啊
void addr(void);
Run Code Online (Sandbox Code Playgroud)
AC
#include <stdio.h>
int x;
void addr(void) {
printf("a:x=%p\n", &x);
}
Run Code Online (Sandbox Code Playgroud)
公元前
#include <stdio.h>
#include "a.h"
char x;
int main(void) {
addr(); /* a:x=0x601044 */
printf("b:x=%p\n", &x); /* b:x=0x601044 */
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么编译器或链接器不抱怨具有不同类型和相同标识符(x)的两个extern声明,并且它们是静默链接在一起的?
环境:
$ gcc --version
gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
$ gcc -o test -Wall -std=c11 a.c b.c
Run Code Online (Sandbox Code Playgroud)
int x;in a.c和char x;in b.c中的声明只是标识符的暂定定义x.
C11标准草案N1570规定:
6.9.2外部对象定义
...
2具有文件范围而没有初始化程序且没有存储类说明符或存储类说明符为静态的对象的标识符声明构成暂定定义.
相反,如果您x在两个文件中初始化(类似于int x = 2;in a.c和char x = '1';in b.c,它们将成为"完整"定义,然后您将从链接器中获得多个定义错误.
就像是:
Error LNK1169 one or more multiply defined symbols found
Error LNK2005 x already defined in a.obj
Run Code Online (Sandbox Code Playgroud)