Search code examples
c++language-lawyercompiler-optimizationinline-functions

Is there any practical difference between an inline function having internal and external linkage, with compiler optimization?


If a function is static inline, inline here works only as a suggestion. With either static or static inline the function has internal linkage, and the compiler knows this function cannot be called outside of the translation unit. Thus possibly no symbol is emitted for this function with compiler optimization.

In case of inline functions with external linkage, the C++ standard document at 7.1.2.4 states,

An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly the same definition in every case. If the definition of a function appears in a translation unit before its first declaration as inline, the program is ill-formed. If a function with external linkage is declared inline in one translation unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required. An inline function with external linkage shall have the same address in all translation units. ...

which is different from C where, when an inline function "has external linkage and is referenced, an external definition has to appear in another translation unit; the inline definition and the external definition are distinct and either may be used for the call (6.7.4.8)".

On the other hand an inline function in a C++ program must be inline in every translation unit and have the same definition. When the compiler sees an extern inline function, it knows that when this function is called in another translation unit, there will be an identical definition provided in that same translation unit, so the compiler can possibly "inline" it with no symbol output.

So to my understanding, in case of C++, there should be no difference in object code output between static inline and extern inline under optimization. Is this correct?


Solution

  • The important distinction here is that functions with internal linkage in various translation units are different functions, while inline function definitions with external linkage in various translation units all define the same function. This can certainly affect generated code, if only in that if a symbol is emitted (because, for instance, a pointer to the function is stored), external linkage it makes it a weak rather than local symbol.

    However, the more significant difference is the possibility for ODR violations if “a” static inline function f is defined in a header file: any multiply-defined entity (e.g., a function template in a header file that is included more than once) that uses f is invalid because each definition uses a different f.