5

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.

5gon12eder
  • 24,280
  • 5
  • 45
  • 92
  • Functions generally shouldn't be defined in headers. – 2501 Nov 21 '14 at 21:02
  • @2501 Using static inline functions in headers in not uncommon. –  Nov 21 '14 at 21:03
  • Even if that would be true, it is still wrong. – 2501 Nov 21 '14 at 21:04
  • @2501 it's done to guarantee that the function definition appears before it's use, to ensure that inlining happens. I wouldn't say it's "wrong" for `static inline`, as there's no external linkage then. – Dmitri Nov 21 '14 at 21:27
  • @Dmitri What happens if the user starts playing with and comparing function pointers of a library that is static inline header only. – 2501 Nov 21 '14 at 21:29
  • @2501 Well, you can't... just like with a function-like macro. I'm not saying purely inlined functions are always appropriate, but when used the header is often a good place to define them. – Dmitri Nov 21 '14 at 21:32
  • @Dmitri You can compare them just fine, the problem is that the comparison of pointers that point to the same function: `pThisFunction == pThisFunction` can give false as a result. – 2501 Nov 21 '14 at 21:35

2 Answers2

3

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.

justin
  • 104,054
  • 14
  • 179
  • 226
  • 1
    Do you have a reference that non-static inline C functions don't deduplicate at the link stage? Or rather that they deduplicate differently than with c++? If so on what platforms? – textshell Jan 12 '20 at 22:07
1

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
Jon Chesterfield
  • 2,251
  • 1
  • 20
  • 30