将 static const int 作为引用传递时出现链接器错误

Linker error when passing static const int as reference

为什么在使用 gcc 4.6.3 编译时会出现对 NUMBER 的未定义引用错误?:

g++ -std=c++0x -pipe -Wall -pedantic file.c

file.c:

#include <stdio.h>
#include <utility>

class Thing {
public:
    Thing() {
        foo(NUMBER);
        const int* p = &NUMBER;
        printf("%d\n", *p);
    }
    void foo(const int& i) {}
    static const int NUMBER = 123;
};

int main() { Thing thing; return 0; }

错误:

chetic@home:~/Documents$ g++ -std=c++0x -pipe -Wall -pedantic test.c 
/tmp/cceBY2zr.o: In function `Thing::Thing()':
statest.c:(.text._ZN5ThingC2Ev[_ZN5ThingC5Ev]+0x11): undefined reference to `Thing::NUMBER'
statest.c:(.text._ZN5ThingC2Ev[_ZN5ThingC5Ev]+0x21): undefined reference to `Thing::NUMBER'

我在这里提到了#3:http://eel.is/c++draft/class.static.data/#3 但我希望有人能用更简单的术语解释一下。

为什么编译器不给出一个可读的错误让我大吃一惊,或者为什么不将 NUMBER 视为变量?

此外,为什么这会显示为链接器错误?

您必须定义静态数据成员。例如

const int Thing::NUMBER;

在 class 中只声明了静态数据成员。如果编译器不需要它的地址,则不需要它的定义。但是您的代码使用数据成员的地址

const int* p = &NUMBER;

因此编译器必须定义常量。

当你取地址或绑定引用时NUMBER:

foo(NUMBER);            // bind a reference
const int* p = &NUMBER; // taking address

你是 odr-using 变量,这意味着它需要一个越界定义:

const int Thing::NUMBER ;

引用上面的 cppreference:

Informally, an object is odr-used if its address is taken, or a reference is bound to it, and a function is odr-used if a function call to it is made or its address is taken. If an object or a function is odr-used, its definition must exist somewhere in the program; a violation of that is a link-time error.

Jonathan Wakely 在上面的评论中提供了很好的参考:undefined reference to `S::a'