I'm programming (and indeed close to completing) a CLI program to test the user on vocabulary, or indeed any set of questions and responses he/she would care to define.
Full source on github: https://github.com/megamasha/Vocab-Tester
Loading from a file and saving to a file are handled from separate functions, both outside of main(). At the moment they're in the same source file, but I'd like to know how to do this both a) within the file, and b) in the case that they end up in a separate database ops file.
I want to allow the user to save to the file he most recently loaded, so I want my loaddatabase() function to define a global char * to the filename, which the savedatabase() function can then access.
If I declare a char * outside of any function, it is read-only and trying to write a filename to it causes a segfault.
If I declare it within the loaddatabase() function, savedatabase() can't access it.
Will declaring the variable static allow other functions to access it, or if not, how can I allow two functions to access the same char *?
You can define a global variable by defining it in a single .c file:
char * database;
And by declaring it in a .h file:
extern char * database;
And by including the .h file in every file that uses the variable.
The extern keyword declares the variable without defining it. It says the compiler that the variable exists in an other file.
So for your problem, you can define char * database in the file of your load/save functions, and declare it (extern char * database) in the file of your main function.
You can do the same thing with char database[1024] instead of char * database if you don't want to bother allocating and freeing memory for the filename. This way you can directly write to database.
You need to declare a character array, i.e. char filename[260].
Related
I want to define an array in a header file, together with the function using it. Not inside the function, but at the top, like a global variable.
Now I am not sure if this will work at all. How long would the array live? Is it like creating a local variable in a loop or will it stay alive since #include "said_header.h" untill the program's end?
Keep in mind that #include "headerfile.h" in C is more or less logically equivalent to opening your text editor and replacing the #include line with the entire contents of the included file.
So, header files are best used for declarations (which need to be shared between different source files, aka compilation units), while definitions are best kept in just one source file. Note that you can declare an object, and then define it, and indeed doing so when the declaration is in a header file is a good way to allow the compiler to verify that the declaration and the definition match.
so in headerfile.h you might put the declaration of your array:
extern char array[100];
and in one of your source files you might define your array:
#include "headerfile.h"
char array[100];
and in other source files you can just reference the global array:
#include "headerfile.h"
strncpy(array, "some string", sizeof(array) - 1);
In a source file inv_mpu.c there is a structure definition gyro_state_s and a file scope variable declaration:
static struct gyro_state_s st = {
.reg = ®,
.hw = &hw,
.test = &test
};
Nested in this structure is a member st.chip_cfg.bypass_mode that I wish to access from withing another file.
Question: How to read the state of this flag st.chip_cfg.bypass_mode within another file?
I have tried extern struct gyro_State_s st ;, but this remains unrecognized when I test it in if(!st.chip_cfg.bypass_mode).
Attempting to expose all of st and its definition just to access this one flag is a bad design and should be avoided. Globals are always bad, and in this case you would be unnecessarily making all the internals of st visible to the entire program.
inv_mpu.c already has a function mpu_set_bypass() which is called before it is used, so must have a prototype somewhere, most likely in the existing header inv_mpu.h. The simplest, safest and most in-keeping with the existing code style solution would be to add a "getter" accessor counter-part mpu_get_bypass().
In inv_mpu.c you might add:
unsigned char mpu_get_bypass( void )
{
return st.chip_cfg.bypass_mode ;
}
The add the prototype declaration to inv_mpu.h thus:
unsigned char mpu_get_bypass( void ) ;
Then in the accessing source file, you #include "inv_mpu.h", then call the getter, thus for example:
if( !mpu_get_bypass() ) ...
Put the structure in a shared header that is included in both files.
extern means: 'this is defined/instantiated elsewhere'
Since a structure on it's down doesn't compile to any physical code (an instance of a structure does, the structure itself just describes how to create an instance of it) you just need to define the same structure in both files, this is best done by putting the structure in a shared header then including the header in both of the files you need the structure in.
I have this structure as a header file in one of my c projects.
struct info{
char name[50];
char address[150];
char country[20];
char region[20];
char postalcode[10];
char phonenumber[15];
char paymethod[15];
};
But can i store a function in a header file? Cause it'd be easier to maintain the whole program.
The appropriate practice is to store the function prototypes (function declarations) in header file. The function implementations go into a ".c" file.
But can i store a function in a header file? Cause it'd be easier to maintain the whole program.
I assume by store, you mean define.
Yes, you can define functions in a header file using the inline keyword if using C99 or a later version of C.
However, in practice that is good only for small functions.
It's best to declare functions in .h files and define them in .c files for most functions.
Defining functions inline can provide performance boost to the program but it also couples the declaration and definition. If the definition needs to be changed, you'll have to re-compile all the .c files that #include the .h file. Depending on the size of the project, that can be expensive.
You can store a function in a header file but you shouldn't.
It seems easy to manage a project with "a file for a single operation" style but when project gets bigger, and when you have lots of functionalities, it will be easier to read through header files for definitions.
And if you want to make your code re-usable, header files helps you binary-only distribution of your code in libraries(i.e. you share your function library through a header without exposing your actual code)
You can write a function and save it in a header file with the extension .h, so that you can use it in times. As example, i will create a function to add two integer values and return the sum whenever the function is being called..
int sumOfTwoInteger(int a ,int b){
return a+b;
}
Now all i have to do is save the file with a name and an extension .h, e.g 'myheader.h'
Now put the header file in the same directory where your actual program is.
In the beginning of your actual program add the header file
#include"myheader.h"
Now you can call that function whenever you want...
int sum;
sum = sumOfTwoInteger(10,5);
And the sum will be stored in the variable 'sum'
Is it possible to declare a structure type that is only visible in the .c file which uses the structure? I know that by putting static in front of a external data object, you change the linkage of the variable to be internal. But is it possible to put static in front of the declaration of a new struct type, like the following?
static struct log{
...;
...;
};
typedef struct log log;
If it is not possible to make the structure type, say log as above, to be "private", does it mean that even though other source files do not know the existence of the name (which is log in my example) of the structure, accidental name collisions can still happen if they name some variables log (assuming I will link all object files) ?
EDIT: I am not familiar with how compiler/linker works. If there is a global variable name log, and the file that contains the global variable is linked to the sole source file in which structure log is defined, wouldn't that cause any confusion when linking, one log is a variable name while another log is a type name?
No. The only way to make a struct private is to only have its definition available in the files that use it -- don't put it in a common header file. If it's only used in one source file, then just define it in that source file, but if it's used in more than one source file, you have a tricky problem: you can define it in each source file, but that's fragile since you have to remember to change each instance of it when you make any changes; or, you can define it in a private header file, and make sure only those source files include the private header.
Name collisions in different source files are ok, as long as they don't try to interface with each other in any way. If you have a struct log defined in one file and a different definition of struct log in a different file, do not ever pass one log to the other. In C, the structure name doesn't become part of any symbol names in the object file -- in particular, there's no name mangling of function names to include the parameter types (like C++ does), since function overloading is illegal in C.
No. static is a storage type; it is not meaningful to apply it to a type outside a variable declaration.
If you don't want to define struct log in your header file, you don't have to. Simply writing the typedef as:
typedef struct log log;
is sufficient, so long as you only deal with log * pointers. However, you will need a full definition of the structure to declare a log (or take sizeof(log)), because the size of the structure depends on what it contains.
With regard to name collisions, keep in mind that structures and types are not managed by the linker. The linker only cares about globally visible symbols, such as functions and variables. That being said, you should probably apply a prefix to your type names (e.g, mylib_log_t) to avoid confusion, particularly because log is a math function in the standard library.
You have a reason to write this:
static int a;
Because it prevents the linker from combining it with a defined somewhere else.
The linker has nothing to do with structs, so there is no worries putting in different c files.
As long as its in different c files, there will be no name confusions.
This isn't possible in general. But I can think of a hack that might work on some compilers.
The reason why this is hard to do is because the C compiler needs to know what the structure looks like in order to generate calls to functions with instances of the structure as argument.
So, suppose that you define a library with the following header:
struct foo {
int32_t a, b;
};
foo make_foo(int arg);
foo do_something(foo p1, foo p2);
Then to compile a program which makes a call to do_something, your compiler usually needs to know what the structure foo is like, so that it can pass it as an argument. The compiler can do all sorts of weird things here, like passing part of the structure via registers and part via the stack, so it really needs to know what the structure looks like.
However, I believe that in some compilers, it is possible to give the indication that the structure should be passed entirely via the stack. For instance, the regparm(0) function attribute should work for GCC if you have i386 as your target architecture (docs).
In that situation, it should be possible to do something like this: create a 'public version' of the header file, and in that file, instead of laying out the full struct, you create an undiferentiated version of it:
struct foo {
uint8_t contents[SIZE_OF_STRUCT_FOO];
}
where SIZE_OF_STRUCT_FOO is whatever sizeof(struct foo) returns when you define the struct in the usual way. You are then basically saying that "foo" is a struct with SIZE_OF_STRUCT_FOO bytes. Then, as long as the calling convention treats these two structs in the same way, it should work.
I develop an embedded application which uses the MindTree Bluetooth SDK.
I have the following in a header file:
typedef struct {
UCHAR outputDir;
UCHAR reset;
UCHAR nack;
UCHAR startCondition;
UCHAR stopCondition;
UCHAR busy;
} USCI_ConfigurationFlags;
static USCI_ConfigurationFlags usciConfigFlags = { UCTR, UCSWRST, UCNACKIFG, UCTXSTT, UCTXSTP, UCBBUSY };
Later in two .c files I include the above header and use the usciConfigFlags on different occasions sometimes from within an interrupt.
Is this legal?
I'm trying to understand why(and if it is related to the question) the values of the struct change at runtime, after calling the BT_bluetooth_on method in the SDK.
Thanks,
Adam.
static here doesn't mean what you think it means. It means that the declaration and variable will only be visible in one compilation unit. That is, you have two independent instances of usciConfigFlags.
If you want a global variable, you need to use extern not static and make the actual declaration (without extern) with the initial value in one of your c files.
Also be weary of changing the values in the struct without proper locking. Read-only concurrent access is usually fine.
There is no problem you include the header in two .c file. The static modifier limits the accessible scope of the variable in the file including the header only. The two usciConfigFlags in two different files are not identical.
Also static does not mean constant. So you can modify the value of the structure in whatever way you want.
The following is from wikipedia
In computer programming, a static variable is a variable that has been
allocated statically — whose lifetime extends across the entire run of
the program. This is in contrast to the more ephemeral automatic
variables (local variables), whose storage is allocated and
deallocated on the call stack; and in contrast to objects whose
storage is dynamically allocated.
Prepending a static keyword to a variable makes it visible only in the current translation unit (i.e. if within a function, only that function and if within a file, only that file).
It is never a good idea to define a variable in a header file. Even if you need two static variables in two different files with the same name, it is better that you put in the .c file itself as it helps in better maintaince and readability as you will be clear in which all files it is actually present and is being used.
If you add it in a header file, then at a later point, if some other .c file includes this header, then unneccessarily this variable will included for that translation unit.
Epsalon had suggested other good points which you can consider.