2010-01-29 47 views
6

我想了解C99中的存儲類說明符的確切行爲,有些GCC行爲似乎不遵循規範,除非我誤解了規範。從6.2.2(2):C中的鏈接:GCC是否遵循C99規範,或者我不理解規範?

內的一個翻譯單元,標識符的每個聲明與內部聯動表示相同對象或功能。

然而,我與以下程序測試GCC(PowerPC的蘋果darwin9-GCC-4.2.1):

#include <stdio.h> 
static int f() { 
    static int x = 0; 
    return x++; 
} 
static int g() { 
    static int x = 0; 
    return x++; 
} 
int main(int argc, char *argv[]) { 
    printf("g() = %i\n", g()); 
    printf("g() = %i\n", g()); 
    printf("f() = %i\n", f()); 
    printf("f() = %i\n", f()); 
    return 0; 
} 

-std=c99編譯,它打印出以下內容:

g() = 0 
g() = 1 
f() = 0 
f() = 1 

如果我正確理解規格,應該打印:

g() = 0 
g() = 1 
f() = 2 
f() = 3 

我明白爲什麼海灣合作委員會會偏離這裏的規範,我只是想知道這個行爲是否有更深的解釋。

回答

9

下一段,6.2.2/3,是很重要的:

如果對象或功能的文件範圍標識符的聲明包含存儲類說明靜態的,標識符具有內部聯繫。

(注意強調的文件範圍標識符)。

你的靜態變量x沒有文件範圍,它們有塊範圍。

+0

換句話說,每個x都是聲明它的函數的局部。 – 2010-01-29 03:11:30

+0

謝謝。很容易遺漏規範中的單詞。 – 2010-01-29 03:19:55

+2

@Dietrich:是的。事實上,這很容易,我錯過了更相關和重要的部分,作爲答案張貼。 – 2010-01-29 04:06:50

10

在6.2.2(6),它說:

以下標識符沒有起重:[...]塊範圍中聲明 標識符的對象,而不存儲類說明的extern 。

靜態變量是對象的塊範圍標識符,它們未聲明爲extern。因此他們沒有聯繫,特別是沒有內部聯繫。

+2

+1;這比我引用的段落更有意義。 – 2010-01-29 03:19:08