C++内联重新声明



考虑以下示例(在同一翻译单元中):

inline void f();
void f() {}

重新宣布f时会发生什么?f还算inline吗?

我查看了这种情况的标准,但我只在 10.1.6/6 [dcl.inline] 中找到了相反的情况:

[...]如果函数或变量的定义出现在翻译单元中,然后才将其首次声明为内联,则程序格式不正确。[...]

我想要标准中的一些参考资料,以指定在这种情况下会发生什么。

我看到了这篇文章,但它没有在标准中显示明确的参考。我倾向于相信没有这样的参考。

重新声明f时会发生什么?f还算inline吗?

是的,f仍然被认为是inline.

标准中与inline函数说明符语义相关的部分可以在[dcl.fct.spec]中找到:

函数声明...使用inline说明符声明内联函数。inline说明符向实现指示,在调用点对函数体进行内联替换比通常的函数调用机制更可取。

内联函数应在使用它的每个翻译单元中定义,并且在每种情况下都应具有完全相同的定义([basic.def.odr])。[注意:在内联函数的定义出现在翻译单元中之前,可能会遇到对内联函数的调用。 —尾注] 如果函数的定义出现在翻译单元中,然后才将其第一次声明为内联,则程序格式不正确。如果具有外部链接的功能在一个翻译单元中声明为内联,则应在出现该函数的所有翻译单元中声明为内联;无需诊断。具有外部链接的inline职能在所有翻译单元中应具有相同的地址。

在[basic.def.odr]中:

每个

程序应只包含该程序中使用的每个非内联函数或变量的一个定义

另请参阅 [dcl.stc]/8 中的示例:

void h();
inline void h();                // external linkage
inline void l();
void l();                       // external linkage

所有内容的解释是:

  • inline作为函数说明符充当标志,表达您希望对给定函数的调用内联。一旦在某个函数声明中遇到它,它就会为该特定函数重载保持"设置",并且无法"取消设置"它。

  • 声明或函数定义上指定inline并不重要,因为定义也是声明,并且允许多个声明。
    但是,必须在函数定义之前或函数定义之前以及 odr 使用之前遇到inline说明符(odr-use意味着编译器需要实际发出调用函数的代码,或者出于任何原因需要其地址)。

  • inline说明符对函数的链接没有影响,对于非静态全局函数,函数的链接仍然是外部的。如果获取inline函数(具有外部链接)的地址,编译器将为其发出一个外联定义,确保链接器可以在必要时折叠多个定义(例如使用弱符号)。这样,不同 TU 中inline函数的地址将是相同的。

  • 一旦一个函数被声明为inline并具有外部链接,就必须在使用它的所有其他翻译单元中inline声明它。

  • 您必须在 odr 使用的每个翻译单元中提供inline函数的定义,并且它必须完全相同。

重新声明的效果在 [basic.def]/1 中指定

声明可以将一个或多个名称引入翻译单元,或重新声明先前声明引入的名称。如果是这样,声明将指定这些名称的解释和属性。[...]

因此,通过重新声明,可以为名称添加规范,但不能删除它们。

相关内容

  • 没有找到相关文章

最新更新