Search code examples
cfunctioninline

Using a regular function with the name of an inline function in C


Assume I have two files:

1.c

inline int test(int in){
 return in+1; 
}

int get();

int main(){
 return get();
}

2.c

int test(int in){
  return in+9;
}

int get(){
 return test(5);
}

Compiling it with gcc 1.c 2.c goes smoothly with no errors.

Is this defined behaviour? i.e test in 1.c is different from the other function and we essentially have 2 test functions in generated in code?


Solution

  • The inline copy of test in 1.c doesn't actually constitute a external function definition, allowing for test in 2.c to be used by the program. If you were to call get in the main function and print the result, you would get the value 14.

    If you were to call test from the main function, is could use either version of the function. Which one it does use is unspecified.

    The mechanics of inline are specified in section 6.7.4 of the C standard, paragraphs 6 and 7:

    6 A function declared with an inline function specifier is an inline function. Making af unction 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.140)


    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.

    140 ) Since an inline definition is distinct from the corresponding external definition and from any other corresponding inline definitions in other translation units, all corresponding objects with static storage duration are also distinct in each of the definitions.

    As an example of unspecified behavior, if you added the following line to main:

    printf("test(3)=%d\n", test(3));
    

    If you compile in gcc with -O0 you'll get test(3)=12. If you compile with -O1 or higher you'll get test(3)=4.