【问题标题】:Using a regular function with the name of an inline function in C在 C 中使用带有内联函数名称的常规函数
【发布时间】:2020-11-26 18:10:48
【问题描述】:

假设我有两个文件:

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 函数?

【问题讨论】:

  • 尝试在main中调用get。
  • 来自en.cppreference.com/w/c/language/inline : 如果非静态函数被声明为内联,那么它必须在同一个翻译单元中定义。不使用 extern 的内联定义在外部是不可见的,也不妨碍其他翻译单元定义相同的函数。这使得 inline 关键字可以替代 static 用于在头文件中定义函数,这些函数可能包含在同一程序的多个翻译单元中。
  • @P__JsupportswomeninPoland 我做了,在上面进行了相应的编辑。编译正常,2.c 中的定义按预期使用。 14 在 main 中返回。

标签: c function inline


【解决方案1】:

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

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

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

6使用inline 函数说明符声明的函数是内联函数。使 afction 成为内联函数 建议对函数的调用与 138) 此类建议的适用程度 有效是实现定义的。139)

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


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

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

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

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

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

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

【讨论】:

    【解决方案2】:

    来自inline functions上的这个链接

    你可以有一个单独的(不是内联的)定义在另一个 翻译单元,编译器可能会选择那个或 内联定义。

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

    【讨论】:

    • 谢谢,这是未定义的行为。
    • 不是未定义的。如另一个答案所述 - 未指定。不一样
    猜你喜欢
    • 2012-02-11
    • 1970-01-01
    • 2022-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-21
    • 2017-01-05
    相关资源
    最近更新 更多