目录

  • 一、先说结论
  • 二、当attribute修饰符号的引用/声明时——不做链接
    • 2.1、变量声明
    • 2.2、函数声明
  • 三、链接.o文件
    • 3.1、函数
      • 3.1.1、多个强符号
      • 3.1.2、一个强符号多个弱符号
      • 3.1.3、多个弱符号
    • 3.2、变量
      • 3.2.1、多个强符号
      • 3.2.2、一个强符号多个弱符号
        • 3.2.2.1、弱符号全部在.data中
        • 3.2.2.2、弱符号部分在.data中,部分在.common中
        • 3.2.2.3、弱符号全部在.common中
      • 3.2.3、多个弱符号
        • 3.2.3.1、弱符号全部在.data中
        • 3.2.3.2、弱符号部分在.data中,部分在.common中
        • 3.2.3.3、弱符号全部在.common中
  • 四、链接库文件
    • 4.1、函数
      • 4.1.1、多个强符号
      • 4.1.2、多个强符号多个弱符号
      • 4.1.3、多个弱符号
      • 4.1.4、小结
    • 4.2、变量
      • 4.2.1、多个强符号
      • 4.2.2、一个强符号多个弱符号
        • 4.2.2.1、弱符号全部在.data中
        • 4.2.2.2、弱符号部分在.data中,部分在.common中
        • 4.2.2.3、弱符号全部在.common中
      • 4.2.3、多个弱符号
        • 4.2.3.1、弱符号全部在.data中
        • 4.2.3.2、弱符号部分在.data中,部分在.common中
        • 4.2.3.3、弱符号全部在.common中
  • 五、强弱符号存在,如果避免错误?
  • 六、说明:COMMON 节

Ubuntu版本:12.04
Linux版本:3.5.0
GCC版本:4.6.3

一、先说结论

在C语言中,强符号:

  • 非静态函数
  • 初始化的非静态全局变量(包括显示初始化为0)

弱符号:

  • 未初始化的非静态全局变量
  • GCC的 __attribute__((weak)) 来定义任何一个强符号

强弱符号是针对于定义来说的,不是针对符号的引用。

__attribute__((weak)) 修饰引用时,可以不用链接,依据符号在实际语句中的作用将其替换成0,编译时还是需要做语法正确性检查。

虽然允许多个相同弱符号同时存在,但是这里的存在只是在同一个项目中不同的文件中相同弱符号允许存在,同一个文件中不允许相同的弱符号同时存在。

======================================================================================================
下面对上述内容进行举例说明,如有理解错误,望不吝指正。

二、当attribute修饰符号的引用/声明时——不做链接

__attribute__((weak)) 修饰强符号(定义好的)的时候,可以将强符号变成弱符号,当__attribute__((weak)) 修饰引用/声明时,可以避过链接,依据符号在实际语句中的作用将其替换成0,编译时候语法正确性检查还是需要的

什么是定义?
变量定义、函数定义认为是定义,例如:int a; void func(void){}

什么是引用/声明?
外部变量、函数原型认为是引用/声明,例如:extern int a; void func(void)

2.1、变量声明

阶段一、

/* test.c文件 */
#include <stdio.h>int main(int argc, const char *argv[])
{a++;return 0;
}

编译:gcc test.c

(错误原因:‘a’ 未申报 )

阶段二、

/* test.c文件 */
#include <stdio.h>
extern int a; //外部变量——声明
int main(int argc, const char *argv[])
{a++;return 0;
}

编译:gcc test.c

(错误原因:对‘a’的未定义引用 )

阶段三、

/* test.c文件 */
#include <stdio.h>
extern int __attribute__((weak)) a; //外部变量——声明
int main(int argc, const char *argv[])
{a++;return 0;
}

编译:gcc test.c
编译结果:通过,不做链接。
运行结果:Segmentation fault (core dumped),因为链接器会将此未定义的weak symbol赋值为0,所以出现段错误。

2.2、函数声明

__attribute__((weak)) 修饰函数声明,同样也是避过链接,将对应的符号设置成0,依然在编译时会做语法正确性检查。

gcc编译器中函数不用进行原型声明的解释
gcc编译器如果没有写函数原型,编译器会把函数调用同时认为是声明,默认返回值为int。
如果写了函数原型,那么以函数原型去检查函数调用是否符合规定。
变量如果是外部引用的也必须说明,不然编译报错。
安全起见还是写一下函数原型!!!

参考:关于gcc编译器中函数不用进行原型声明的解释

【C语言】强符号与弱符号相关推荐

  1. 【嵌入式】C语言高级编程-强符号和弱符号(09)

    00. 目录 文章目录 00. 目录 01. weak属性 02. 变量强符号和弱符号 03. 函数强符号和弱符号 04. 弱符号的作用 05. alias属性 06. 附录 01. weak属性 G ...

  2. 新手小心:c语言的强符号和弱符号

    声明:下面的实例全部在linux下尝试,window下未尝试.有兴趣者可以试一下.文章针c初学者. c语言的强符号和弱符号是c初学者经常容易犯错的地方.而且很多时候,特别是多人配合开发的程序,它引起的 ...

  3. C语言 强符号与弱符号

    对于C语言来说,编译器默认函数和初始化的全局变量为强符号,未初始化的全局变量为弱符号(C++并没有将未初始化的全局符号视为弱符号).可以通过GCC的"__ attribute ((weak) ...

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

    注意,强符号和弱符号都是针对定义来说的,不是针对符号的引用. 一.概述 在C语言中,函数和初始化的全局变量(包括显示初始化为0)是强符号,未初始化的全局变量是弱符号. 对于它们,下列三条规则使用: ① ...

  5. c语言弱符号与函数指针,浅谈C语言中的强符号、弱符号、强引用和弱引用【转】...

    首先我表示很悲剧,在看<程序员的自我修养--链接.装载与库>之前我竟不知道C有强符号.弱符号.强引用和弱引用.在看到3.5.5节弱符号和强符号时,我感觉有些困惑,所以写下此篇,希望能和同样 ...

  6. C语言中的强符号与弱符号(关于变量声明与定义的深入讨论)

    看到一篇介绍C语言强符号与弱符号的文章非常好,转载过来加深印象. 原文地址:http://blog.csdn.net/astrotycoon/article/details/8008629 ===== ...

  7. 【C语言】强符号和弱符号

    1.强符号.弱符号定义 编译器在编译源程序时,无论你是变量名.函数名,在它眼里,都是一个符号而已,用来表征一个地址.编译器会将这些符号集中,存放到一个叫符号表的 section 中. 那么对于两个.c ...

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

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

  9. 浅谈一下嵌入式中的强符号和弱符号

    __attribute__  是一个编译器指令,其实是 GNU C 的一种机制,本质是一个编译器的指令,在声明的时候可以提供一些属性,在编译阶段起作用,来做多样化的错误检查和高级优化. 用于在 C.C ...

最新文章

  1. pcs7更改项目计算机名时出错,PCS7 C/S报警问题-工业支持中心-西门子中国
  2. LeetCode 1480 一维数组的动态和
  3. win7输入密码界面背景怎么更改
  4. Flask-SQLAlchemy 对数据库的过滤查询
  5. 会说话的狗狗本电脑版_「电脑知识」硬件狗狗专业电脑硬件检测跑分工具免安装单文件版|电脑硬件|电脑|显卡|狗狗|操作系统...
  6. Jupyter Notebook安装jupyter_contrib_nbextension扩展功能和安装后不显示Nbextensions标签的解决办法
  7. Python基础——continute与break(循环控制)
  8. VS2013 MFC + OpenCV3.0 打开图片
  9. UI基础UIView常见属性及方法
  10. [iOS] HealthKit 睡眠分析
  11. OC中链式编程和函数式编程
  12. 解决: 在类xxx 中找不到 main 方法, 请将 main 方法定义为: public static void main(String[]
  13. jmeter里看java的log,jmeter中java协议请求
  14. about dream
  15. Linux防火墙的关闭
  16. 新手必备pr 2021快速入门教程「十一」PR字幕添加
  17. INS-06101nbsp;IPnbsp;ADRESSnbsp;OFnbsp;LOCALHOST
  18. 一些开源库,提高开发效率
  19. gradient clipping
  20. 关于wifi打印服务器方案和USB共享打印机模块工作原理

热门文章

  1. 【Spring学习】AOP实现日志记录
  2. java抠图人物背景图片_人物抠图换背景两种实用方法!
  3. 单片机中断实验2 EX0
  4. Java中world、PDF、Excel转图片
  5. tf.round(): 四舍六入五取偶
  6. OneDrive - “You‘re already syncing this account.“ 错误的解决方案
  7. 告别单调, 给Unity编辑器换一个皮肤吧
  8. android 辅助功能 模拟点击,Android模拟点击的四种方式
  9. 错误 C4996 inet_addr: Use inet_pton() or InetPton() instead or defin
  10. 净亏损2.9亿元,财务业绩陷入困境后,逸仙电商盈利仍遥遥无期