Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
469 views
in Technique[技术] by (71.8m points)

c - static inline functions in a header file

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;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...