我遇到GCC问题。它无法找到我的全局变量。我创建了一个示例C ++项目来隔离问题:
a.cpp:
#include "b.h"
const char * const g_test = "blah blah";
int main(){
test();
return 0;
}
b.cpp:
#include <iostream>
#include "a.h"
using namespace std;
void test(){
cout << g_test;
}
A.H:
extern const char * const g_test;
b.h:
void test();
我这样编译:
$ g++ -o a.o -c a.cpp
$ g++ -o b.o -c b.cpp
$ g++ -o test a.o b.o
b.o: In function `test()':
b.cpp:(.text+0x7): undefined reference to `g_test'
collect2: error: ld returned 1 exit status
在最后一个命令中更改目标文件的顺序并不会改变任何内容。
为什么链接器会抛出错误?我本来希望只是创建一个可执行的打印&#34; blah blah&#34;,但不知怎的错误出现了。我没有看到它应该失败的原因。
答案 0 :(得分:6)
由于const变量g_test
只有内部链接,即只能在.cpp文件中使用它。为了给const变量提供全局链接(即使其可以从其他源文件中使用),你必须添加extern
关键字,即:
#include "b.h"
extern const char * const g_test = "blah blah";
int main(){
test();
return 0;
}
或者,您可以在开头添加a.h
。在这种情况下,编译器在翻译extern
时会知道a.cpp
前向声明。
然而,最好的解决方案是将g_test
(没有extern
关键字)的定义移到头文件中。原因是编译器以这种方式知道每个编译单元中g_test
的定义,并且例如能够在编译时使用它来计算const表达式。
答案 1 :(得分:0)
最简单的解决方案是将关键字extern
添加到您的定义中。我知道看起来很奇怪,extern
通常使它成为前向声明而不是deffinition,但编译器仍将它视为定义(实例化),因为你给它一个值。
Quentin的评论(stolen from Quentin)中的链接是对原因的一个很好的解释。