GCC链接器抱怨对现有全局变量的未定义引用

Nie*_*kob 4 c++ linker gcc ld

我遇到了GCC的问题.它无法找到我的全局变量.我创建了一个示例C++项目来隔离问题:

a.cpp:

#include "b.h"

const char * const g_test = "blah blah";

int main(){
    test();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

b.cpp:

#include <iostream>
#include "a.h"

using namespace std;

void test(){
    cout << g_test;
}
Run Code Online (Sandbox Code Playgroud)

啊:

extern const char * const g_test;
Run Code Online (Sandbox Code Playgroud)

BH:

void test();
Run Code Online (Sandbox Code Playgroud)

我这样编译:

$ 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
Run Code Online (Sandbox Code Playgroud)

在最后一个命令中更改目标文件的顺序不会改变任何内容.

为什么链接器会抛出错误?我本来希望只是创建一个可执行的打印"blah blah",但不知怎的错误出现了.我认为没有任何理由会失败.

Haa*_*hii 6

由于const变量g_test只有内部链接,即只能在.cpp文件中使用它.为了给出const变量全局链接(即使其可以从其他源文件中使用),您必须添加extern关键字,即:

#include "b.h"

extern const char * const g_test = "blah blah";

int main(){
    test();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以a.h在开头包括.在这种情况下,extern转换时编译器知道前向声明a.cpp.

然而,最好的解决方案是将g_test(无extern关键字)的定义移动到头文件中.原因在于,通过这种方式,编译器知道g_test每个编译单元中的定义,并且例如能够在编译时使用它来计算const表达式.