链接属性再总结

本文详细介绍了链接属性,包括`extern int a = 1;`与`extern int a;`的区别,分析了全局变量定义错误放入头文件导致的报错情况,以及解释了为什么不能多次定义全局变量。此外,还探讨了强符号和弱符号的链接规则,阐述了链接器如何解析符号并处理多重定义的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接属性再总结

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,一个显式表示,一个隐式表示。

强符号和弱符号

了解一下链接器是怎样解析符号的。

解析符号:将符号的引用与符号的定义关联起来。

强符号:定义一个变量,即声明的同时初始化。例:int a = 1 
弱符号:仅声明变量,不进行初始化赋值。例:int a

链接器解析多重定义的全局符号:
1. 不允许有多个同名的强符号。(发生冲突)
2. 如果有一个强符号和多个弱符号同名,则选择强符号。
3. 如果多个弱符号同名,则从这些弱符号任意选择一个。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值