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.
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
说明符必须在before或with函数的定义和before[=72] =] 它是 odr-used(odr-use 意味着编译器需要实际发出调用函数的代码,或者出于任何原因需要它的地址)。
inline
说明符在函数的链接上有 no effect,对于非静态全局函数,它仍然是外部的。如果使用 inline
函数(具有外部链接)的地址,编译器将为其发出一个外联定义,确保链接器可以在必要时折叠多个定义(例如使用弱符号).这样 inline
函数在不同 TU 中的地址将是相同的。
一旦函数被声明 inline
并且具有外部链接,它必须在所有其他使用它的翻译单元中被声明 inline
。
您必须在每个使用它的翻译单元中提供inline
函数的定义,并且必须完全相同。
考虑以下示例(在同一翻译单元中):
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
? Isf
still consideredinline
?
是的,f
仍然被认为是inline
。
有关 inline
函数说明符语义的标准相关部分可以在 [dcl.fct.spec]:
A function declaration ... with an
inline
specifier declares an inline function. Theinline
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.
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
说明符必须在before或with函数的定义和before[=72] =] 它是 odr-used(odr-use 意味着编译器需要实际发出调用函数的代码,或者出于任何原因需要它的地址)。inline
说明符在函数的链接上有 no effect,对于非静态全局函数,它仍然是外部的。如果使用inline
函数(具有外部链接)的地址,编译器将为其发出一个外联定义,确保链接器可以在必要时折叠多个定义(例如使用弱符号).这样inline
函数在不同 TU 中的地址将是相同的。一旦函数被声明
inline
并且具有外部链接,它必须在所有其他使用它的翻译单元中被声明inline
。您必须在每个使用它的翻译单元中提供
inline
函数的定义,并且必须完全相同。