Multiple definition of namespace::variable even using ifndef

1.5k Views Asked by At

I know I must be doing something wrong here.

rank.h

#ifndef RANK_H
#define RANK_H
namespace mmi {
int chunk;
void rank(int my_rank);
}
#endif

rank.cpp

#include "rank.h"
namespace mmi {
//do something with chunk
}

main.cpp

#include "rank.h"
int main() {
    mmi::chunk = 1;
}

And the output of compilation;

g++ -g -Wall -std=gnu++11   -c -o main.o main.cpp
g++ -g -Wall -std=gnu++11   -c -o rank.o rank.cpp
mpic++ main.o rank.o  -o main
rank.o:(.bss+0x0): multiple definition of `mmi::chunk'
main.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status
Makefile:12: recipe for target 'main' failed
make: *** [main] Error 1

My understanding is that header file is being included multiple times. But I was expecting to correct this issue by using the #ifndef.

So, may I ask what's going on here?

2

There are 2 best solutions below

6
R Sahu On BEST ANSWER

The line

int chunk;

is not only a declaration, it is also a definition. Every .cpp file that #includes the .hpp file ends up defining it.

Change it to

extern int chunk;

Then, make sure to define it in a .cpp file.

rank.cpp

#include "rank.h"
namespace mmi {
   int chunk;
  //do something with chunk
}
0
john On

In C++ each file (aka translation unit) is compiled separately. So the compilation of main.cpp is completely independent from the compilation of rank.cpp. There is no way that a #define in one compilation can affect the other compilation. And by the time you link your two object files together the defines have disappeared.

The purpose of include guards is to prevent the inclusion of one header file twice during a single compilation, not across multiple compilations.