我们可以使用 extern 在文件中使用变量吗,该变量在基本文件中既定义为静态又全局?
你不能extern
-re定义一个static
变量,但你可以extern
-re声明它。
错:
//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
不会声明具有外部链接的链接标识符:它(重新(声明具有其先前链接(外部或内部(的标识符,除非之前没有此类声明或声明没有链接(非静态局部没有链接(。
6.2.2p4:
对于使用存储类说明符 extern 声明的标识符 该标识符的先前声明可见的范围,31( 如果先前的声明指定了内部或外部链接,则 后面声明中标识符的链接与 先前声明中指定的联系。如果没有事先声明 可见,或者如果先前的声明指定没有链接,则 标识符具有外部链接。
不过,我不会尝试用复杂的阴影来推动这种行为,因为 gcc 和 clang 都不像内部静态的外部重新声明,如果您在全局静态和最内层的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=%dn", x); //42
}
仅由 clang 接受(由于链接冲突,技术上 UB (
#include <stdio.h>
static int x = 42;
extern int x;
int main()
{
int x = 1000;
printf("x=%dn", 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=%dn", 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=%dn", x); //1000?
}