2

可能重复:
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-initializer,它应该是一个整数常量表达式。

由于我所做的似乎是“在规则范围内”,任何人都可以为这种奇怪的行为想出任何可能的解释吗?

我在 ideone 上尝试了类似的代码并且没有问题(但是,我无法模仿确切的结构,即那里的头文件)。这是否意味着我使用的链接器不太符合这里的标准?

非常感谢任何见解。我也可以随时提供更多信息。

4

2 回答 2

4

如果编译器认为它需要static成员变量的地址,例如,在某个时刻将变量绑定到引用时,它将创建一个相应的未定义符号,您将不得不定义该成员:

int const foo::TEST;

(在一个翻译单元中)。如果编译器只访问 a 值,您可以不定义对象而侥幸逃脱。除非您需要类型为 an int,否则您可以使用 anenum并避免定义成员的需要:

enum { TEST = 33 };

如果我没记错的话,要查找的标准中的术语是odr-used 。

于 2012-11-15T01:47:50.637 回答
3

std::max通过引用而不是值来获取其参数。绑定对静态 const 的引用需要一个实际的对象,而不仅仅是值。

于 2012-11-15T01:46:05.323 回答