2011-06-16 51 views
24

例如:C&C++缺省全局變量聯動,多個聲明&定義問題

code1.c /的.cpp

int a; 

// ... and so on 

code2.c /的.cpp

int a; 

int main(void) { 
    return 0; 
} 

去編譯:

$gcc code1.c code2.c  # this is fine 
$ 

$g++ code1.cpp code2.cpp # this is dead 
/tmp/ccLY66HQ.o:(.bss+0x0): multiple definition of `a' 
/tmp/ccnIOmPC.o:(.bss+0x0): first defined here 
collect2: ld returned 1 exit status 

是否有任何全局變量的連接CC++之間的差異?

+7

+1問很好 – Stuti 2011-06-16 11:30:18

+3

您可以通過使用'static'或(最好)一個無名的命名空間避免C++的問題,但是這不是你的問題。我擔心C連接規則不夠熟悉(與C++相反)。 – Sven 2011-06-16 11:32:34

+2

http://blogs.oracle.com/ali/entry/what_are_tentative_symbols – 2011-06-16 11:42:03

回答

18

這不是嚴格合法的。 int a;是C中的臨時定義。允許在C中使用外部鏈接的每個對象的每個翻譯單元的多個暫定義和最多一個非暫定義定義,但在程序中的所有翻譯單元中只能有一個定義。

這是一個通用的擴展,允許跨C中的多個翻譯單元進行試探性定義,只要不超過一個翻譯單元包含非暫定義的定義,但它不是嚴格的標準。

在C++ int a;只是一個定義 - 沒有試驗性的概念 - 並且跨程序的翻譯單元有多個對象的定義仍然是非法的。

對於C的情況,你不妨看一下this question

+0

感謝您的好回覆,我非常感謝:) – Bossliaw 2011-06-16 13:02:27

4

這兩者都是非法的,但C編譯器通常實現擴展。請參閱this answer

+0

感謝您的回答,我非常感謝 – Bossliaw 2011-06-16 13:04:57

+0

@Artefacto:爲此帶來的+1 – legends2k 2014-03-03 12:09:11

2

有針對的解決問題的方式有三種:

  1. 如果變量a是在這兩個文件是相同的,則必須在所有文件中聲明爲extern只有一個除外。 extern關鍵字對鏈接器說,此名稱位於另一個文件中。

  2. 您可以使用static關鍵字將變量範圍限制爲一個文件。它在哪裏被宣佈。

  3. 或者您可以使用無名稱的命名空間。

+0

感謝您的回答,我非常感謝 – Bossliaw 2011-06-16 13:04:14

+0

還有'-zmuldefs',但它通常被認爲是邪惡解決方案 – 2015-07-10 20:59:44

1

g ++編譯器比gcc編譯器更加嚴格。 它也取決於gcc的版本,可能是gcc的更高版本,即4.X以上,它可能會給出相同的錯誤。

使用extern避免

+0

感謝您的回答,我非常感謝 – Bossliaw 2011-06-16 13:03:57