2011-06-08 124 views
1

我能想象的靜態變量var內部功能func被命名爲喜歡[email protected]全局靜態/非靜態變量如何在c中被破壞?

怎麼樣全局靜態和非靜態變量?

+0

您是否檢查了裝配體? – 2011-06-08 01:45:26

+2

'var @ func'不會是唯一的,除非'func'是外部的......但無論如何,你都離開了。一旦編譯器完成它們,非外部變量和函數就不再具有名稱。 – 2011-06-08 01:48:00

+0

@R ..對不起,我感到困惑。但是靜態變量存儲在哪裏呢?你說這只是在調試符號表中,我對此懷疑很多。我認爲它們應該在用於解析符號的符號表中 – cpuer 2011-06-08 02:52:21

回答

4

編譯器不需要使用內部鏈接來唯一命名事物,如靜態變量和函數。您無法訪問翻譯單元之外的靜態對象,因此鏈接器無需爲其獲取名稱。

具有外部鏈接的全局變量通常不會在其名稱上應用很多變形或修飾,而且通常與應用於函數的變量完全相同。一個領先的下劃線並不罕見。

+0

@John Calsbeek,靜態變量也在符號表中恢復,所以你必須有一個名字。 – cpuer 2011-06-08 01:37:28

+0

誰的符號表?彙編的? – 2011-06-08 01:41:50

+3

@cpuer:只有調試符號表。它們不存儲在用於解析符號的符號表中,因爲它們沒有任何名稱,所以它們沒有被破壞。 – 2011-06-08 01:46:35

2

此外,由於這裏給出的信息至少不完整。大多數編譯器會爲靜態變量創建「本地」符號,是的,因爲函數範圍中靜態變量的命名不是唯一的,所以它們必須對名稱進行修改。 gcc,例如,通過給名稱附加一個點和一個唯一編號來實現這一點。由於該點不是任何有效標識符的一部分,因此可以確保沒有名稱衝突。

當編譯器支持標識符中的通用字符時,事情變得模糊。根據環境的不同,編譯器必須修改這些標識符,因爲例如加載器可能不支持符號表中的這些字符。

icc選擇類似於用_uXXXX替換這樣的字符,其中XXXX是字符的十六進制表示。在這種情況下(icc)會導致兩個微妙的編譯器錯誤。首先,這種修改使用了允許用戶使用的有效標識符,因此它們可能會使用來自同一編譯單元甚至其他單元的標識符衝突全局符號。其次,icc甚至混合了自己的內部命名,並且只保留一個靜態變量的空間,並且如果它們例如也被聲明爲volatile,則完全暴露無遺。