开发者

Header-only linking

Many C++ projects (e.g. many Boost libraries) are "header-only linked".

Is th开发者_如何学Cis possible also in plain C? How to put the source code into headers? Are there any sites about it?


Executive summary: You can, but you shouldn't.

C and C++ code is preprocessed before it's compiled: all headers are "pasted" into the source files that include them, recursively. If you define a function in a header and it is included by two C files, you will end up with two copies in each object file (One Definition Rule violation).

You can create "header-only" C libraries if all your functions are marked as static, that is, not visible outside the translation unit. But it also means you will get a copy of all the static functions in each translation unit that includes the header file.

It is a bit different in C++: inline functions are not static, symbols emitted by the compiler are still visible by the linker, but the linker can discard duplicates, rather than giving up ("weak" symbols).

It's not idiomatic to write C code in the headers, unless it's based on macros (e.g. queue(3)). In C++, the main reason to keep code in the headers are templates, which may result in code instantiation for different template parameters, which is not applicable to C.


You do not link headers.

In C++ it's slightly easier to write code that's already better-off in headers than in separately-compiled modules because templates require it. 1

But you can also use the inline keyword for functions, which exists in C as well as C++. 2

// Won't cause redefinition link errors, because of 6.7.4/5
inline void foo(void) {
   // ...
}

[c99: 6.7.4/5:] A function declared with an inline function specifier is an inline function. The function specifier may appear more than once; the behavior is the same as if it appeared only once. Making a function an inline function suggests that calls to the function be as fast as possible. The extent to which such suggestions are effective is implementation-defined.

You're a bit stuck when it comes to data objects, though.


1 - Sort of.
2 - C99 for sure. C89/C90 I'd have to check.


Boost makes heavy use templates and template meta-programming which you cannot emulate (all that easily) in C.

But you can of course cheat by having declarations and code in C headers which you #include but that is not the same thing. I'd say "When in Rome..." and program C as per C conventions with libraries.


Yes, it is quite possible. Declare all functions in headers and either all as static or just use a single compilation unit (i.e. only a single c file) in your projects.

As a personal anecdote, I know quite a number of physicists who insist that this technique is the only true way to program C. It is beneficial because it's the poor man's version of -fwhole-program, i.e. makes optimizations based on the knowledge of function behaviour possible. It is practical because you don't need to learn about using the linker flags. It is a bad idea because your whole program must be compiled as a whole and recompiled with each minor change.

Personally, I'd recommend to let it be or at least go with static for only a few functions.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜