具有内联函数的不同定义是不确定的行为?

时间:2012-06-26 04:31:09

标签: c++ inline undefined-behavior function-prototypes

最小代码:

// --------inline.h--------
struct X { 
  static inline void foo ();
};   
#ifdef YES
inline void X::foo () { cout << "YES\n"; }
#else
inline void X::foo () { cout << "NO\n"; }
#endif

// --------file1.cpp--------
#define YES    // <---- 
#include"inline.h"
void fun1 ()
{
  X::foo();
}

// --------file2.cpp--------
#include"inline.h"
void fun2 ()
{
  X::foo();
}

如果我们拨打fun1()fun2(),他们将分别打印YESNO,这意味着他们指的是同一个X::foo()的不同功能正文

无论是否应编码,我的问题是:
这是一个定义明确或未定义的行为吗?

3 个答案:

答案 0 :(得分:13)

是的,这是未定义的行为。

<强>参考:

C ++ 03标准:

7.1.2函数说明符[dcl.fct.spec]
第4段:

  

内联函数应在每个使用它的翻译单元中定义,并且在每种情况下都应具有完全相同的定义(3.2)。 [注意:在定义出现在翻译单元之前,可能会遇到对内联函数的调用。 ]如果在一个翻译单元中内联声明具有外部链接的功能,则应在其出现的所有翻译单元中内联声明;无需诊断。一个   具有外部链接的内联函数在所有翻译单元中应具有相同的地址。外部内联函数中的静态局部变量始终引用同一个对象。 extern内联函数中的字符串文字是不同翻译单元中的相同对象。

注意:3.2指的是一个定义规则,其中规定:

3.2一个定义规则[basic.def.odr]
第1段:

  

任何翻译单元都不得包含任何变量,函数,类类型,枚举类型或模板的多个定义。

答案 1 :(得分:7)

未定义。您违反了ODR。

答案 2 :(得分:4)

  

如果我们调用fun1()和fun2(),那么它们将分别打印YES和NO,这意味着它们引用相同X :: foo()的不同函数体。

你尝试过吗?具有不同的优化级别?

我得到YES和NO,YES和YES,或NO和NO取决于优化级别和编译对象呈现给链接器的顺序。

毋庸置疑,这是未定义的行为。