使用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视为变量?
另外,为什么这会出现链接器错误?
答案 0 :(得分:6)
当您获取地址或绑定对NUMBER
的引用时:
foo(NUMBER); // bind a reference
const int* p = &NUMBER; // taking address
你是odr-using变量,这意味着它需要一个行外定义:
const int Thing::NUMBER ;
从上面引用cppreference:
非正式地说,如果一个对象的地址被占用,或者一个引用被绑定到该对象上,那么该对象就会被使用,如果对它进行函数调用或者使用它的地址,则该函数会被使用。如果一个对象或函数使用了odr,它的定义必须存在于程序的某个地方;违反这一点的是链接时错误。
Jonathan Wakely在上面的评论中提供了一个很好的参考:undefined reference to `S::a'。
答案 1 :(得分:3)
您必须定义静态数据成员。例如
const int Thing::NUMBER;
在类中,仅声明静态数据成员。如果编译器不需要其地址,则不需要其定义。但是,您的代码使用数据成员的地址
const int* p = &NUMBER;
因此编译器必须定义常量。