问题
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?
回答1:
The line
int chunk;
is not only a declaration, it is also a definition. Every .cpp file that #include
s 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
}
回答2:
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.
来源:https://stackoverflow.com/questions/51435384/multiple-definition-of-namespacevariable-even-using-ifndef