名称空间::变量的多重定义,即使使用ifndef

时间:2018-07-20 05:04:05

标签: c++ c++11 namespaces ifndef

我知道我这里一定做错了。

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;
}

以及编译结果;

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

我的理解是头文件被多次包含。但是我希望通过使用#ifndef来解决此问题。

那么,请问这是怎么回事?

2 个答案:

答案 0 :(得分:3)

int chunk;

不仅是声明,还是定义。 #include是.hpp文件的每个.cpp文件最终都会对其进行定义。

将其更改为

extern int chunk;

然后,确保在.cpp文件中定义它。

rank.cpp

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

答案 1 :(得分:2)

在C ++中,每个文件(也称为翻译单元)分别编译。因此,main.cpp的编译完全独立于rank.cpp的编译。一个编译中的#define无法影响其他编译。到将两个目标文件链接在一起时,定义已经消失了。

包含防护的目的是防止在一次编译中两次而不是在多次编译中一次包含一个头文件。