6

I've been trying to fix my multiple definition error and most answers seem to be to use extern but even after I did that the error still persists

main.cpp

#include "header.h"

int main(){

ifstream indata;
indata.open(file.c_str());

int x;

while(indata){
    indata >> x;
    print(x);
}

return 0;
}

functions.cpp

#include "header.h"

void print(int x){
    cout << x << endl;
}

header.h

#ifndef _HEADER_H
#define _HEADER_H

#include <fstream>
#include <iostream>
#include <string>
#include <cstring>

using namespace std;

extern string file="testFile.txt";

void print(int x);

#endif

Makefile

all: main

main.o: main.cpp header.h
    g++ -c main.cpp

functions.o: functions.cpp header.h
    g++ -c functions.cpp

main: main.o functions.o
    g++ main.o functions.o -o main

check: all
    ./main

clean:
    rm -f *.o main

and the resulting error message i get is

make
g++ -c main.cpp
In file included from main.cpp:1:0:
header.h:11:15: warning: ‘file’ initialized and declared ‘extern’
 extern string file="testFile.txt";
               ^
g++ -c functions.cpp
In file included from functions.cpp:1:0:
header.h:11:15: warning: ‘file’ initialized and declared ‘extern’
 extern string file="testFile.txt";
               ^
g++ main.o functions.o -o main
functions.o:functions.cpp:(.bss+0x0): multiple definition of `file'
main.o:main.cpp:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status
Makefile:10: recipe for target 'main' failed
make: *** [main] Error 1

Can someone point me in the right direction here.

Jc.kal
  • 93
  • 1
  • 1
  • 3

4 Answers4

10

An extern declaration is the one to be shown to every translation unit, not a definition,

Consider leave nothing but

extern string file;

in the header, then move the definition to one of the source files:

string file = "testFile.txt";
iDingDong
  • 447
  • 2
  • 11
3

Your initializer "overrides" the extern keyword, making the line a definition rather than a declaration.

You cannot have your cake and eat it too.

Community
  • 1
  • 1
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
1

Declare it in header.h:

extern string file;

And define it in a .cpp file:

string file = "testFile.txt";

Otherwise everything that includes header.h will have its own definition of file, resulting in the "multiple definition of `file'" error you got.

Emil Laine
  • 41,598
  • 9
  • 101
  • 157
1

Extern is a directive to tell the linker that the definition of the symbol is available in another object file. extern is a declaration specifier - i.e. it is not a definition. You should not define a variable declared as extern.

As a practise, it is not good to have global variables defined in header files. That is the reason for the multiple definition error. This is because your header file is included in both the cpp files.

Solution:

Remove from header.h extern string file="testFile.txt"

Add to functions.cpp string file="testFile.txt"

Add to main.cpp extern declaration extern string file;

buchipper
  • 606
  • 4
  • 16