In my Kernel module, I have two very short C source files (the main file and a daq.c and daq.h file). The header file contains a number of variables and functions. When I compile the functions normally, by declaring the variable in the daq.h file:
volatile uint32_t *gpio;
I receive the following error:
error In function `.LANCHOR1':
daq.c:(.bss+0x50): multiple definition of `gpio'
This error is only solved by declaring the variable as static, as follows:
static volatile uint32_t *gpio;
The kernel module works fine but in this case I receive the following warning as a static declaration creates a separated copy on every file in which it is included:
warning: ‘gpio’ defined but not used [-Wunused-variable]: static volatile uint32_t *gpio;
I've tried to declare it extern or just simply declaring the variable as uint32_t *gpio instead of declaring it static but then I get a:
WARNING: "gpio" undefined!
followed by an "out-of-tree definition" message in the dmesg log when the module is inserted (and the module is not loaded).
So, in this case, how is the best way to proceed in order to declare the variable? Is it correct to declare it as:
static volatile uint32_t *gpio;
and just omit the "defined but not used" warning given by the compiler? I don't think just "omitting" the warnings is a good practice, especially when it comes to kernel modules.
Thanks in advance.
Your question is not very clear because a full context is missing; but anyway I think some advice can be given.
First, your sources will be used together with other files; those files define things you have to be aware of, otherwise things like multiple definition of 'gpio' come out. In this case (gpio), you must decide if you want to interact with the "other" gpio variable - if not, you must use another name (it is not mandatory, but it is better).
Second, you must understand how the C compiler works, especially if you interface with the kernel, which adds some mechanisms. In general, you don't want to define variables in a header (.h) file; instead, you do declare them, together with data types, macros, and function prototypes. In the source files (.c) you #include headers in order to use the declarations found in them.
Variables are defined in .c files, and made available to other modules through header files, if this is wanted. Otherwise, make them static and do not mention them in the header.
The difference between declaration and definition is this: a declaration tells the compiler "you will encounter (perhaps) this name, somewhere, which has the following properties"; a definition instead means "I create this name, with these properties, and this thing is exactly here.".
When more than a single piece of software are used together, often happens that one piece does something needed in another one... declaration are the way to let these pieces work together.
Hope this helps a little.
Related
My project incorporates a stack, which has a number of user-defined types (typedef). The problem is that many of these type definitions conflict with our in-house type definitions. That is, the same symbol name is being used. Is there any way to protect against this?
The root of the problem is that to use the stack in our application, or wrapper code, as the case may be, a certain header file must be included. This stack header file in turn includes the stack provider's types definition file. That's the problem. They should have included their type definition file via a non-public include path, but they didn't. Now, there are all sorts of user-defined type conflicts for very common names, such as BYTE, WORD, DWORD, and so forth.
Since you probably can't easily change the program stack you are using, you will have to start with your own code.
The first thing to do is (obviously) to limit the number of names in the global namespace, as far as possible. Don't use global variables, just use static ones, as an example.
The next step is to adopt a naming convention for your code modules. Suppose you have an "input module" in the project. You could then for example prefix all functions in the input module "inp".
void inp_init (void);
void inp_get (int input);
#define INP_SOMECONSTANT 4
typedef enum
{
INP_THIS,
INP_THAT,
} inp_something_t;
And so on. Whenever these items are used elsewhere in the code, they will not only have a unique identifier, it will also be obvious to the reader which module they belong to, and therefore what purpose they have. So while fixing the namespace conflicts, you gain readability at the same time.
Something like the above could be the first steps to implementing a formal coding standard, something you need to do sooner or later anyway as a professional programmer.
I suggest you define a wrapping header that redefines all of the functions and structures exported by the stack in terms of your own types. This header is then included in your system files but not in the stack files (where it would conflict). You can then compile and link but there is a weak point at the interface. If you select your types correctly in your redefinitions, it should work correctly, leaving only an maintenance problem on each update from the stack supplier...
I think that I've come up with a reasonable workaround, for the time being, but as Lundin stated, a formal coding standard is needed for a long-term solution.
Basically what I did was to move the inclusion of the required stack header file to before the inclusion of our in-house type definitions file. Then, between those two includes I added a compiler macro to set a defined constant dependent on whether the stack's header file single-include protection definition has been defined. Then, I used that conditional defined constant as a conditional compile option in our in-house type definition file to prevent the conflicting data-types from being re-defined. It's a little sloppy, but progress can only be made in incremental steps.
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.
Ok, I'm looking to define a set of memory addresses as constants in a .h file that's used by a bunch of .c files (we're in C, not C++). I want to be able to see the name of the variable instead of just seeing the hex address in the debugger... so I want to convert the #defines I currently have into constants that are global in scope. The problem is, if I define them like this:
const short int SOME_ADDRESS = 0x0010
then I get the dreaded "multiple declarations" error since I have multiple .c files using this same .h. I would like to use an enum, but that won't work since it defaults to type integer (which is 16 bits on my system... and I need to have finer control over the type).
I thought about putting all the addresses in a struct... but I have no way (that I know of) of setting the default values of the instance of the structure in the header file (I don't want to assume that a particular .c file uses the structure first and fills it elsewhere.. I'd really like to have the constants defined in the .h file)
It seemed so simple when I started, but I don't see a good way of defining a globally available short int constant in a header file... anyone know a way to do this?
thanks!
Declare the constants in the header file using extern:
extern const short int SOME_ADDRESS;
then in any, but only one, .c file provide the definition:
const short int SOME_ADDRESS = 0x0010;
If you're compiling with gcc, you can add the -ggdb3 switch, which will tell gcc to store macro information (i.e. #defines) so that they can be used inside gdb.
I'm working on a embedded application where I need to declare an array of function pointers on a fixed memory address and then use it in different .c files. What I came up with is this:
typedef void(__irq __arm * p_intr_handler_t)(void);
p_intr_handler_t * IntTable = (p_intr_handler_t *)&VIM_RAM_BASE;
p_intr_handler_t IntTable[95];
VIM_RAM_BASE is the address. I delcare this in main.f file and I need to use it in various .c files, so I declared it like this:
extern p_intr_handler_t IntTable[95];
But whilst trying to compile I get an error message:
"declaration is incompatible with "p_intr_handler_t *IntTable" (declared at line 3)"
that message goes for both the normal and the extern declaration.
Any ideas what's wrong?
Thanks
Depending on what you're trying to do, it may make more sense to do this with the linker rather than the compiler. In that case you just declare the symbol as extern in the C file (with no definition at all), and tell the linker where it is. So your header would contain:
extern p_intr_handler_t IntTable[95];
and then you'd add a link-time option (GNU gcc/ld syntax here -- other linkers are different)
-Wl,--defsym=_IntTable=0x8000000
where you set the address to whatever you like. Check out the documentation for your linker to see what the equivalent option is.
Why are you redeclaring IntTable with a different type?
Just jeep the first definition in a single .c, and create an extern for it in a .h to be included in the other .c, like this:
extern p_intr_handler_t * IntTable;
Obviously this works only if VIM_RAM_BASE is already somehow reserved for your data (i.e. the compiler won't try to put there other data), otherwise you should check out your compiler's documentation to see if there's a way to tell it to put a variable at a specific place in memory.
You've defined IntTable twice, shouldn't you rename that to something else?
I wonder about the use of the static keyword as scope limiting for variables in a file, in C.
The standard way to build a C program as I see it is to:
have a bunch of c files defining functions and variables, possibly scope limited with static.
have a bunch of h files declaring the functions and possibly variables of the corresponding c file, for other c files to use. Private functions and variables are not published in the h file.
every c file is compiled separately to an o file.
all o files are linked together to an application file.
I see two reasons for declaring a gobal as static, if the variable is not published in the h file anyway:
one is for readability. Inform future readers including myself that a variable is not accessed in any other file.
the second is to prevent another c file from redeclaring the variable as extern. I suppose that the linker would dislike a variable being both extern and static. (I dislike the idea of a file redeclaring a variable owned by someone else as extern, is it ok practice?)
Any other reason?
Same goes for static functions. If the prototype is not published in the h file, other files may not use the function anyway, so why define it static at all?
I can see the same two reasons, but no more.
When you talk about informing other readers, consider the compiler itself as a reader. If a variable is declared static, that can affect the degree to which optimizations kick in.
Redefining a static variable as extern is impossible, but the compiler will (as usual) give you enough rope to hang yourself.
If I write static int foo; in one file and int foo; in another, they are considered different variables, despite having the same name and type - the compiler will not complain but you will probably get very confused later trying to read and/or debug the code. (If I write extern int foo; in the second case, that will fail to link unless I declare a non-static int foo; somewhere else.)
Global variables rarely appear in header files, but when they do they should be declared extern. If not, depending on your compiler, you risk that every source file which includes that header will declare its own copy of the variable: at best this will cause a link failure (multiply-defined symbol) and at worst several confusing cases of overshadowing.
By declaring a variable static on file level (static within function has a different meaning) you forbid other units to access it, e.g. if you try to the variable use inside another unit (declared with extern), linker won't find this symbol.
When you declare a static function the call to the function is a "near call" and in theory it performs better than a "far call". You can google for more information. This is what I found with a simple google search.
If a global variable is declared static, the compiler can sometimes make better optimizations than if it were not. Because the compiler knows that the variable cannot be accessed from other source files, it can make better deductions about what your code is doing (such as "this function does not modify this variable"), which can sometimes cause it to generate faster code. Very few compilers/linkers can make these sorts of optimizations across different translation units.
If you declare a variable foo in file a.c without making it static, and a variable foo in file b.c without making it static, both are automatically extern which means the linker may complain if you initialise both, and assign the same memory location if it doesn't complain. Expect fun debugging your code.
If you write a function foo () in file a.c without making it static, and a function foo () in file b.c without making it static, the linker may complain, but if it doesn't, all calls to foo () will call the same function. Expect fun debugging your code.
My favorite usage of static is being able to store methods that I wont have to Inject or create an object to use, the way I see it is, Private Static Methods are always useful, where public static you have to put some more time in thinking of what it is your doing to avoid what crazyscot defined as, getting your self too much rope and accidentally hanging ones self!
I like to keep a folder for Helper classes for most of my projects that mainly consist of static methods to do things quickly and efficiently on the fly, no objects needed!