Header-only and static-inline-only library in C

2.7k views Asked by At

I write small header-only and static-inline-only libraries in C. Would this be a bad idea when applied to big libraries? Or is it likely that the running time will be faster with the header-only version? Well, without considering the obvious compilation time difference.

2

There are 2 answers

1
justin On BEST ANSWER

Yes, it is a bad idea -- especially when integrated with larger libraries.

The problem of inline functions' complexity generally increases as these libraries are included and visible to more translations and more complex header inclusion graphs -- which is quite common with larger projects. It becomes much more time consuming to build as translation counts and dependencies increase. The increase is not typically linear complexity.

There are reasons this flies in C++, but not in C. inline export semantics differ. In short, you will end up producing tons of copies of functions in C (as well as functions' variables). C++ deduplicates them. C does not.

Also, inlining isn't a silver bullet for speed. The approach will often increase your code size and executable size. Large functions can create slower code. Copies of programs/functions can also make your program slower. Larger binaries take more time to link and initialize (=launch). Smaller is usually better.

It's better to consider alternatives, such as Link Time Optimizations, Whole Program Optimizations, Library design, using C++ -- and to avoid C definitions in headers.

Also keep in mind that the compiler can eliminate dead code, and the linker can eliminate unused functions.

0
Jon Chesterfield On

I wrote a unit testing framework* as a single C89 header file. Essentially everything is a macro or marked static and link time optimisation (partly) deduplicates the result.

This is a win for ease of use as integration with build systems is trivial.

Compile times are OK, since this is C, but the resulting function duplication does bother me a little. It can therefore be used as header + source instead by setting a macro before #including in a single source file, e.g.

#define MY_LIB_HEADER_IMPLEMENTATION
#include "my_lib.h"

I don't think I would take this approach for a larger project, but I think it's optimal for what is essentially a set of unit testing macros.

  • in the "don't call us, we'll call you" sense