beejjorgensen / bgc

Beej's Guide to C Programming source
Other
467 stars 88 forks source link

Nitpicks on inline functions #125

Closed LegionMammal978 closed 4 months ago

LegionMammal978 commented 1 year ago

In 41.1.1, "inline for Speed—Maybe", you write:

Another way is to declare the function as extern inline. This will attempt to inline in this file, but will also create a version with external linkage. And so gcc will use one or the other depending on optimizations, but at least they’re the same function.

This is not quite accurate: a function definition with extern inline is no longer an inline definition (C17 6.7.4/7), so it behaves identically to a normal extern definition (except for the suggestion to the compiler). So there's only ever one version of the definition.

But let’s say you’re doing a build where the compiler is inlining the function. In that case, you can just use a plain inline in the definition.

As it happens, using an non-static inline definition without providing an external definition is always forbidden in ISO C (C17 6.9/5, emphasis mine):

An external definition is an external declaration that is also a definition of a function (other than an inline definition) or an object. If an identifier declared with external linkage is used in an expression (other than as part of the operand of a sizeof or _Alignof operator whose result is an integer constant), somewhere in the entire program there shall be exactly one external definition for the identifier; otherwise, there shall be no more than one.

So such a program is always considered invalid, even though the compiler need not produce an error or warning.

You can’t refer to any static globals:

Nor can you call any static functions from a non-static inline definition.

beejjorgensen commented 4 months ago

OK, I've finally gotten around to this and took a machete to the section. It was just too much anyway. But I think I have it right based on your much-appreciated feedback. Please reopen if there's still something wrong in there.

Cheers!