Linker error: undefined reference in a function template that uses external variables

Viewed 248

I have a mini project with two files:

main.cpp

#include <string>
template<int I>
int getint(int i)
{
    extern std::string var;
    return var.size() * i;
}

int main()
{
    return getint<2>(2);
}

and sub.cpp

#include <string>
extern std::string var;
std::string var = "Hello";

But when I compile the project, the linker gives the error:

-------------- Clean: Debug in test (compiler: GNU GCC Compiler)---------------

Cleaned "test - Debug"

-------------- Build: Debug in test (compiler: GNU GCC Compiler)---------------

mingw32-g++.exe -Wall -fexceptions -g  -c C:\Users\Fan\Downloads\test\test\main.cpp -o obj\Debug\main.o
mingw32-g++.exe -Wall -fexceptions -g  -c C:\Users\Fan\Downloads\test\test\sub.cpp -o obj\Debug\sub.o
mingw32-g++.exe  -o bin\Debug\test.exe obj\Debug\main.o obj\Debug\sub.o   
obj\Debug\main.o: In function `Z6getintILi2EEii':
C:/Users/Fan/Downloads/test/test/main.cpp:6: undefined reference to `var'
collect2.exe: error: ld returned 1 exit status
Process terminated with status 1 (0 minute(s), 0 second(s))
2 error(s), 0 warning(s) (0 minute(s), 0 second(s))

I have no clue how this happens, because as long as I simplified the program a little, the problem goes away.

  1. If I make getint() a plain old function instead of a function template, then the compilation succeeds.

  2. If I move the line "extern std::string var;" outside the function (say to one line above it), then the compilation succeeds.

  3. If I change the type of var to an int (and omit ".size()" in main.cpp, and assign 1 to it in sub.cpp), then the compilation succeeds.

It seems a weird combination of factors that prevent my original project from compiling. I have no idea what they are :(

Edit: In response to the "cannot reproduce" remark, I am trying the compilation on my local windows 7 machine using Code::Blocks 17.12. Output of the compiler and the linker has been updated to include compiler flags.

0 Answers
Related