对内联函数有不同的定义是否是一种未定义的行为
Is it an undefined behavior to have different definitions of an inline function?
最少的代码:
// --------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()
,那么他们将分别打印YES
和NO
,这意味着它们指的是同一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() 的不同函数体。
你试过吗?具有不同的优化级别?
我得到是和否,是和是,或否和否,具体取决于优化级别和编译对象呈现给链接器的顺序。
不用说,这是未定义的行为。
相关文章:
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 从 std::string 到 std::array<char,size> 的 memcopy 额外数据是否是一种未定义的行为?
- 在硬件SIMD矢量指针和相应类型之间进行"interpret_cast"是一种未定义的行为吗
- C 编译器未检查模板类中是否存在一种方法
- 如何将对象定义为一种类型,然后再将其声明为子类型
- 在另一台计算机中运行 GTKMM 代码时未定义的符号
- 是否有另一种方法可以在不使用宏定义的情况下进行此操作
- 是否有一种方法可以修复编译器未找到特定的OPENCV变量/函数
- 在类似工会的类中,“reinterpret_cast”上的“这个”是一种未定义的行为吗?
- 使用二维数组作为一维数组是否正确?可能会导致未定义的行为左右?
- 推荐一种在未输入获取行分隔符时引发异常的方法?
- (C )正在创建专门用于处理所有其他自定义对象的类/对象一种处理项目的正确方法
- 为什么glut.h会在CodeBlocks中弹出一堆未定义的引用
- 对内联函数有不同的定义是否是一种未定义的行为
- 这是一种未定义的行为吗?我可以在没有温度的情况下交换值吗?
- 当您将引用返回到局部变量时,它是否是一种未定义的行为
- 如何创建一组未定义的shared_ptr对象
- 是否可以在全局对象构造函数中进行打印/日志记录,或者这是一种未定义的行为?
- 操作符只能以一种方式定义——c++
- C++:函数重新声明是一种未定义的行为