前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C语言中的强符号和弱符号

C语言中的强符号和弱符号

作者头像
lexingsen
发布2022-02-24 15:54:05
1.5K0
发布2022-02-24 15:54:05
举报
文章被收录于专栏:乐行僧的博客乐行僧的博客

一、强弱符号

强弱符号针对的是处于同一工程下在不同源文件下定义的全局变量符号,链接器只处理global的符号而不处理local的符号。链接的核心是符号的重定位,在符号引用的地方找到符号定义的地方,包括函数产生的符号和全局变量产生的符号。

强符号:函数和初始化的全局变量所生成的符号。 弱符号:未初始化的全局变量所生成的符号。

很多情况下写出的代码会出现链接的错误,符号重定义,这是因为在不同的源文件中定义了同名的全局变量并且都进行了初始化。

代码语言:javascript
复制
//a.c
int gdata = 10;
//b.c
int gdata = 20;
#include<stdio.h>
int main(){
    printf("gdata = %d\n",gdata);
    return 0;
}
这里写图片描述
这里写图片描述

这是很多新手容易犯的错误,若将a.c或b.c中全局变量gdata只初始化一次,则不会出现链接错误,并且会链接成功。那么新的问题是: (1)出现强符号和弱符号,选择哪一个? (2)若出现多个同名的强符号,最终怎么选择? (3)若出现多个同名的弱符号,最终会怎么选择? 显然需要这样的一套规则来约束这些可能存在的问题。

二、强弱符号的使用规则

(1)如果出现多个强符号,最终会出现链接错误即符号的重定义。 (2)如果出现强符号和弱符号,编译器最终会选择强符号。 (3)如果出现多个同名弱符号,编译器最终会选择内存占用量最大的那个符号。

一个有趣的小例子再看强弱符号:

代码语言:javascript
复制
//a.c
int x;
void func(){
    x = 20;
}
//b.c
#include<stdio.h>
short x = 10;
short y = 10;
extern void func();
int main(){
    func();
    printf("x = %d,y = %d\n",x,y);
    return 0;
}
//试问输出的x和y分别是多少,大家可以自己先想一下,看看自己的答案。

执行结果:

这里写图片描述
这里写图片描述

和大家心中的答案是否一致呢? 有很多人会有疑问,为什么y输出的不是10,而是0呢? 源文件是独立进行编译的

代码语言:javascript
复制
//a.c
int x;//弱符号
void func(){
    x = 20; //往x的内存上写20,写4个字节   编译阶段就完成的
}
//b.c
#include<stdio.h>
short x = 10;//强符号   14 00 00 00最终将y覆盖为0
short y = 10;
extern void func();
int main(){
    func();//链接的完成选择强符号
    printf("x = %d,y = %d\n",x,y);
    return 0;
}

在 gcc中,可以通过__attribute__((weak))来强制定义任何一个符号为弱符号。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档