Reputation: 7935
inline void foo();
int main() {
foo(); return 0;
}
void foo(){
}
Is there any difference if setting foo
's declaration as inline
and not foo
's definition? How about the opposite? How about marking them both as inline
?
Upvotes: 3
Views: 212
Reputation: 47603
This is all C11 says about inline (Note: inline
is a function specifier, currently the only other function specifier is _Noreturn
) (emphasis mine):
6.7.4
2. Function specifiers shall be used only in the declaration of an identifier for a function.
3. An inline definition of a function with external linkage shall not contain a definition of a modifiable object with static or thread storage duration, and shall not contain a reference to an identifier with internal linkage.
5. A function specifier may appear more than once; the behavior is the same as if it appeared only once.
6. A function declared with an inline function specifier is an inline function. Making a function an inline function suggests that calls to the function be as fast as possible.138 The extent to which such suggestions are effective is implementation-defined.139
7. Any function with internal linkage can be an inline function. For a function with external linkage, the following restrictions apply: If a function is declared with an inline function specifier, then it shall also be defined in the same translation unit. If all of the file scope declarations for a function in a translation unit include the inline function specifier without extern, then the definition in that translation unit is an inline definition. An inline definition does not provide an external definition for the function, and does not forbid an external definition in another translation unit. An inline definition provides an alternative to an external definition, which a translator may use to implement any call to the function in the same translation unit. It is unspecified whether a call to the function uses the inline definition or the external definition.
10. EXAMPLE 1 The declaration of an inline function with external linkage can result in either an external definition, or a definition available for use only within the translation unit. A file scope declaration with extern creates an external definition. The following example shows an entire translation unit.
inline double fahr(double t) { return (9.0 * t) / 5.0 + 32.0; } inline double cels(double t) { return (5.0 * (t - 32.0)) / 9.0; } extern double fahr(double); // creates an external definition double convert(int is_fahr, double temp) { /* A translator may perform inline substitutions */ return is_fahr ? cels(temp) : fahr(temp); }
11. Note that the definition of
fahr
is an external definition becausefahr
is also declared with extern, but the definition ofcels
is an inline definition. Becausecels
has external linkage and is referenced, an external definition has to appear in another translation unit (see 6.9); the inline definition and the external definition are distinct and either may be used for the call.138 By using, for example, an alternative to the usual function call mechanism, such as ‘‘inline substitution’’. Inline substitution is not textual substitution, nor does it create a new function. Therefore, for example, the expansion of a macro used within the body of the function uses the definition it had at the point the function body appears, and not where the function is called; and identifiers refer to the declarations in scope where the body occurs. Likewise, the function has a single address, regardless of the number of inline definitions that occur in addition to the external definition.
139 For example, an implementation might never perform inline substitution, or might only perform inline substitutions to calls in the scope of an inline declaration
6.9
5. An external definition is an external declaration that is also a definition of a function (other than an inline definition) or an object.
J.1 Unspecified behavior
- Whether a call to an inline function uses the inline definition or the external definition of the function (6.7.4).
J.2 Undefined behavior
- A function with external linkage is declared with an inline function specifier, but is not also defined in the same translation unit (6.7.4).
J.3 Implementation-define behavior
J.3.8 Hints
- The extent to which suggestions made by using the inline function specifier are effective (6.7.4).
6.7.4.3
: If you have an inline function that is also visible to the linker, it can't have static
local variables.
It also can't use file-scope variables/functions (defined like a global identifier but with static
). (Note: can someone
tell if my understanding is correct about this last sentence? It doesn't feel right.)
6.7.4.6
: Making a function inline doesn't force the compiler to act as if it's a macro. It just hints at the compiler that
you want the function to be fast.
6.7.4.7
:
static
function, you are allowed to make it inline
.inline
function declaration,
somewhere in the same TU it should be able to find its definition.inline
, then the compiler would see that function somewhat as static
(but not exactly).138
: No matter how many times you define the inline function in different TUs, they have the "same" address. I believe
this also means that if you use a function pointer to store the address and then call the function through that pointer, the
external definition of the function would be called.
6.9.5
: a normal function definition both declares and defines an external function. But as we saw before an inline definition
of the function doesn't define a defintion that would be externally visible, even though it may declare an external function.
1 In your example, if you place inline
in your definition of foo
, you will get an error by gcc (during link phase)
that foo
has undefined reference. If you place another implementation of foo
in the same file, you will get a redefinition error.
This is consistent with what I said: all-inline declarations/definitions don't provide external linkage and if the function is used
in the TU, it needs a definition in another TU.
Further reading:
Upvotes: 4