This question already has answers here:
C: Why do we include header files, which declare but don't define?
(5 answers)
Closed 4 years ago.
This is the question I still cannot answer by myself (probably due to lack of experience in C).
So I found this answer and the question is what's wrong with putting definitions into a header files? I we don't declare them as static it should be fine since they will have external linkage and linker will not complain.
Secondly, why should not we put static definition into a header file? Suppose we want to make some function sort of "compilation-unit private" that is not intended to have external linkage.
And what I was surprised about was why is it (rarely) possible to put inline function definition into header files?
Is it just by convention only?
There is not usually any point in putting information into a header unless it will be included in multiple other source files. That means that if the header defines some variables, each source file that includes the header will define those variables. And it is normally an error to define the same (global) variable more than once. So, putting variable definitions into a header normally defeats the reason for creating a header in the first place.
Note that C does have a 'one definition rule', similar to C++, but not as strong. There is a 'common' extension — complete with double entendre — that often allows you to get away with defining a variable in more than one file, but it doesn't work if the variable has a non-trivial initialization.
You can find a lot of information in How do I use extern to share variables between source files?, including information about the common extension.
You should not normally define static variables in a header because that means that each file that includes the header will define its own copy of the variables. This is usually not what's wanted. It tends to make programs bigger.
If you reliably work with compilers that support inline, there is no particular reason why you can't put static inline function definitions into a header. There is a risk that if the function cannot be inlined, then the compiler will generate a static function in the object code for each source file that uses the function, again increasing the size of the executable. You might be able to avoid that by using non-static inline function definitions. If the functions are small enough that they will be inlined, there is no particular reason not to put them in a header.
You can find more information about inline functions, with static or extern, in the Q&A on Stack Overflow:
extern inline
Is inline without static or extern ever useful in C99
What's the difference between static and static inline functions?
Note the rather extensive use of weasel words such as 'usually' and 'normally' in the answer above. You can, with care, find exceptional situations that warrant breaking the rules, but if you remember that headers are the glue that provide cross-checking between the code that uses some functionality (types, constants, functions, sometimes variables) and the code that implements the functionality, then you'll realize that it is good to follow these rules:
Headers declare types, constants, enumerations, functions, variables that are used by multiple source files.
Source files implement functions and define variables that are used by multiple source files.
The header files are used by the implementation code to ensure that the implementation matches the specification.
The header files are used by the consumer code to follow the source-level rules for the implementation.
Header files should not define variables.
Source files should not declare external variables; they should include the relevant header.
Headers may sensibly define static inline functions; you may even include plain inline function definitions in a header, but you have to be careful to instantiate the functions somewhere in case they are not inlined — and that's when extern inline comes into play. (Be aware that old GCC rules for inline functions are different from C99 standard rules.)
There are some rules that simply including a header won't enforce, such as required sequences for calling functions (don't call a free function before the corresponding allocate function, for example). But using headers wisely prevents a lot of errors.
See also:
Should I use #include in headers?
How to link multiple implementation files in C?
And many other questions, no doubt.
Related
I'm looking at a header-only C "library": https://github.com/zserge/jsmn/blob/master/jsmn.h
As far as I can understand, this code will be compiled into every object file where the .c file includes jsmn.h, wasting space.
(The file's function definitions are inside #ifndef JSMN_HEADER, so you could use this as a "traditional" header file by defining JSMN_HEADER.)
Why hasn't it been written as a "traditional" .c and .h pair?
Is the linker clever enough to dedup function identical definitions between object files? I would have expected "duplicate symbol" errors.
What advantage does putting code in headers give in C? (Not C++.)
From where do you get the function definitions if you use #define JSMN_HEADER before importing?
Is jsmn.h being header-only a clever trick, from which I can learn?
The header expands into one of the following, depending on the macros defined:
No macros — function definitions (public functions are non-static, private ones are).
JSMN_HEADER — function declarations (for public functions only).
JSMN_STATIC — static function definitions (for both private and public functions).
If only a single TU needs the library, you can freely choose between (1) and (3).
If more than one TU needs the library, you need (1) in one of the TUs and (2) in all others. Then the only thing that's "wasted" is preprocessor time for skipping function definitions for (2), but it shouldn't matter since they're so tiny.
In this case, trying to go with (1) for all TUs would give you "duplicate symbol" linker errors. Trying to go with (3) for all TUs would silently duplicate the symbols, which would be wasteful.
Why hasn't it been written as a "traditional" .c and .h pair?
For supposed convenience of distributing and using the library.
Is the linker clever enough to dedup function identical definitions between object files? I would have expected "duplicate symbol" errors.
It's probably not clever enough, but it doesn't need to be.
You're expected to define the macros so that only a single TU has the definitions.
What advantage does putting code in headers give in C?
Less source files to distribute.
From where do you get the function definitions if you use #define JSMN_HEADER before importing?
From your other TU that didn't define this macro before including the header.
Is jsmn.h being header-only a clever trick, from which I can learn?
Yes.
Lately I have been making an attempt to read more open source C code. A common pattern that I have been adopting in my hobby projects is as follows.
In my C files, I have functions that are either static or exported. Only functions that are exported are placed in a header file. Global variables which are only used within the scope of an object are also used as static global variables.
My question concerns the usefulness and motivation of having static inline functions inside header files. From what I read online, not using the static keyword causes a multiple definition error and that is the reason for not just defining the function as just inline.
However, does this mean that this function is exported for other objects to use?
If yes, then why not just defining this function in the C file and export it via the header file?
If not, why putting this in the header file rather than just having it inside the C file?
Is there a reason behind this coding style? What am I missing?
One such example can be found in the git codebase inside hashmap.h:
/*
* Converts a cryptographic hash (e.g. SHA-1) into an int-sized hash code
* for use in hash tables. Cryptographic hashes are supposed to have
* uniform distribution, so in contrast to `memhash()`, this just copies
* the first `sizeof(int)` bytes without shuffling any bits. Note that
* the results will be different on big-endian and little-endian
* platforms, so they should not be stored or transferred over the net.
*/
static inline unsigned int sha1hash(const unsigned char *sha1)
{
/*
* Equivalent to 'return *(unsigned int *)sha1;', but safe on
* platforms that don't support unaligned reads.
*/
unsigned int hash;
memcpy(&hash, sha1, sizeof(hash));
return hash;
}
A static inline function is, in practice, likely (but not certain) to be inlined by some good optimizing compiler (e.g. by GCC when it is given -O2) at most of its call sites.
It is defined in a header file, because it then could be inlined at most call sites (perhaps all of them). If it was just declared (and simply "exported") the inlining is unlikely to happen (except if you compile and link with link-time optimizations, a.k.a. LTO, also, e.g. compile and link with gcc -flto -O2, and that increases a lot the build time).
In practice, the compiler needs to know the body of a function to be able to inline it. So a suitable place is to define it in some common header file (otherwise, it could be inlined only in the same translation unit defining it, unless you enable LTO), so that every translation unit would know the body of that inlinable function.
It is declared static to avoid multiple definitions (at link time) in case the compiler did not inline it (e.g. when you use its address).
In practice, in C99 or C11 code (except with LTO, which I rarely use), I would always put the short functions I want to be inlined as static inline definitions in common header files.
Be sure to understand how and when the C preprocessor works. Notice that you could in principle (but it would be very bad practice and disgusting style) avoid defining some static inline function in a common header file and instead copy and paste its identical definition in multiple .c files.
(However, that might make sense for generated .c files, e.g. if you design a compiler emitting C code).
FYI LTO is practically implemented by recent GCC compilers by embedding some internal compiler representation (some GIMPLE) inside object files, and redoing some "compilation" step - using the lto1 frontend - at "link" time. In practice, the entire program is almost compiled "twice".
(actually, I always wondered why the C standardization committee did not decide instead that all explicitly inline functions are static)
Do I need to declare all functions I use in a .c file in a header file, or can I just declare and define right there in the .c file? If so, does a definition in the .c file in this case count as the declaration also?
Do I need to declare all functions I use in a .c file in a header file,
or can I just declare and define right there in the .c file?
You used "use" in the first question and "define" in the next question. There is a difference.
void foo()
{
bar(10);
}
Here, foo is defined and bar is used. You should declare bar. If you don't declare bar, the compiler makes assumptions about its return type.
You can declare bar in the .c file or add the declaration in a .h file and #include the .h file in the .c file. Whether you use the first method or the second method is up to you. If you use the declaration in more than one .c file, it is better to put that in a .h file.
You can define foo without a declaration.
If so, does a definition in the .c file in this case count as the declaration also?
Every function definition counts as a declaration too.
For the compiler, it does not matter if a declaration occurs in a .h or a .c file, because the compiler sees the preprocessed form.
For the human developer reading and contributing to your code, it is much better (to avoid copy&pasting the same declaration twice) to put the declaration of any function used in more than one translation unit (i.e. .c file) in some #include-d header.
And you can define a function before using it.
BTW, you might even avoid declaring a function that you are calling (it defaults to returning int for legacy purposes), but this is poor taste and obsolete way of coding (and most compilers can emit a warning in that case).
No, it is not necessary.
The reason of the header files is to separate the interface from the implementation. The header declares "what" a class (or whatever is being implemented) will do, while the .c file defines "how" it will perform those features.
This reduces dependencies so that code that uses the header doesn't necessarily need to know all the details of the implementation and any other classes/headers needed only for that. This will reduce compilation times and also the amount of recompilation needed when something in the implementation changes.
The answer to both questions is yes. You can declare c-functions in both header and .c file. Same with definition. However, if you are defining it in header file, you may have slight problems during compilation.
By default functions have external linkage. It means that it is supposed that functions potentially will be used in several compilation units.
However sometimes some auxiliary functions that form implementations of other functions are not designed to be used in numerous compilation units. Such functions declared with keyword static have internal linkage.
Usually they are declared and defined inside some .c module and are not visible in other compilation units.
One occasion that requires functions to be declared in a separate header is when one is creating a library for other developers to use. Some libraries are distributed as closed source and they are provided to you as a library file (*.dll / *.so ...) and a header.
The header file would contain declarations of all publicly accessible functions and definitions of all publicly required structures, enums and datatypes etc.
Without this header file the 3rd party library user would not know how to interface with the library file and thus would not be able to link against it.
But for small, trivial C programs that are not intended for use by other people, no you can just dump everything into a C file and build it. Although you might curse yourself years later when you need to maintain that code :)
I'm using eclipse indigo, gcc and cdt in a project. If two functions in separate source files share names (regardless of return type or parameters), eclipse flags a redefinition error. This isn't a huge issue regarding this project given I can easily rename these functions, and I'm well aware of wrappers if it were. Although this isn't a critical issue, it does make me think I'm not understanding the c build process. What occurs during the build process in which a program structure like this would cause issue?
Here's some more info. on the situation, and where my understanding is so far -- not necessary to answer the question, although there must be a hole in my understanding.
In this case, the two functions are intended to be used only locally, as such their prototypes are not given in the .h interface, and for the sake of my point, neither are defined 'static'.
Neither of these source files are being included anywhere in the project, so they shouldn't be sharing any compilation units. With that in consideration, I would have assumed that the neither source file is aware of the presence of the other, and the compiler would have no problem indexing the two functions, as the separate files would allow for proper distinguishing between the two during linking -- so long as they weren't included in the same compilation unit.
I noticed that statically defining either instance of the function declaration removes the error. I remember reading at some point that every function not declared static is global -- although given these functions are not a part of the .h interface, the practical example in which including the .h interface doesn't allow for the including program to reference all .c functions would indicate "hiding" these functions would be of no issue.
What am I overlooking?
Some insight would be greatly appreciated, thanks!
This is the concept of "linkage". Every function and variable in C has a linkage type, one of "external", "internal", and "none". (Only variables can have no linkage.)
Functions have external linkage by default, which means that they can be called by name from any compilation unit (where "compilation unit" roughly means one source file and all the headers it includes). This can be expressed explicitly by declaring them extern, or it can be overridden by declaring them static. Functions declared static have internal linkage, meaning they can be referenced by name only from other functions in the same compilation unit.
No two external functions anywhere in the same program can have the same name, regardless of header files, but static functions in different compilation units may have the same name. A static function may have the same name as an external function, too -- then the name resolves to the static function within its compilation unit, and to the external function elsewhere. These restrictions make sense, for otherwise it would be possible for a function call to be ambiguous.
Header files don't factor into the linkage equation at all. They are primarily a vehicle for sharing declarations, but a function's linkage depends only on how it is declared, not on where.
I leave discussion of variables' linkage for another time.
It doesn't matter whether one source module includes headers for another. Header files only contain declarations for the purpose of local functions being able to find functions in other modules. It doesn't mean that functions not declared don't exist from the perspective of that module.
When everything gets linked together, anything not specifically defined to be local to one source module (i.e. static) has to have a unique name across all linked components.
remember reading at some point that every function not declared static is global
Having understood this you got the main point and reason for the behaviour observed.
.h files are not known to the linker, after pre-processing there are only translation units left (typically a .c file with all includes merged in), from which .o files are compiled.
There are no interfaces on language level in C.
Neither of these source files are being included anywhere in the project, so they shouldn't be sharing any compilation units.
Declare those functions as static. This is the only way to "hide" a function from the linker "inside" a translation unit.
C doesn't "mangle" function names the way C++ or Java do (since C doesn't support function polymorphism).
For example, in C++, the functions
void foo( void );
void foo( int x );
void foo( int x, double y );
have their names "mangled" into the unique symbols1
_Z3fooid
_Z3fooi
_Z3foov
which is how overloaded function/method calls are disambiguated at the machine level.
C doesn't do that; instead, the linker sees two different function definitions using the same symbol and yaks because it has no way to disambiguate the two.
1. This is what happens on my system, anyway
Is there a case when a function can be defined within a header file? I was told by person whose opinion I respect that there are cases when a function can be defined in a header file included by multiple C source files. However, I could not find any. Just confirm, I define the function in-line in a header file but that also did not work. I will but have not found any answers yet. There is no practical requirement as such. I just wanted to see if there is some part of the C standard that I don't know of which will allow this. Thanks for any answers
Yes, but only if it is declared as static inline.
Functions that are declared simply as inline behave exactly like functions that are defined with no modifiers, except that they may be inlined within the translation unit that they're defined as inline in. They still have global scope, so including them in a header file will result in errors, as the function will be multiply defined.
static inline functions, on the other hand, do not have global scope — they only exist where they are used, more in line (ha ha) with the way you probably think of inline functions. As such, they're appropriate for use in header files.
No C function should not be defined in Header files.
function declaration can go in Header files.
But function definition should not ever go in header files.
Reason:
If function defination goes in header files then header will be included by multifple c files and when they are going to compile they will give error for multi defination of same files.
static inline function can be defined in Header files.
But that should not be used because
The "static" keyword in "static inline" is harmful in the situation
where a "static inline" function gets included and compiled in N
different files and does not get inlined. In this situation, one would
typically want the N copies of this function to get merged into one,
to avoid code bloat. But the "static" keyword prevents that, forcing
the linker to not merge these redundant functions.
As a side note to the answers/discussion on inline functions, I believe that theoretically one could define a function in a header in the same way as in a normal .c file, providing the header was only included once and in single location.
Though I'm not sure if the standard explicitly forbids this or not, it follows from the idea that the contents of a header file are essentially being copied and pasted into the top of the source file in which it is included from which point of view, there would be no issue.