【问题标题】:Extern Inline Risks外部内联风险
【发布时间】:2015-05-09 18:15:57
【问题描述】:

我不明白为什么这是不可能的:

inline void f(void) {}

int main(void)
{
    f();
}

extern inline的回答:

C99(或 GNU99):

"inline": 像 GNU "extern inline";没有外部可见的功能 发出,但可能会调用一个,因此必须存在

问题 1:

我的理解是 f() 不是外部可见的,对我来说外部可见意味着我不能从另一个文件调用 f(),但是这里我直接在 main 中调用它。有什么问题?

解决方案

定义放到.h文件中。

inline void f(void) {}

只有一个 .c 文件中的声明

extern inline void f(void); 

问题 2:

但我也可以这样做:

这个声明放在头文件中

extern inline void f(void);

而且这个定义只存在于一个 .c 文件中

extern void f(void) {}

现在我可以使用我想要的功能了,唯一的条件是不写

extern void f(void) {}

在任何其他 .c 文件中。

如果我不使用“正常”解决方案并像我刚刚写的那样做会有什么风险?

编译

gcc -std=c11

【问题讨论】:

  • 您是否有不想使用static的原因?
  • 对#1 的回答:是的,您就是这样做的。对#2 的回答:不,不要那样做。 extern inline void f(void); 在头文件中没有意义。
  • @DietrichEpp 我试图理解为什么它没有意义,那有什么问题?它与正确的解决方案有何不同,您能解释一下吗?谢谢
  • @Oleg,你看到我的回答了吗?

标签: c inline c11


【解决方案1】:

inline 关键字允许您使函数的定义在所有翻译单元 TU(.c 文件)中可见,而不会导致“多个定义的符号”错误。如果您考虑到这个目的,那么在一个 .c 文件中定义一个 inline 并通过标题声明在所有其他文件中引用它并没有多大意义。在这种情况下,只需忽略 inline 它就没有用了。 (并且在标头中声明 extern inline 就更没有意义了。)

对于可预见的情况,头文件中的inline 定义避免了在任何翻译单元中生成符号。所以这些不同的翻译单元不能相互冲突。当您的代码实际上需要符号时,此策略作为一个明显的限制。例如,如果您获取函数的地址,或者编译器出于某种原因决定他不能或不会使用“在线”函数的定义,则可能会出现这种情况。因此,您始终应该告诉编译器您要在哪个 TU 中发出符号。

【讨论】:

  • inline 修饰符通过在调用函数的每个位置嵌入函数体,消除了执行时的调用/返回开销。因为编译器会在每个调用它的地方嵌入函数体,所以完整的函数定义必须对编译器可见。为此,应在头文件中定义函数。
  • @user3629249,不,不是inline 说明符减少了开销,而是定义可见并且编译器决定内联它。关键字本身并不意味着,如果编译器在同一个 TU 中给出,则编译器可以将所有代码内联到位。您似乎将使用该关键字的意图与其技术效果混为一谈。
猜你喜欢
  • 1970-01-01
  • 2020-01-21
  • 2012-01-16
  • 1970-01-01
  • 2010-12-28
  • 2017-03-01
  • 2011-10-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多