C literal constants : in header or C file? - c

I'd like to include in na single static C program a bunch of data (say, images, but also other data, embedded in executable since I'm working on an embedded platform without files).
Thus, I wrote a little img2c creating const data from my data files, creating a file with static const arrays initializers to be put to flash (using C99 nice features)
My question is, should I put them in a .h file, like I've seen many times - by example gimp can save as .h files, not .c files - or in a .c file, referenced in a header with just the const extern declaration for further references, without having to include all data and pass it all to the compiler, and redeclare it each time I use it ?
Preprocessor macros are out of the question, since I'll reference their address, not include the whole data each time.

If you put the data in a header every compilation unit that pulls in that header will get its own copy of the data. Imagine two .c files that each go to a .o. Each .o will have a copy of the data and your final executable can be bigger than it needs to be.
If you put it in a .c and extern it in a header, only the one .o will contain the data and your final executable can be smaller. Also, if you change things the recompile can be quicker if it's just a change to a single .c rather than all the .c files that include your header.
As you noted, you may also run into problems with the linker, as symbols will be defined multiple times, see the answers to Repeated Multiple Definition Errors from including same header in multiple cpps. It's going to be better all around to put an extern in the header and the data in a .c

Header files in C are nothing special; the .h extension won't change how the compiler handles them. It's more of a hint for humans "this file probably doesn't contain any code".
So if you put actual binary data in there, the compiler will create a copy of the array in each file in which you include the header (instead of simply adding a reference to a shared global array).
GIMP creates a header file because it doesn't know how you plan to use the data. The idea is that you'll include this header file exactly once in a .c file which then processes the data in some way. If it wrote a .c file and you made changes to the code, GIMP would have to merge the changes when you ask it to update the data - it would be messy.

As with everything in C, there is some debate as to best practice here. Common practice is to put the actual values in your implementation (.c) and the declarations (extern something something) in the header (.h). That way, you can update the values without having to recompile every file that includes the header.
The answer is almost never "redeclare it each time I use it."

This can be done by making sure that the variable is only defined in a single source file. For this a little preprocessor "programing" is needed.
Header file:
/* Standard include guard */
#ifndef X_H
#define X_H
#ifdef X_SOURCE
uint8_t data[] = { /* ... */ };
#else
extern uint8_t data[];
#endif
#endif /* End of include guard */
Source file:
#define X_SOURCE
#include "x.h"
/* ... */
All other source files just need to include the file "x.h" and they can reference data.

Related

How to use a .h file without header guards multiple times

Currently I have a .h file provided by a professor that I'm not allowed to modify. I have to use structures and implement the methods from the given .h file but it doesn't have header guards. I want to write a file to test the methods but am running into a typedef redefinition error when trying to include the .h file in multiple locations.
I could write all the tests in the corresponding .c file and delete them later, but it would make the file rather big and I would like to use these tests again/modify them in the future as the project builds on itself.
I could also make a copy of the .h and include header guards, test it, then change it back before turning it in. I'm somewhat new to C and was curious if there was a simpler solution or a more efficient way of doing this without modifying the .h file. Thanks.
You can either wrap it with a second header guarded_header.h that has the guards:
#ifndef GUARDED_HEADER_H
#define GUARDED_HEADER_H
#include "unguarded_header.h"
#endif
Then in your source:
#include "guarded_header.h"
or you could just inline the above around each point of inclusion. I like the wrapping better, but if the original header already is known to define one or more macros, you can do it inline easily as:
#ifndef SOMETHING_UNGUARDED_HEADER_DEFINES
#include "unguarded_header.h"
#endif

why should extern declaration be outside .c file ( as per linux coding style )

As per checkpatch.pl script "extern declaration be outside .c file"
(used to examine if a patch adheres coding style)
Note: this works perfectly fine without compilation warnings
The issue is solved by placing the extern declaration in .h file.
a.c
-----
int x;
...
b.c
----
extern int x;
==>checkpatch complains
a.h
-----
extern int x;
a.c
----
int x;
b.c
----
#include "a.h"
==> does not complain
I want to understand why this is better
My speculation.
Ideally the code is split into files so as to modularize the code (each file is a module)
The interface exported by the module is placed in the header files so that other modules (or .c files) can include them. so if any module wants to expose some variables externally, then one must add an extern declaration in a Header file corresponding to the module.
Again, having a header file corresponding to each module (.c file) seems like
to many header files to have.
It would be even better to include the a.h in the a.c file as well. That way the compiler can verify that the declaration and the definition match each other.
a.h
-----
extern int x;
a.c
----
#include "a.h" <<--- add this
int x;
b.c
----
#include "a.h"
The reason for the rule is, as you assume, that we should use the compiler to check what we are doing. It is much better with the tiny details.
If we allow extern declarations all over the place, we get in trouble if we ever want to change x to some other type. How many .c files do we have to scan to find all extern int x? Lots. And if we do, we will likely find some extern char x bugs as well. Oops!
Just having one declaration in a header file, and include it where needed, saves us a lot of trouble. In any real project, x will not be the only element in the header file anyway, so you are not saving on the file count.
I see two reasons:
If you share a variable, it's because it's not in your own file, so you want to make it clear that it's shared by adding the extern to a header file - that way, there is only one place [the include directory] to search for extern declarations.
It avoids someone making an extern declaration, and then someone else making a different (as in using different type or attributes) extern declaration for the same thing. At least if it's in a header file [that is relevant], all files use the same declaration.
If you ever decide to change the type, there are only two places to change. If you were to add a "c.c" file that also use the same variable, and then decide that int is not good enough, I need long, you'd have to modify all three places, rather than two as you'd have if there was a header file included in each of "a.c", "b.c" and "c.c".
Having a header file for your module is definitely not a bad idea. But it could of course be acceptable, depending on the circumstances to put the extern into some existing headerfile.
An alternative, that is quite often a better choice than using an extern, is to have a getter function, that fetches your variable for you. That way, the variable can be static in its own source file [no "namespace pollution", and the type of the variable is also much more well defined - the compiler can detect if you are trying to use it wrongly.
Edit: I should point out that Linux coding style is the way it is for "good" reasons, but it doesn't mean that code that isn't part of the Linux source code can't break those rules in various ways. I certainly don't write my own code using the formatting of Linux - I like extra { } around single statements, and I (nearly) always put { on a new line, in line with whatever the brace belongs to, and the } in the same column again.
One reason I always place the extern declarations in the .h is to prevent code duplication, especially if there are, or may be, more bits of code using your "a.c" code and having to access the "x". In that case all files would have to have the extern declaration.
Another reason is that the extern declaration is part of the interface of the module and as such I would keep it, together with any other interface information in the header file.
Your speculation is right: for maximal code reuse and consistency, the (public) declarations must be put into header files.
Again, having a header file corresponding to each module (.c file) seems like to many header files to have.
Then get used to it. It's a logical concept and a good practice to adapty
You have got the reason right as to why extern declarations must be placed in a header file. So, that they can be accessed across different translation units easily.
Also, it is not necessary that each .c file should have a corresponding .h file. One .h file can correspond to a decent number of .c files depending upon your module segregation design.
Again, having a header file corresponding to each module (.c file) seems like to0 many header files to have.
As you have said, the idea of a header file is simple. They contain the public interface that a module wants to export (make available) to other modules (contained in other .c files). This can include structures and types and function declarations. Now, if a module defines a variable which it wants to make available to other modules, it makes sense for it to be included with it's other public parts in the header file. This is why externs end up in th header file. They are just a part of the things that the module wants to make public. Then anyone can include this public interface by simply including the header file.
Having a .h file per .c file may seem like much, but it may be the right thing to do. But keep in mind that a module may implement its code in multiple .c files, and choose to export its aggregate public interface in a single .h file. So, it is not really a strict one to one thing. The real abstraction is that of the public interface offered by a module.

Using Definitions in C Header Files?

I'm currently learning the C programming language (coming from Java) and I'm a bit confused as to how to define a macro.
In order for other code to use the macro, the header file must have it. But if I define the macro in the header file, then the source file can't use it. Do I have to define it in both or do I have to #include the source file's own header file?
Source files virtually always include their "own" header file -- i.e., a header that declares the functions defined in a source file. Declaring a function before actually defining it is perfectly legal and often desirable: you may get compile errors if the header is accidentally mismatched, and that's a good thing.
First #include is essentially like directly inserting the file in your file. It is run by the compiler pre-processor, which is run before the compiler. Google C preprocessor for more info...
Typically setup is:
#include "macros.h"
...
printf("Macro value %d\n", MACRO_HERE(1) );
and in your header file, macros.h
#ifndef MACROS_H_
#define MACROS_H_
#define MACRO_HERE( n ) ( n + 1 )
#endif
The wrapped #ifdef(s) prevent the macro from being redefined if you later have another include file which also includes macro.h
See also: #pragma once (which is widely used in many compilers also)
You can define it both in the header or the implementation file, but it needs to be visible to the translation unit you use it in.
If it's for use just inside one implementation file, define it in that file only.
If more files use the macro, define it in a header and include that header wherever you need the macro.

What's the difference between using extern and #including header files?

I am beginning to question the usefulness of "extern" keyword which is used to access variables/functions in other modules(in other files). Aren't we doing the same thing when we are using #include preprocessor to import a header file with variables/functions prototypes or function/variables definitions?
extern is needed because it declares that the symbol exists and is of a certain type, and does not allocate storage for it.
If you do:
int foo;
In a header file that is shared between several source files, you will get a linker error because each source would have its own copy of foo created and the linker will be unable to resolve the symbol.
Instead, if you have:
extern int foo;
In the header, it would declare a symbol that is defined elsewhere in each source file.
One (and only one) source file would contain
int foo;
which creates a single instance of foo for the linker to resolve.
No. The #include is a preprocessor command that says "put all of the text from this other file right here". So, all of the functions and variables in the included file are defined in the current file.
The #include preprocessor directive simply copy/pastes the text of the included file into the current position in the current file.
extern marks that a variable or function exists externally to this source file. This is done by the originator ("I am making this data available externally"), and by the recipient ("I am marking that there is external data I need"). A recipient with an unsatisfied extern will cause an Undefined Symbol error.
Which to use? I prefer using #include with the include guard pattern:
#ifndef HEADER_NAME_H
#define HEADER_NAME_H
<write your header code here>
#endif
This pattern allows you to cleanly separate anything you want an outsider to have access to into the header, without worrying about a double-include error. Any time I have to open a .c file to find what externs are available, the lack of a clear interface makes my soul gem crack.
There are indeed two ways of using functions/variables across translation units (a translation unit is usually a *.c/*.cc file).
One is the forward declaration:
Declare functions/variables using extern in the calling file. extern is actually optional for functions (functions are automatically extern), but not for variables.
Implement the function/variables in the implementing file.
The other is using header files:
Declare functions/variables using extern in a header file (*.h/*.hh). Still, extern is optional for functions, but not for variables. So you don't normally see extern before functions in header files.
In the calling *.c/*.cc file, #include the header, and call the function/variable as needed.
In the implementing *.c/*.cc file, #include the header, and implement the function/variable.
Google C++ style guide has some good discussions on the pros and cons of the two approaches.
Personally, I would prefer the header file approach, as it is the single place (the header file) a function signature is defined, calling and implementation all adhere to this one piece of definition. Thus, there would be no unnecessary discrepancies that might occur in the forward declaration approach.

Should variable definition be in header files?

My very basic knowledge of C and compilation process has gone rusty lately. I was trying to figure out answer to the following question but I could not connect compilation, link and pre-processing phase basics. A quick search on the Google did not help much either. So, I decided to come to the ultimate source of knowledge :)
I know: Variables should not be defined in the .h files. Its ok to declare them there.
Why: Because a header file might get included from multiple places, thus redefining the variable more than one time (Linker gives the error).
Possible work-around: Use header-guards in header files and define variable in that.
Is it really a solution: No. Because header-guards are for preprocessing phase. That is to tell compiler that this part has been already included and do not include it once again. But our multiple definition error comes in the linker part - much after the compilation.
This whole thing has got me confused about how preprocessing & linking work. I thought that preprocessing will just not include the code, if the header guard symbol has been defined. In that case, shouldn't multiple definition of a variable problem also get solved?
What happens that these preprocessing directives save the compilation process from redefining symbols under header guards, but the linker still gets multiple definitions of the symbol?
One thing that I've used in the past (when global variables were in vogue):
var.h file:
...
#ifdef DEFINE_GLOBALS
#define EXTERN
#else
#define EXTERN extern
#endif
EXTERN int global1;
EXTERN int global2;
...
Then in one .c file (usually the one containing main()):
#define DEFINE_GLOBALS
#include "var.h"
The rest of the source files just include "var.h" normally.
Notice that DEFINE_GLOBALS is not a header guard, but rather allows declaring/defining the variables depending on whether it is defined. This technique allows one copy of the declarations/definitions.
Header guard protects you from multiple inclusions in a single source file, not from multiple source files. I guess your problem stems from not understanding this concept.
It is not that pre-processor guards are saving during the compile time from this problem. Actually during compile time, one only source file gets compiled into an obj, symbol definitions are not resolved. But, in case of linking when the linker tries to resolve the symbol definitons, it gets confused seeing more than one definition casuing it to flag the error.
You have two .c files. They get compiled separately. Each one includes your header file. Once. Each one gets a definition. They conflict at link time.
The conventional solution is:
#ifdef DEFINE_SOMETHING
int something = 0;
#endif
Then you #define DEFINE_SOMETHING in only one .c file.
Header guards stop a header file being included multiple times in the same translation unit (i.e. in the same .c source file). They have no effect if you include the file in two or more translation units.

Resources