5

I have a problem with GCC. It's unable to find my global variable. I created a sample C++ project to isolate the problem:

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();

I compile it like this:

$ 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

Changing the order of object files in last command doesn't change anything.

Why does linker throw an error? I was expecting to just create an executable printing "blah blah", but somehow the error appears. I don't see any reason it should fail.

Maya
  • 1,490
  • 12
  • 24

2 Answers2

7

As a const variable g_test has only internal linkage, i.e. can only be used in the .cpp file it is defined. In order to give a const variable global linkage (i.e. make it usable from other source files) you have to add the extern keyword, i.e.:

#include "b.h"

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

int main(){
    test();
    return 0;
}

Alternatively you can include a.h at the beginning. In that case the extern forward declaration is known to the compiler when translating a.cpp.

The best solution however is to move the definition of g_test (without extern keyword ) into the header file. The reason being that in this way the compiler knows the definition of g_test in every compilation unit and is for example able to evaluate const expressions using it at compile time.

Haatschii
  • 9,021
  • 10
  • 58
  • 95
0

The easiest solution is to add the keyword extern to your definition. I know that looks weird, extern usually makes it a forward declaration and not a deffinition, but the compiler will still treat it as a definition (instantiation) because you give it a value.

The link in Quentin's comment (stolen from Quentin) is a fantastic explanation of why.

Community
  • 1
  • 1
Jfevold
  • 422
  • 2
  • 11