Search code examples
c++sdlextern

extern undefined reference error when declaring variable


I have 2 header files and 1 source file to work with. Respectively: Utility.h, Game.h and main.cpp. I have declared extern variables in Utility.h and am trying to define them in main.cpp. This gives me an undefined reference error, which I don't understand. I use the variable AFTER I give it a value, so that should be fine?

Utility.h:

#pragma once

#include <string>
#include <fstream>
#include <SDL.h>

namespace Utility {
    extern std::string BIN_PATH;
    extern std::string ROOT_PATH;
    extern std::string EXE_PATH;

    // Omitted rest of namespace.
}

main.cpp

#include "Game.h"

int main(int argc, char * argv[]) {
    // Get the necessary paths
    std::string path = SDL_GetBasePath();

    #ifdef _WIN32
        // TODO check if working on different windows systems
        //  exePath = path;
        //  binPath = path.substr(0, path.find_last_of('\\'));
        //  rootPath = binPath.substr(0, binPath.find_last_of('\\'));
    #elif __LINUX__
        Utility::BIN_PATH = path.substr(0, path.find_last_of('/'));
        Utility::ROOT_PATH = Utility::BIN_PATH.substr(0, binPath.find_last_of('/'));
        // TODO check if working on different linux systems
    #endif

    std::cout << "BinPath: " + Utility::BIN_PATH << std::endl;
    std::cout << "RootPath: " + Utility::ROOT_PATH << std::endl;

    // Omitted rest of source.
}

I am including Utility.h in Game.h, and Game.h in main.cpp. Shouldn't that put the extern definitions above my main.cpp source when linking?


Solution

  • To simplify (rather complicated) rules a bit, each variable (as well as other entities) must be defined once and only once in the whole program. It can be declared multiple times. It is important to understand what is a declaration and what is a definition.

    extern std::string var; // in namespace scope
    

    Is a declaration of string variable var. var is not yet defined. You need to define it somewhere else - only once - by using

    std::string var; // in namespace scope!
    

    In your code, you do not define the variable in function main - instead, you are assigning the value to it. But the variable needs to be defined.