linux 弱符号,弱符号__attribute__((weak))

本文详细解释了弱符号的概念及其在链接过程中的作用。介绍了如何通过__attribute__((weak))将符号声明为弱符号,以及链接器如何处理强符号和弱符号。并通过示例说明了在不同情况下弱符号的行为。

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

弱符号是什么?

弱符号:

若两个或两个以上全局符号(函数或变量名)名字一样,而其中之一声明为weak symbol(弱符号),则这些全局符号不会引发重定义错误。链接器会忽略弱符号,去使用普通的全局符号来解析所有对这些符号的引用,但当普通的全局符号不可用时,链接器会使用弱符号。当有函数或变量名可能被用户覆盖时,该函数或变量名可以声明为一个弱符号。弱符号也称为weak alias(弱别名)。

attribute((weak))的作用

情况是这样的,碰到一个棘手的问题:我们不确定外部模块是否提供一个函数func,但是我们不得不用这个函数,即自己模块的代码必须用到func函数:

extern int func(void);

...................

int a = func();

if( a > .....)

{

..........

}

............

我们不知道func函数是否被定义了;

这会导致2个结果:

1:外部存在这个函数func,并且EXPORT_SYMBOL(func),那么在我自己的模块使用这个函数func,正确。

2:外部其实不存在这个函数,那么我们使用func,程序直接崩溃。

所以这个时候,__attribute__((weak)) 派上了用场。

在自己的模块中定义:

int __attribute__((weak)) func(......)

{

return 0;

}

将本模块的func转成弱符号类型,如果遇到强符号类型(即外部模块定义了func),那么我们在本模块执行的func将会是外部模块定义的func。

如果外部模块没有定义,那么,将会调用这个弱符号,也就是在本地定义的func,直接返回了一个1(返回值视具体情况而定)

相当于增加了一个默认函数。

原理:连接器发现同时存在弱符号和强符号,有限选择强符号,如果发现不存在强符号,只存在弱符号,则选择弱符号。如果都不存在:静态链接,恭喜,编译时报错,动态链接:对不起,系统无法启动。

weak属性只会在静态库(.o .a )中生效,动态库(.so)中不会生效。

强符号和弱符号的例子

举个例子:

strong.c //生成 libstrong.so

#include

void real_func()

{

printf("int real func\n");

}

#include

void real_func() __attribute__((weak));

void real_func()

{

printf("fake func\n");

}

如果

gcc main.c -lstrong -lweak

那么输出结果"real func"。

main.c

#include

extern void real_func();

void main()

{

real_func();

}

如果

gcc main.c -lweak -lstrong

那么输出结果为"fake func"。

可见,对于动态库,weak属性毫无作用,且main中调用哪个real_func(),取决于顺序。

如果将strong.c 和 weak.c编译成.a或者.o

gcc main.c strong.o weak.o

或者

gcc main.c strong.o weak.o

那么输出结果都是"real func"。

所以,如果在so中使用weak属性,那么任何不符合预期的情况,都是可能出现的。

C语言中的弱符号(weak)用法及实例

一 符号概念: 在C语言中,有强符号和弱符号,符号简单来说就是函数.变量的名字,对于全局(非局部.非static)的函数和变量,能不能重名是有一定规矩的,强.弱符号就是针对这些全局函数和变量来说的. ...

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

转自:http://blog.youkuaiyun.com/astrotycoon/article/details/8008629 一.概述 在C语言中,函数和初始化的全局变量(包括显示初始化为0)是强符号,未初 ...

GNU C/C++ __attributes__ GCC中的弱符号与强符号

最近在看一些源代码,遇到了一些使用__attribute__修饰函数和变量的属性方面的代码,不是太了解,很是汗颜,再此做个总结:   GCC使用__attribute__关键字来描述函数,变量和数据类 ...

GCC中的弱符号与强符号

GCC中的弱符号与强符号 我们经常在编程中碰到一种情况叫符号重复定义.多个目标文件中含有相同名字全局符号的定义,那么这些目标文件链接的时候将会出现符号重复定义的错误.比如我们在目标文件A和目标文件B都 ...

GCC中的强符号和弱符号及强引用和弱引用

1. 强符号和弱符号 1.1 u-boot和kernel中的__weak指令 u-boot和kernel比较普遍地使用了__weak来定义函数. 在include\linux\compiler-gcc ...

gcc/g++中weak弱符号及alias别名

最近查看linux内核代码时,表现了一些编译器选项如__attribute_((weak)).__attribute__( (alias("target"))),一开始不了解,后来 ...

C++中弱符号(弱引用)的意义及实例

今天读别人代码时看到一个“#pragma weak”,一时没明白,上网研究了一个下午终于稍微了解了一点C.C++中的“弱符号”,下面是我的理解,不正确的地方望大家指正. 本文主要从下面三个方面讲“弱符 ...

关于C语言中的强符号、弱符号、强引用和弱引用的一些陋见,欢迎指正

首先我表示很悲剧,在看之前我竟不知道C有强符号.弱符号.强引用和弱引用.在看到3.5.5节弱符号和强符号时,我感觉有些困惑,所以写下此篇,希望能和同样 ...

浅谈C语言中的强符号、弱符号、强引用和弱引用

摘自http://www.jb51.net/article/56924.htm 浅谈C语言中的强符号.弱符号.强引用和弱引用 投稿:hebedich 字体:[增加 减小] 类型:转载 时间:2014- ...

随机推荐

HDU 4941 Magical Forest(map映射+二分查找)杭电多校训练赛第七场1007

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4941 解题报告:给你一个n*m的矩阵,矩阵的一些方格中有水果,每个水果有一个能量值,现在有三种操作,第 ...

[BZOJ1370][Baltic2003]Gang团伙

[BZOJ1370][Baltic2003]Gang团伙 试题描述 在某城市里住着n个人,任何两个认识的人不是朋友就是敌人,而且满足: 1. 我朋友的朋友是我的朋友: 2. 我敌人的敌人是我的朋友: ...

ExtJs之Ext.form.field.TimePicker DatePicker组合框

ExtJs

java web 学习六(servlet开发2)

一.ServletConfig讲解 1.1.配置Servlet初始化参数 在Servlet的配置文件web.xml中,可以使用一个或多个标签为servlet配置一些 ...

Oracle数据库12560及更改密码为永久

小厂子的程序员还要折腾Oracle维护.这这里简单记录一下Oracle数据库服务器使用时遇到并解决的一些问题. 1. 在Oracle数据库服务器上(即安装Oracle数据库端的机器上),可以使用命令 ...

论javascript模块化的优缺

如今backbone.emberjs.spinejs.batmanjs 等MVC框架侵袭而来.CommonJS.AMD.NodeJS.RequireJS.SeaJS.curljs等模块化的JavaSc ...

OBS实现直播解决方案【html实现直播】

项目的需要,要整一个视频直播,但又不想在其他平台那种直播室盗链展示,那我就直接用播放器来实现rtmp流媒体服务器推流吧!没废话,走起 1.你要有一个媒体服务器,暂时用[盘古云],这个还好,算是不错的平 ...

WPF使用RoutedCommand自己定义命令

主要代码例如以下所看到的: /// /// 声明并定义命令. /// RoutedCommand ClearCommand = new ...

POJ1269 Intersecting Lines[线段相交 交点]

Intersecting Lines Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 15145   Accepted: 66 ...

Python encode() 方法(转)

转自:http://www.cnblogs.com/wushuaishuai/p/7686290.html 描述 encode() 方法以指定的编码格式编码字符串,默认编码为 'utf-8'. 对应的 ...

<think>好的,用户想了解C/C++中的__attribute__关键字的作用和常见用法。首先,我需要回忆一下自己对这个关键字的理解。__attribute__是GCC的扩展,用于指定变量、函数、类型等的特殊属性,比如优化控制、内存对齐等。用户提供的引用中提到了weak属性和-fvisibility=hidden的配合使用,还有官方文档的链接,这些都需要涵盖进去。 接下来,我应该整理__attribute__的基本作用,比如编译器优化、错误检查、平台适配。然后列出常见的用法,每个用法要有例子和说明。比如aligned属性用来对齐内存,packed取消结构体填充,weak用于符号,section将代码放入指定段,unused处理未使用的变量警告,deprecated标记过时代码,visibility控制符号可见性。 需要注意用户提供的引用内容,特别是关于weak和visibility的部分,要正确引用到对应的标记。比如引用[1]提到weak属性,引用[3]提到visibility和hidden参数的关系,这些都要在相关部分注明来源。 还要确保回答结构清晰,分点说明,每个属性用代码示例展示,并解释其作用。同时,生成相关问题时要围绕用户可能感兴趣的扩展点,比如其他编译器是否支持、不同属性的区别、实际应用案例等。 最后检查是否符合用户的要求:使用中文,LaTeX格式正确,引用标识正确放置,相关问题合理。确保没有遗漏任何用户提到的引用内容,并且语法和示例代码正确无误。</think>### C/C++中`__attribute__`关键字的作用与常见用法 `__attribute__`是GNU编译器(如GCC)的扩展关键字,用于在声明时指定变量、函数或类型的特殊属性。它通过语法`__attribute__((属性名))`实现,能够控制编译器行为,例如优化、内存对齐或符号可见性。 --- ### 一、核心作用 1. **编译器优化** 指定函数或变量的优化方式,例如强制内联(`inline`)或禁用优化(`optimize`)。 2. **错误检查增强** 如`format`属性可验证格式化字符串与参数是否匹配,减少运行时错误[^2]。 3. **平台适配** 控制符号可见性(如动态库中隐藏符号)或内存对齐方式。 --- ### 二、常见用法及示例 #### 1. 内存对齐控制:`aligned` ```c struct __attribute__((aligned(16))) Data { int x; char y; }; // 结构体按16字节对齐 ``` #### 2. 取消结构体填充:`packed` ```c struct __attribute__((packed)) SensorData { uint8_t id; float value; }; // 禁用结构体字段自动填充 ``` #### 3. 符号定义:`weak` ```c // 若其他文件定义了同名函数,此函数会被覆盖 __attribute__((weak)) void default_handler() { // 默认实现 } ``` 在Linux内核中常用于提供默认实现[^1]。 #### 4. 指定代码段:`section` ```c __attribute__((section(".custom_section"))) int config_data = 0x1234; // 变量被放入自定义段 ``` #### 5. 抑制未使用警告:`unused` ```c int __attribute__((unused)) debug_flag = 1; // 避免编译器警告 ``` #### 6. 标记过时代码:`deprecated` ```c __attribute__((deprecated("改用新API"))) void old_func(); ``` #### 7. 控制符号可见性:`visibility` ```c // 配合编译选项 -fvisibility=hidden 使用 __attribute__((visibility("default"))) void public_api(); // 仅此函数对外可见[^3] ``` --- ### 三、实际应用场景 1. **嵌入式开发**:通过`section`将关键代码放入特定内存区域。 2. **动态库开发**:使用`visibility`隐藏内部符号,提升安全性和加载效率。 3. **跨平台兼容**:利用`aligned`解决不同硬件架构的内存对齐问题。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值