简体   繁体   English

当存在与内联函数同名的extern函数时,将调用哪一个?

[英]Which one is called when existing an extern function with the same name as an inline function?

test.cpp 测试文件

#include <iostream>
void f()
{
    std::cout<<"non-inline"<<std::endl;
}

main.cpp main.cpp

#include <iostream>
using namespace std;
inline void f()
{
    cout<<"inline"<<endl;
}

int main()
{
    f();
    return 0;
}

In debug mode, the output is: non-inline. 在调试模式下,输出为:非内联。 command:g++ [-g] -o main main.cpp test.cpp 命令:g ++ [-g] -o main main.cpp test.cpp

In release mode, the output is: inline. 在发布模式下,输出为:内联。 command:g++ -O -o main main.cpp test.cpp 命令:g ++ -O -o main main.cpp test.cpp

Why? 为什么?

Linux G++ 4.7.3 Linux G ++ 4.7.3

In C99, an inline definition does not provide an external definition for the function, so we can provide an external definition of the identifier by defining another function in other source file. 在C99中,内联定义不为函数提供外部定义,因此我们可以通过在其他源文件中定义另一个函数来提供标识符的外部定义。

Does an inline definition provide an external definition for the function in C++?? 内联定义是否为C ++中的函数提供外部定义?

Thx!! 谢谢!!

Your program has UB (Undefined Behaviour), because it violates ODR (One Definition Rule) by providing two different definitions of f() . 您的程序具有UB(未定义行为),因为它通过提供f()两个不同定义来违反ODR(一个定义规则f() There is therefore next to no way of reasoning why it behaves one way or the other. 因此,几乎没有理由推理它为什么以一种或另一种方式表现。 In the best tradition of UB, any behaviour is possible (including ordering pizza over the Internet). 按照UB的最佳传统,任何行为都是可能的(包括通过Internet订购披萨)。

EDIT 编辑

These quotes from the standard (ISO/IEC 14882:2011) prove it's UB: 这些来自标准(ISO / IEC 14882:2011)的引用证明它是UB:

[basic.def.odr]§3: [basic.def.odr]§3:

Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; 每个程序应准确地包含该程序中使用的每个非内联函数或变量的一个定义; no diagnostic required. 无需诊断。 ... An inline function shall be defined in every translation unit in which it is odr-used. ...内联函数应在使用过的每个翻译单元中定义。

[basic.def.odr]§5: [basic.def.odr]§5:

There can be more than one definition of ... inline function with external linkage ... in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. 如果每个定义出现在不同的翻译单元中,并且满足以下要求,则在程序中可以有一个以上定义...具有外部链接的内联函数... Given such an entity named D defined in more than one translation unit, then 给定这样一个在多个翻译单元中定义的名为D的实体,则

  • each definition of D shall consist of the same sequence of tokens; D的每个定义应由相同的令牌序列组成; and
  • ... ...

[dcl.fct.spec]§4 [dcl.fct.spec]§4

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 (3.2). 内联函数应在使用过的每个翻译单元中定义,并且在每种情况下均应具有完全相同的定义(3.2)。 [ 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. -end note ]如果函数的定义在其首次声明为内联之前出现在转换单元中,则程序格式错误。 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. 无需诊断。 ... ...

(Emphasis mine) (强调我的)

Your program violate the One definition Rule then it is Undefined behavior . 您的程序违反了一个定义规则,那么它是未定义行为

When you have an Undefined behaviour , anything is possible but you have to know that the worst case will come during the most important demo ;) 当您有未定义的行为时 ,一切皆有可能,但您必须知道最重要的演示期间会出现最坏的情况;)

The standard says: 该标准说:

3.2 One definition rule [basic.def.odr] 3.2一个定义规则[basic.def.odr]

1/ No translation unit shall contain more than one definition of any variable, function, class type, enumeration type, or template. 1 /任何翻译单元不得包含多个变量,函数,类类型,枚举类型或模板的多个定义。

[...] [...]

4/ Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; 4 /每个程序应准确地包含该程序中使用的每个非内联函数或变量的一个定义; no diagnostic required. 无需诊断。 The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see 12.1, 12.4 and 12.8). 该定义可以显式出现在程序中,可以在标准库或用户定义的库中找到,或者(在适当的情况下)可以隐式定义(请参见12.1、12.4和12.8)。 An inline function shall be defined in every translation unit in which it is odr-used. 内联函数应在使用的每个翻译单元中定义。

5/ There can be more than one definition of [...] inline function with external linkage (7.1.2) [...] in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. 5 /在程序中,具有外部链接(7.1.2)的内联函数可以有多个定义,只要每个定义出现在不同的翻译单元中,并且这些定义满足以下要求。 Given such an entity named D defined in more than one translation unit, then 给定这样一个在多个翻译单元中定义的名为D的实体,则

  • each definition of D shall consist of the same sequence of tokens; D的每个定义应由相同的令牌序列组成; and

  • [...] [...]

If the definitions of D satisfy all these requirements, then the program shall behave as if there were a single definition of D. If the definitions of D do not satisfy these requirements, then the behavior is undefined. 如果D的定义满足所有这些要求,则程序应像D的单个定义那样运行。如果D的定义不满足这些要求, 则该行为未定义。

And later: 然后:

7.1.2 Function specifiers [dcl.fct.spec] 7.1.2功能说明符[dcl.fct.spec]

4/ 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 (3.2). 4 / 内联函数应在使用过的每个翻译单元中定义,并且在每种情况下均应具有完全相同的定义 (3.2)。 [ Note : A call to the inline function may be encountered before its definition appears in the translation unit. [ 注意 :内联函数的定义可能会在转换单元中出现之前被调用。 endnote ] If the definition of a function appears in a translation unit before its first declaration as inline, the program is ill-formed. endnote ] 如果函数的定义在其首次声明为内联之前出现在翻译单元中,则程序格式错误。 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. 无需诊断。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM