链接器为某些上下文中使用的集成静态常量成员提供错误"undefined symbol"
Linker gives error "undefined symbol" for integral static const members used in certain contexts
可能重复:
C++-在类定义中定义静态常量整数成员
注意:关于类似的问题,有几个现存的问题,但我已经审查了其中的许多问题,无法找到解释这种行为的答案:
假设我有如下代码(在头文件中)
class Foo {
static const int TEST = 33;
public:
void willItWork(void) {
printf("%d", std::max(TEST, 75)); // embedded platform, no streams
}
};
int main(void) {
Foo tester;
tester.willItWork();
}
这将编译,但不会链接。我得到链接器错误
错误:L6218E:未定义的符号Foo::TEST(从Foo.o引用).
似乎只是将值传递给外部函数会导致问题。在类中的普通表达式或函数中使用TEST
可以很好地工作。如果我改为将willItWork()
写为
void willItWork(void) {
int diff = TEST - 23;
printf("%d", diff);
}
没有错误。
我发现了另一个引用C++标准的问题(第9.4.2节):
如果静态数据成员是const整型或const枚举类型,则其在类定义中的声明可以指定const初始值设定项,该初始值设定值设定项应为整型常量表达式。
既然我所做的似乎"在规则范围内",有人能想到对这种奇怪行为的任何可能解释吗?
我在ideone上尝试了类似的代码,没有问题(然而,我无法模仿确切的结构,即头文件)。这是否意味着我使用的链接器不完全符合这里的标准?
任何见解都将不胜感激。我也可以随时提供更多信息。
如果编译器认为它需要static
成员变量的地址,例如,在某个点将变量绑定到引用时,它将创建一个相应的未定义符号,并且您必须定义成员:
int const foo::TEST;
(在一个翻译单元中)。如果编译器只访问该值,则可以不定义该对象。除非您需要类型为int
,否则可以使用enum
,从而避免定义成员:
enum { TEST = 33 };
如果我没有记错的话,标准中要查找的术语是odr使用的。
std::max
通过引用而不是通过值获取参数。将引用绑定到静态常量需要一个实际对象,而不仅仅是值。
相关文章:
- 私有类型的静态常量成员
- constexpr构造函数需要常量成员函数时出现问题
- 是否可以同时声明一个类成员的常量/非常量?
- 当成员值从指针更改为非指针时,C++常量问题
- 常量公共成员有什么问题?
- Clang 格式 10.0 与 5.0 常量成员函数的格式不同
- C++/QT:使用指向私有成员的常量指针作为只读数据共享
- 空指针常量 (nullptr)、空指针值和空成员指针值之间有什么区别?
- 为什么"具有常量成员的结构"类型的指针不能指向"具有非常量成员的结构"?
- 初始化依赖于子类的继承类的常量类成员
- 常量成员函数中成员变量的类型
- 如何为非常量和常量重载实现一次成员函数?
- 如何处理运算符=中的常量成员?
- 移动类的成员作为常量引用参数传递
- 为什么我可以改变常量对象中的成员变量,这是返回常量对象函数的结果?
- 常量和引用成员函数限定符
- 返回对常量结构(指针类型)成员的引用:明显的左值到右值转换
- 常量成员和没有setter的私有成员之间有什么区别
- 如何初始化类C++的成员常量向量
- 当我希望调用基类构造函数时,如何在派生类中初始化成员常量引用