对静态常量积分类型的未定义引用
Undefined reference to static const integral type
我对静态整数常量有一个奇怪的行为:
#include <iostream>
#include <inttypes.h>
class Test{
public:
static const uint32_t Magic = 0x1123;
};
class DataStream{
public:
template<typename T>
DataStream& operator <<( const T& value )
{
std::cout << value << std::endl;
return *this;
}
};
int main()
{
DataStream s;
uint32_t a = Test::Magic; // ok
bool compare = ( a == Test::Magic ); // ok
s << compare;
s << a;
s << Test::Magic; // fail
return 0;
}
我知道这样的常量应该在类外定义.cpp
const uint32_t Test::Magic;
但奇怪的是,上面的代码在外行s << Test::Magic;
下工作正常,并且只有在直接与模板operator <<
一起使用时才Magic
产生错误。
GCC
出现更多的错误undefined reference to 'Test::Magic'
,但MSVC
不会出现。
问题是为什么我应该在类外定义Test::Magic
(即使没有值!!(,以及为什么我的代码在某些情况下即使没有这样的定义也能正常工作?
通常,如果使用 ODR,则应.cpp文件中定义所有静态常量名称。参考论点是ODR using
他们。但是,违反此规则是未定义的行为,MSVC 不报告错误只是显示未定义行为的方式之一。
作为实际考虑因素,当函数未内联时,您可能会遇到错误,并且对于内联函数可能看不到错误。我的猜测是,内联的工作方式与您用于这些编译器的优化级别不同。
§ 9.4.2 静态数据成员 [class.static.data]
如果非易失性 const 静态数据成员是整型或枚举类型,则其在类定义中的声明可以指定 大括号或等于初始值设定项 [...]这如果成员在程序中是 ODR-use(3.2(,则仍应在命名空间作用域中定义成员,并且命名空间作用域定义不应 包含初始值设定项。
[ 注意:程序中应只有一个odr 使用的静态数据成员定义 (3.2(;无需诊断。—尾注 ]
相关文章:
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- 编译时的 CImg 库返回对"__imp_SetDIBitsToDevice"的未定义引用
- 对Py_Initialize()的未定义引用
- 使用mysql c++连接器的未定义引用
- 对 Scalar ::Scalar() 的未定义引用
- 对复制 CTOR 和 CTOR 的未定义引用
- 对显式实例化的模板函数的未定义引用
- TensorRT (C++ API) 对"createNvOnnxParser_INTERNAL"的未定义引用
- 2个模板化类的非模板友元函数未定义引用错误
- 编译 libfluid 样本控制器时对"event_base_del_virtual"的未定义引用
- 获取对function_name的未定义引用
- 对 'std::thread::_M_start_thread CMake 的未定义引用进行基准测试
- 对结构方法的未定义引用
- 使用内联函数 c++ 的未定义引用
- 对 CMake 中'cudaRegisterLinkedBinary'链接错误的未定义引用?
- 对 DLOPEN 的未定义引用
- QT C++中对全局变量的未定义引用
- 快速数学导致对"__pow_finite"的未定义引用
- 对 boost::system::d etail::system_category_instance 的未定义引用,从
- OpenCV 3.4.3 中对 'cv::String::d eallocate()' 错误的未定义引用