c++ - 静态常量类成员声明

标签 c++ gcc linker

在 Foo.h 中:

class Foo
{
public:
    Foo();
    static const unsigned int FOOBAR = 10;
    static const unsigned int BARFOO = 20;

private:
    unsigned int m_FooBar;
    bool m_Bar;
    void Bar();
};

在 Foo.cpp 中:

Foo::Foo()
    : m_FooBar(FOOBAR), // this works
      m_Bar(false)
{
}

void Foo::Bar()
{
    //m_FooBar = m_Bar ? FOOBAR : BARFOO; // linker fails *1
    m_FooBar = FOOBAR; // ok
}

我正在使用 GCC 4.5.3 进行编译。取消注释行 *1 时链接器会失败的原因是什么?

Foo.o: In function 'Foo::Bar' (name unmangled):
Foo.cpp: undefined reference to `Foo::FOOBAR'
Foo.cpp: undefined reference to `Foo::BARFOO'

尝试使用 VC2005、2008、2010 和 CB2010。他们都编译并链接得很好。为什么 GCC 在这种情况下会失败?

鉴于 answer here ,为什么其他流行的编译器不像 GCC 那样失败?不管怎样,对于 GCC 或其他流行的编译器来说,它必须是一个错误。还是有更合理的解释?

最佳答案

形式上,头文件只声明了静态常量,而且它们也必须被定义(至少在 C++03 中是这样)。但是,如果您只使用它们的值,那么您通常会逃脱惩罚。

在 C++11 中,这被更正式地指定为当静态“使用 odr”时需要定义。 *1 行就是一个例子。三元运算符试图形成对值的引用,而编译器(或实际上是链接器)意识到它不能。


C++11 标准说

9.4.2 Static data members
§3...
The member shall still be defined in a namespace scope if it is odr-used (3.2) in the program and the namespace scope definition shall not contain an initializer.

关于c++ - 静态常量类成员声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12489597/

相关文章:

c++ - C 风格字符串和 C++ 中的动态分配

gcc - 如何使用 gccgo 构建完整的 go 程序二进制文件?

c++ - 如何使用 PKEY_Device_FriendlyName 修复链接器错误

c - 在特定内存中定位c库函数

c++ - 当它是模板参数时默认成员变量指针

c++ - 消息包头的设计模式

c++ - 仅使用整数计算两条线的交点

gcc - 为什么我的 flex/yacc 编译器在另一台 Linux 机器上无法正确编译

c++ - Gcc 预处理器和粘贴

c++ - 尽管包含路径中的头文件中存在函数定义,但 C++ 中的“ undefined reference ”错误