对内联函数有不同的定义是否是一种未定义的行为

Is it an undefined behavior to have different definitions of an inline function?

本文关键字:一种 未定义 定义 函数 是否是      更新时间:2023-10-16

最少的代码:

// --------inline.h--------
struct X { 
  static inline void foo ();
};   
#ifdef YES
inline void X::foo () { cout << "YESn"; }
#else
inline void X::foo () { cout << "NOn"; }
#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()的不同功能体。

不管这是否应该编码,我的问题是:
这是一个明确定义或未定义的行为?

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

参考:

C++03 标准:

7.1.2 函数说明符
第4段:

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

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

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

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

未定义。您违反了 ODR。

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

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

我得到是和否,是和

是,或否和否,具体取决于优化级别和编译对象呈现给链接器的顺序。

不用说,这是未定义的行为。

相关文章: