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

Reply via email to