具有相同标识符的不同类型变量链接在一

pho*_*ean 7 c gcc

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)

P.W*_*P.W 6

int x;in a.cchar x;in b.c中的声明只是标识符的暂定定义x.

C11标准草案N1570规定:

6.9.2外部对象定义
...
2具有文件范围而没有初始化程序且没有存储类说明符或存储类说明符为静态的对象的标识符声明构成暂定定义.

相反,如果您x在两个文件中初始化(类似于int x = 2;in a.cchar 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)