C++ 内联重新声明

C++ inline redeclaration

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

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

重新声明 f 时会发生什么? f 是否仍被认为是 inline

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

[...] If the definition of a function or variable appears in a translation unit before its first declaration as inline, the program is ill-formed. [...]

我想要标准中的一些参考资料,详细说明在这种情况下会发生什么。

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

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

中指定

A declaration may introduce one or more names into a translation unit or redeclare names introduced by previous declarations. If so, the declaration specifies the interpretation and attributes of these names.[...]

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

What happens at the redeclaration of f? Is f still considered inline?

是的,f仍然被认为是inline

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

中找到

A function declaration ... with an inline specifier declares an inline function. The inline specifier indicates to the implementation that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism.

An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly the same definition in every case ([basic.def.odr]). [ Note: A call to the inline function may be encountered before its definition appears in the translation unit. — end note ] If the definition of a function appears in a translation unit before its first declaration as inline, the program is ill-formed. If a function with external linkage is declared inline in one translation unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required. An inline function with external linkage shall have the same address in all translation units.

[basic.def.odr]中:

Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program

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

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

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

一切的解释是:

  • inline 作为函数说明符充当标志,表达您希望内联给定函数的调用。一旦在某个函数声明上遇到它,对于那个特定的函数重载,它仍然是"set",没有办法"unset"它。

  • 声明 定义 中指定 inline 并不重要一个函数,因为一个定义 is also a declaration and because multiple declarations are allowed.
    但是,inline说明符必须在beforewith函数的定义和before[=72] =] 它是 odr-used(odr-use 意味着编译器需要实际发出调用函数的代码,或者出于任何原因需要它的地址)。

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

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

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