[英]Which one is called when existing an extern function with the same name as an inline function?
测试文件
#include <iostream>
void f()
{
std::cout<<"non-inline"<<std::endl;
}
main.cpp
#include <iostream>
using namespace std;
inline void f()
{
cout<<"inline"<<endl;
}
int main()
{
f();
return 0;
}
在调试模式下,输出为:非内联。 命令:g ++ [-g] -o main main.cpp test.cpp
在发布模式下,输出为:内联。 命令:g ++ -O -o main main.cpp test.cpp
为什么?
Linux G ++ 4.7.3
在C99中,内联定义不为函数提供外部定义,因此我们可以通过在其他源文件中定义另一个函数来提供标识符的外部定义。
内联定义是否为C ++中的函数提供外部定义?
谢谢!!
您的程序具有UB(未定义行为),因为它通过提供f()
两个不同定义来违反ODR(一个定义规则f()
。 因此,几乎没有理由推理它为什么以一种或另一种方式表现。 按照UB的最佳传统,任何行为都是可能的(包括通过Internet订购披萨)。
编辑
这些来自标准(ISO / IEC 14882:2011)的引用证明它是UB:
[basic.def.odr]§3:
每个程序应准确地包含该程序中使用的每个非内联函数或变量的一个定义; 无需诊断。 ...内联函数应在使用过的每个翻译单元中定义。
[basic.def.odr]§5:
如果每个定义出现在不同的翻译单元中,并且满足以下要求,则在程序中可以有一个以上定义...具有外部链接的内联函数... 给定这样一个在多个翻译单元中定义的名为D的实体,则
- D的每个定义应由相同的令牌序列组成; 和
- ...
[dcl.fct.spec]§4
内联函数应在使用过的每个翻译单元中定义,并且在每种情况下均应具有完全相同的定义(3.2)。 [ 注意:内联函数的定义可能会在转换单元中出现之前被调用。 -end note ]如果函数的定义在其首次声明为内联之前出现在转换单元中,则程序格式错误。 如果在一个翻译单元中内联声明了具有外部链接的功能,则应在出现该功能的所有翻译单元中将其内联声明; 无需诊断。 ...
(强调我的)
当您有未定义的行为时 ,一切皆有可能,但您必须知道最重要的演示期间会出现最坏的情况;)
该标准说:
3.2一个定义规则[basic.def.odr]
1 /任何翻译单元不得包含多个变量,函数,类类型,枚举类型或模板的多个定义。
[...]
4 /每个程序应准确地包含该程序中使用的每个非内联函数或变量的一个定义; 无需诊断。 该定义可以显式出现在程序中,可以在标准库或用户定义的库中找到,或者(在适当的情况下)可以隐式定义(请参见12.1、12.4和12.8)。 内联函数应在使用的每个翻译单元中定义。
5 /在程序中,具有外部链接(7.1.2)的内联函数可以有多个定义,只要每个定义出现在不同的翻译单元中,并且这些定义满足以下要求。 给定这样一个在多个翻译单元中定义的名为D的实体,则
D的每个定义应由相同的令牌序列组成; 和
[...]
如果D的定义满足所有这些要求,则程序应像D的单个定义那样运行。如果D的定义不满足这些要求, 则该行为未定义。
然后:
7.1.2功能说明符[dcl.fct.spec]
4 / 内联函数应在使用过的每个翻译单元中定义,并且在每种情况下均应具有完全相同的定义 (3.2)。 [ 注意 :内联函数的定义可能会在转换单元中出现之前被调用。 — endnote ] 如果函数的定义在其首次声明为内联之前出现在翻译单元中,则程序格式错误。 如果在一个翻译单元中内联声明了具有外部链接的功能,则应在出现该功能的所有翻译单元中将其内联声明; 无需诊断。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.