min*_*ess 5 c storage duration linkage
考虑以下示例:
static int a;
extern int a; //OK -- what linkage does the a have now?
static int a;
int a; //ERROR
extern int a;
static int a; //ERROR
int a;
static int a; //ERROR
extern int a;
int a; //OK as expected
int a;
extern int a; //OK as expected
Run Code Online (Sandbox Code Playgroud)
为什么在第一个示例中可以,但在第二个示例中不行?
就文件范围变量(全局范围)而言,当没有指定关键字时,这些变量具有外部链接和静态持续时间。
谢谢
AFAIK,函数的链接和存储持续时间有点不同。
编辑:我试过使用 gcc 4.5.2 -Wall -pedantic --std=c99 进行编译
更多关于:http : //c-faq.com/decl/static.jd.html你可以看到第一个例子也可以在那里工作,但第二个例子没有。但是,我看不出是什么让它们如此不同。
您的第一个问题的答案可以在 C 标准的 §6.2.2 中找到:
4 对于在该标识符
extern
的先前声明可见的范围内使用存储类说明符声明的标识符,如果先前声明指定了内部或外部链接,则在后面的声明中标识符的链接与链接相同在事先声明中指定。如果没有可见的先前声明,或者如果先前声明没有指定链接,则标识符具有外部链接。
所以链接a
是内部的。
对于你的第二个问题,紧接下一段的第二句恰如其分:
5 如果函数的标识符声明没有存储类说明符,则其链接的确定与使用存储类说明符声明的完全相同
extern
。如果对象的标识符声明具有文件范围且没有存储类说明符,则其链接是外部的。
因为a
是一个对象,而不是一个函数,所以int a;
没有存储类说明符的声明给出了a
外部链接。同一部分然后有这样的说法:
7 如果在翻译单元内,相同的标识符出现在内部和外部链接中,则行为未定义。
由于在您的第二个示例a
中同时出现内部和外部链接,因此触发了此段落。未定义行为的一种(特别有用的)表现是您的编译器产生的错误。
你所有的例子都可以通过这些规则来理解:
int a;
总是a
用外部链接声明;static int a;
总是a
用内部链接声明;extern int a;
声明a
它已经拥有的任何链接,如果没有,则使用外部链接;a
具有不同链接的同一范围内的两个声明会产生未定义的行为。