原因分析
在頭文件map.h中定義了數組:struct MyStruct arr[2]
#ifndef MAP_H
#define MAP_H
struct MyStruct{
int id;
int num;
};
struct MyStruct arr[2] = {{1,4},{2,6}};
void PrintMap();
#endif
而在test.c和map.c中都include了map.h:
//map.cpp
#include"map.h"
#include<stdio.h>
void PrintMap(){
printf("%d\n",arr[0].num);
}
//test.cpp
#include <stdio.h>
#include "map.h"
int main() {
printf("%d\n",arr[0].num);
return 0;
}
以上的結果是在test.obj和map.obj中都定義了數組arr,arr在不同的模塊中對應不同的地址單元,因爲一旦包含.h,則定義一個arr,編譯器爲之分配內存。換句話說就是這2個arr是不同的arr!
注意:#ifndef, #define, #endif 只能防止一個c/cpp文件內重複包含頭文件。
多個c/cpp之間是獨立的,不能互相阻止。
StackOverflow相關問題:Variable definition in header files
附錄:
Header guard protects you from multiple inclusions in a single source file, not from multiple source files. I guess your problem stems from not understanding this concept.
It is not that pre-processor guards are saving during the compile time from this problem. Actually during compile time, one only source file gets compiled into an obj, symbol definitions are not resolved. But, in case of linking when the linker tries to resolve the symbol definitons, it gets confused seeing more than one definition casuing it to flag the error.