On Thu, Mar 19, 2020 at 6:38 PM Gregory Nutt <spudan...@gmail.com> wrote:
> > > More likely is the fact that inlining is disabled at -O0 and now the > > functions really are implemented as static functions and generate > > static functions. Now you really do have unreferenced static > > functions. Try removing the static storage class from the inline > > prototypes. > > What would work best for header files is to declare inline functions as > extern. Then provide a C file with the inline function definitions. > this is preferable because it works in all cases: It works when > inlining is not enabled and it works with C89 compilers. This is > recommended: https://gcc.gnu.org/onlinedocs/gcc/Inline.html >From that page: "This combination of inline and extern has almost the effect of a macro. The way to use it is to put a function definition in a header file with these keywords, and put another copy of the definition (lacking inline and extern) in a library file. The definition in the header file causes most calls to the function to be inlined. If any uses of the function remain, they refer to the single copy in the library." To use the correct technical terminology, that *sucks*, because it means that we will have two copies of functions, which leads to a maintenance nightmare. > static inline in header files is never recommended: https://groups.google.com/forum/#!topic/mozilla.dev.platform/Ulw9HoZbSyQ That refers to code written in C++, not C. Later in the discussion, the OP writes: "You example is C. I had C++ in mind, as our codebase is predominantly C++. I should have made that clear. My point is that we have lots of file-scope static inlines in C++ headers. " C++ is sometimes said to be a "superset of C" but that isn't really true. Things are different in subtle ways that often lead to headaches, like this one. In C, if placing a function in a header, "static inline" is needed to avoid a "multiple definitions" problem, but means that if the compiler decides *not* to inline the function, and if the function is used from multiple C modules, then some code bloat results because you could end up with multiple copies of the object code in your executable. But I consider this to be a negligible problem because you should not make functions inline unless they're really short and simple anyway. There is another option: Macros instead of inline functions. Those come with advantages and disadvantages as well, but if written as follows: #define my_macro(x,y) do { blah blah blah } while (0) or #define my_multiline_macro(x,y) do { \ blah \ blah \ blah \ } while (0) then its being a macro becomes transparent to all callers. See https://stackoverflow.com/questions/257418/do-while-0-what-is-it-good-for. I've seen entire libraries implemented as C headers full of macros. Such as: Here's an example: https://github.com/silentbicycle/greatest/blob/master/greatest.h By the way, that's a very, very useful automated testing library, all self-contained in one header file. Cheers, Nathan