c++compiler-errorsmultiple-definition-error

C++ Multiple definitions even though only one definition is given


I'm trying to make a small unordered map that I can use to store keys and values permanently, as a sort of dictionary. The type TengwarChar is just an object with two values, a string and an enum, and later I'll add methods too. The header I use is as follows:

#ifndef TENGWARLIBRARY_H
#define TENGWARLIBRARY_H

#include "tengwarchar.h"
#include <unordered_map>
#include <algorithm>
#include <string>

typedef std::unordered_map<std::string, TengwarChar> CharMap;

extern const CharMap numbers = {
    {"0", TengwarChar("ð", SHORT)},
    {"1", TengwarChar("ñ", SHORT)},
    {"2", TengwarChar("ò", SHORT)},
    {"3", TengwarChar("ó", SHORT)},
    {"4", TengwarChar("ô", SHORT)},
    {"5", TengwarChar("õ", SHORT)},
    {"6", TengwarChar("ö", SHORT)},
    {"7", TengwarChar("÷", SHORT)},
    {"8", TengwarChar("ø", SHORT)},
    {"9", TengwarChar("ù", SHORT)}
 };

std::string translateFromEnglishToTengwar(std::string str);
std::string translateFromTengwarToEnglish(std::string str);

#endif // TENGWARLIBRARY_H

Then, I have a simple testing cpp file that goes along with it:

#include "tengwarlibrary.h"

std::string translateFromEnglishToTengwar(std::string str)
{
    std::transform(str.begin(), str.end(), str.begin(), (int (*)(int))std::tolower);
    return str;
}

std::string translateFromTengwarToEnglish(std::string str)
{
    return "Hello world.";
}

The problem is, I keep getting 'multiple definition of numbers[abi:cxx11]' errors, when invoke translateFromTengwarToEnglish in my main function, even though I'm fairly certain I have only defined it once, in my header file, using header guards too. In case it might help, here is my humble main cpp file:

#include "mainwindow.h"
#include <QApplication>

#include <iostream>

#include "utils/tengwarlibrary.h"

int main(int argc, char *argv[])
{

    std::string s = "BlaH FElfeFEJI, IEORlfj";
    std::cout<<translateFromEnglishToTengwar(s)<<std::endl;

    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

Solution

  • According to C++ standard §3.1.2

    A declaration is a definition unless it declares a function without specifying the function’s body, it contains the extern specifier or a linkage-specification and neither an initializer nor a function-body ...

    Declaration of numbers in the header file tengwarlibrary.h is extern declaration with initializer. So it is also a definition.

    As you have included tengwarlibrary.h in two source files (one where translateFromTengwarToEnglish() is defined and where main() defined) both of them has the definition of numbers. Hence, the error.

    To solve this problem declare number with extern in header file and initialize it in a single source file.