命名空间::变量的多重定义,甚至使用 ifndef

KcF*_*nMi 3 c++ namespaces c++11 ifndef

我知道我在这里一定做错了什么。

等级.h

#ifndef RANK_H
#define RANK_H
namespace mmi {
int chunk;
void rank(int my_rank);
}
#endif
Run Code Online (Sandbox Code Playgroud)

排名.cpp

#include "rank.h"
namespace mmi {
//do something with chunk
}
Run Code Online (Sandbox Code Playgroud)

主程序

#include "rank.h"
int main() {
    mmi::chunk = 1;
}
Run Code Online (Sandbox Code Playgroud)

以及编译的输出;

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
Run Code Online (Sandbox Code Playgroud)

我的理解是头文件被包含多次。但我希望通过使用#ifndef.

那么,我可以问一下这是怎么回事吗?

R S*_*ahu 5

线路

int chunk;
Run Code Online (Sandbox Code Playgroud)

不仅是一个声明,它也是一个定义。.hpp 文件的每个#include.cpp 文件最终都会定义它。

将其更改为

extern int chunk;
Run Code Online (Sandbox Code Playgroud)

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

排名.cpp

#include "rank.h"
namespace mmi {
   int chunk;
  //do something with chunk
}
Run Code Online (Sandbox Code Playgroud)

  • @HackerDaGreat57,但所有这些错误都是已知的,并将在现有软件中考虑在内,或者根本不会遇到。迁移到新的编译器是一种不必要的风险,可能会出现新的错误或依赖于现已修复的错误而破坏代码,并且在环境变化迫使迁移到新工具之前项目经理可能会离开。明智之举是花一点钱来保持产品和工具链的最新状态,但人类,就其本质而言,几乎总是会为了更多的钱或更轻松的生活而将问题抛在一边。 (2认同)