首页 > 解决方案 > 在 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顺利进行,没有错误。

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

标签: cfunctioninline

解决方案


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

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

的机制在C 标准inline的第 6.7.4 节第 6 和第 7 段中指定:

6用函数说明符声明的inline函数是内联函数。使 af 函数成为内联函数意味着对函数的调用尽可能快。138) 此类建议的有效程度由实施定义。139)

7任何具有内部链接的函数都可以是内联函数。对于具有外部链接的函数,适用以下限制: 如果函数用inline函数说明符声明,则它也应在同一翻译单元中定义。 如果翻译单元中函数的所有文件范围声明都包含inline函数说明符 without extern,则该翻译单元中的定义是内联定义。内联定义不为函数提供外部定义,也不禁止在另一个翻译单元中进行外部定义。 内联定义提供了外部定义的替代方案,翻译器可以使用它来实现对同一翻译单元中函数的任何调用。 未指定对函数的调用是使用内联定义还是外部定义。140)


138 ) 例如,通过使用通常函数调用机制的替代方案,例如“内联替换”。内联替换不是文本替换,也不是创建新函数。因此,例如,在函数体中使用的宏的扩展使用它在函数体出现时的定义,而不是函数所在的位置叫做; 标识符指的是正文出现的范围内的声明。
同样,该函数具有单个地址,而不管除外部定义之外出现的内联定义的数量。

139 ) 例如,一个实现可能永远不会执行内联替换,或者可能只对inline声明范围内的调用执行内联替换。

140)由于内联定义不同于对应的外部定义和其他翻译单元中的任何其他对应的内联定义,因此具有静态存储持续时间的所有对应对象在每个定义中也是不同的。

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

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

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


推荐阅读