在 C 中使用具有内联函数名称的常规函数

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

假设我有两个文件:

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);
}

gcc 1.c 2.c 编译它很顺利,没有错误。

这是定义的行为吗?即 1.c 中的 test 与其他函数不同,我们基本上在代码中生成了 2 个 test 函数?

test in 1.c 的 inline 副本实际上并不构成外部函数定义,允许使用 2.c 中的 test由程序。如果您要在 main 函数中调用 get 并打印结果,您将得到值 14.

如果您要从 main 函数调用 test,则可以使用该函数的任一版本。它使用的是未指定

inline 的机制在 C standard 的第 6.7.4 节第 6 和第 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.

作为未指定行为的示例,如果您将以下行添加到 main

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

如果你用 -O0 在 gcc 中编译,你会得到 test(3)=12。如果您使用 -O1 或更高版本进行编译,您将得到 test(3)=4.

来自 link inline functions

You can have a separate (not inline) definition in another translation unit, and the compiler might choose either that or the inline definition.

所以,这就是编译器没有给出任何错误的原因。