Множественное определение namespace :: variable даже с использованием 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,

Итак, могу я спросить, что здесь происходит?

0

Решение

Линия

int chunk;

это не только декларация, это также определение. Каждый файл .cpp, который #includes .pp файл заканчивается определением его.

Измените это на

extern int chunk;

Затем убедитесь, что вы определили его в файле .cpp.

rank.cpp

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

Другие решения

В C ++ каждый файл (он же переводчик) компилируется по отдельности. Таким образом, компиляция main.cpp полностью независима от компиляции rank.cpp. Не существует способа, которым #define в одной компиляции может повлиять на другую компиляцию. И к тому времени, когда вы свяжете два ваших объектных файла вместе, определения исчезнут.

Цель включать охранников состоит в том, чтобы предотвратить включение одного заголовочного файла дважды во время одной компиляции, а не в нескольких компиляциях.

2

По вопросам рекламы [email protected]