链接属性再总结

链接属性再总结

1.extern int a = 1;和extern int a;的区别

代码块之外

extern int a = 1;
int a = 1;

上述代码没有任何区别,代码快之外,在缺省关键字extern情况下,变量a的默认链接属性就是external,extern int a = 3;表示在显式地声明这个变量的链接属性时external

上面的代码会在静态内存中分配空间

extern int a;
int a;  //如果其他文件定义并初始化,缺省extern和加上extern等价
        //当然,如果其他文件没有定义,这里表示定义,默认初始化值为0

这句话仅仅是声明,并不会分配内存空间,这句话告诉编译器,这个变量a在另一个文件中,编译后,链接时,到其他文件中寻找变量a(外部链接属性)

2.报错分析

A.将全局变量的定义错误的放到头文件中

main.o main.c:(.data+0x0): multiple definition of `a'
test.o test.c:(.data+0x0): first defined here

源文件1:

/*main.c*/
#include <stdio.h>
#include "test.h"
int main(void){
    printf("%d",a);
    return 0;
}

源文件2:

/*test.c*/
#include "test.h"
void test(){
    a++;
}

头文件:

#ifndef TEST_H
#define TEST_H

int a = 3;

#endif

可能这个例子很蠢,但是,就是想说不要把全局变量的定义放到头文件中,这里只是一个头文件,而且还没有多重包含,如果头文件很多,而且多重包含,那错误会很难找。

分析:

问:头文件的编辑格式采用了条件编译,为什么会报错多次定义了a?
答:的每个文件都是单独编译,所以对于main.o和test.o两个文件,都有自己的变量;报错发生在链接阶段,因为缺省情况下,全局变量的定义默认为外部链接属性(多个文件使用一个实体),然而,却有两个实体,所以报错了。

总结——不要将全局变量定义放到头文件中(非要放,加上static)

全局变量加上static表示将链接属性变成内部链接属性,这样,每一个文件中的变量,在自己的文件中表示一个实体。

B.没有实体——没有定义

undefined reference to `a'

分析:

这条报错的唯一原因就是没有定义,要么就是变量名写错了,或者就是只有声明,没有定义。

/*main.c*/
#include <stdio.h>
extern int a;
int main(void){
    printf("%d",a);
    return 0;
}

extern int a;只是声明,告诉编译器这个变量在别的文件,但是,链接的时候,并没有找到这个变量。

C.可以多次声明,但不能多次定义

最简单的例子:函数原型,多次声明同一个函数原型并不会报错。

int f();
int f();

这样并不会报错。

同样

extern int a;
extern int a;

也不会报错。

在说明一下:

extern int f();
int f();

这两个原型等价,链接属性都是external,一个显式表示,一个隐式表示。

猜你喜欢

转载自blog.csdn.net/qq2071114140/article/details/89204530