2017-03-09 100 views
0

我有一個頭文件和兩個源文件。在所述頭文件中,我有以下聲明:包含數組聲明頭時出錯

const char *letters[] = {"A", "B", "C", "D"}; 

我在兩個源文件中都包含了我的頭文件。當我嘗試編譯,我得到:

/tmp/cc6gLw9s.o:(.data+0xa0): multiple definition of `letters' 
/tmp/ccjqd0rr.o:(.data+0xa0): first defined here 
+4

您有多次定義的相同變量,它是一個數組,但仍然是一個變量。你不應該把變量**定義**放在頭文件中。 – StoryTeller

+3

這在技術上不是*編譯器*錯誤,而是*鏈接器*錯誤,並且意味着您*定義了多個[*翻譯單元*]中的變量(https://en.wikipedia.org/wiki/Translation_unit_%28programming %29)(基本上所有包含頭文件的源文件)。不要*在頭文件中定義變量(或函數)。 –

回答

5

如果單獨編譯2的源文件和他們每個人包括頭,那麼變量letters將被宣佈兩次,一次在每一個源文件。爲了防止這種情況,在頭文件中聲明變量爲extern

extern const char *letters[]; 

然後,把實際的變量在源文件。

const char *letters[] = {...}; 
+0

關於全局變量,尤其是那些與外部鏈接有關的全局變量,爲什麼會有問題,您能否加上一兩句話?這是唯一讓我困擾的答案。 – StoryTeller

+0

我不太確定該說些什麼。我知道他們很醜陋,但我從來沒有真正有過任何經驗,因爲他們過去特別麻煩,因爲我主要使用團結建設。 – bace1000

+0

這與構建封裝的好設計沒有多大關係。它也成爲多線程程序中的噩夢。但好吧,NVM。 – StoryTeller

1

在C中包含文件幾乎是從字面上複製和粘貼它。如果在同一個編譯中包含兩次頭文件,就好像該代碼被寫入了兩次。

這通常通過使用預處理器來避免標頭被編譯兩次而避免。

#ifndef _MYHEADERS_H_ 
#define _MYHEADERS_H_ 

const char *letters[] = {"A", "B", "C", "D"}; 

#endif 

這是除了在其他答案中提出的問題。