0

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?

Some Name
  • 8,555
  • 5
  • 27
  • 77

1 Answers1

3

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:

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:

And many other questions, no doubt.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • But if the function definition is quite large would it be possible to declare it as `static inline` in header file? – Some Name Dec 27 '18 at 08:11
  • 2
    You _can_ declare any size of function `static inline` in a header. Beware of what happens if it is not inlined, or indeed if a large function is inlined many times. Use `inline` judiciously, cautiously. In case of doubt, don't — maybe overly cautious, but not by a large margin. – Jonathan Leffler Dec 27 '18 at 08:13
  • The quiestion is if we declare a static function (not `inline`ed) in a header file and define it with external linkage in a source file would we get UB? – Some Name Dec 27 '18 at 08:42
  • 1
    A static non-inline function defined in a header means that each file that includes the header will have its own copy of the function. There‘s no conflict with any of the other files that include the header; that’s the point of static functions. You should get unused function warnings if a file including the header doesn’t actually call it. There’s no conflict with a non-static copy either, as long as the file that defines it doesn’t also include the header. It is, though, wasteful to do that. If more than one file needs to use the function, it should not be static (non-inline) anywhere. – Jonathan Leffler Dec 27 '18 at 18:00