我们可以在使用 extern 的文件中使用一个变量,该变量在基本文件中既定义为静态又定义为全局?
问问题
70 次
1 回答
2
你不能extern
-redefine 一个static
变量,尽管你可以extern
-redeclare 它。
错误的:
//filescope
static int x = 42;
extern int x = 43; //WRONG
正确的:
//filescope
static int x = 42;
extern int x; //redeclares the previous STATIC x (no linkage)
extern
不使用外部链接声明具有链接的标识符:它(重新)使用其先前的链接(外部或内部)声明标识符,除非之前没有这样的声明或声明没有链接(非静态本地有没有链接)。
对于在一个范围内使用存储类说明符 extern 声明的标识符,该标识符的先前声明是可见的,31) 如果先前声明指定内部或外部链接,则后面声明的标识符的链接与先前声明中指定的链接。如果前面的声明不可见,或者前面的声明没有指定链接,则标识符具有外部链接。
不过,我不会尝试用复杂的遮蔽来推动这种行为,因为 gcc 和 clang 都不像内部静态的 extern-redeclarations 并且如果您在全局静态和最内部的重新声明之间有干预自动变量extern
,那么最内部的标识符将有冲突的链接,这会导致按照6.2.2p7的未定义行为(感谢Eric Postpischil指出这一点)。
被 gcc 和 clang 接受:
#include <stdio.h>
static int x = 42;
extern int x;
int main()
{
extern int x;
printf("x=%d\n", x); //42
}
仅由 clang 接受(由于链接冲突,技术上是 UB)
#include <stdio.h>
static int x = 42;
extern int x;
int main()
{
int x = 1000;
printf("x=%d\n", x); //1000
{
extern int x; //conflicting (external) linkage
//=> undefined behavior due to http://port70.net/~nsz/c/c11/n1570.html#6.2.2p7
printf("x=%d\n", x); //42 on clang; compile time error on gcc
}
}
也许奇怪的是不接受:
#include <stdio.h>
static int x = 42;
extern int x;
int main()
{
static int x = 1000;
extern int x;
printf("x=%d\n", x); //1000?
}
于 2020-07-04T13:53:48.230 回答