2011-09-20 77 views
3

让我们说我的项目中只有一个名为test.c的文件;如果我没有定义“TRUE”,下面的代码不能编译。我只是想了解这种行为。请在这方面提出一些看法。static extern vs extern static

#ifdef TRUE 
static int a; 
extern int a; 
#else 
extern int a; 
static int a; 
#endif 

int main (void) 
{ 
    a =10; 
    printf("%d", a); 
    return 0; 
} 
+9

当事情不能编译,它的发布错误消息是一个好主意。 – Jon

+0

在GCC上,当'TRUE'被定义时它编译得很好,但如果不是的话则不会。 –

+0

我猜想GCC可能在解析'static'后忽略'extern'声明。 –

回答

6

当未定义TRUE,第一声明(extern)表示a有外部链接,(ISO/IEC 9899:1999,6.2.2,第4段,没有事先声明)。第二个声明(static)声明a有内部联系(第3段)。一个标识符不能同时具有内部和外部联系(第7段)。

TRUE定义的情况下,第二个声明中的extern没有影响,因为之前有一个声明a的内部链接声明(第4段)。

请参阅draft of ISO/IEC 9899:1999

3

我不知道你想在这里做什么,而是你重新声明a既是一个静态和外部变量,在不同的顺序。

当应用于变量时,static允许全局变量仅在该文件中可见。 extern声明一个外部变量,在别处定义。因此,例如,如果最初在一个单独的文件中定义了a作为extern,并且将其声明为static(如果它只应该在该文件本身内可见),那么它将声明为extern。

下面是错误:

test.c:8:12: error: static declaration of ‘a’ follows non-static declaration 
test.c:7:12: note: previous declaration of ‘a’ was here 

您声明a为外部变量(在不同的文件中定义),但随后重新声明为静态的,只有这个文件中可见。

在这种情况下,我会检查那些存储类(extern,static等)的含义,然后决定如何声明变量。

0

当你定义TRUE,您声明a为外部,这意味着a定义是在一些其他的文件,但是编译器无法找到它,所以它不能编译文件。

另外,我觉得你写错了,这个文件应该编译的时候你没有定义 TRUE。

0

这里的问题是,当你没有使用#define TRUE定义TRUE时,编译器在执行#else部分时首先遇到变量'a'的'extern'声明并开始预测其在某个外部作用域中的声明。记住extern的内存是在程序开始执行时分配的。因此,它在此之后找到另一个静态定义,并尝试在编译时分配内存,但由于不确定extern声明是否存在冲突。所以会产生一个错误作为重复的声明。

但是,当定义true并执行第一个条件时,'a'在extern声明之前是静态的,并在编译时分配内存权,因此进一步的定义不会冲突。我希望这有帮助。:)

阅读此链接http://www.tenouk.com/ModuleZ.html