6

我试图了解 C99 中存储类说明符的确切行为,并且某些 GCC 行为似乎不遵循规范,除非我误解了规范。从 6.2.2 (2) 开始:

在一个翻译单元中,具有内部链接的标识符的每个声明都表示相同的对象或函数。

但是,我使用以下程序测试了 GCC (powerpc-apple-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

我理解为什么 GCC 会偏离这里的规范,我只是想知道这种行为是否有更深层次的解释。

4

2 回答 2

10

在 6.2.2 (6) 中它说:

以下标识符没有链接:[...]一个没有存储类说明符 extern 声明的对象的块范围标识符。

静态变量是对象的块范围标识符,它们没有被声明extern。因此它们没有联系,尤其是没有内部联系。

于 2010-01-29T03:16:41.733 回答
9

下一段 6.2.2/3 很重要:

如果对象或函数的文件范围标识符的声明包含存储类说明符 static,则该标识符具有内部链接。

(注意强调的文件范围标识符)。

您的静态变量x没有文件范围,它们具有块范围。

于 2010-01-29T03:08:05.960 回答