通过一个简单的例子介绍一下gcc的__attribute__ ((constructor))属性的作用。gcc允许为函数设置__attribute__ ((constructor))和__attribute__ ((destructor))两种属性,顾名思义,就是将被修饰的函数作为构造函数或析构函数。程序员可以通过类似下面的方式为函数设置这些属性:

void funcBeforeMain() __attribute__ ((constructor));

void funcAfterMain() __attribute__ ((destructor));

也可以放在函数名之前:
void __attribute__ ((constructor)) funcBeforeMain();

void __attribute__ ((destructor)) funcAfterMain();

带有(constructor)属性的函数将在main()函数之前被执行,而带有(destructor)属性的函数将在main()退出时执行。
下面给出一个简单的例子:

 1 #include <stdio.h>
 2
 3 void __attribute__((constructor)) funcBeforeMain()
 4 {
 5     printf("%s...\n", __FUNCTION__);
 6 }
 7
 8 void __attribute__((destructor)) funcAfterMain()
 9 {
10     printf("%s...\n", __FUNCTION__);
11 }
12
13 int main()
14 {
15     printf("main...\n");
16     return 0;
17 }

View Code

运行结果:

funcBeforeMain...
main...
funcAfterMain...

  为什么有这么神奇的函数呢?它是怎么实现的呢?

  通过翻看GNU的link文档,我找到了答案:

在GNU link中,也就是你的系统中的XX.S文件,找到了详细的答案,

当使用a.out文件来链接程序时,链接器使用一个与众不同的关键字construct 来支持C++里面的全局constructors 和 destructors,当链接对象不支持任意剖分时,链接器可以通过名字来自动识别构造器和解析器。

link文件中的构造器格式如下:

 1       __CTOR_LIST__ = .;
 2       LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
 3       *(.ctors)
 4       LONG(0)
 5       __CTOR_END__ = .;
 6       __DTOR_LIST__ = .;
 7       LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
 8       *(.dtors)
 9       LONG(0)
10       __DTOR_END__ = .;

View Code

符号__CTOR_LIST__标志者全局构造器的开始,符号__DTOR_LIST标志着构造器的结束。列表中的第一个关键字代表条目的个数,后面紧跟者是构造器和解析器的地址。最后是一个零字符。编译器必须排队去执行这些代码。

GNU编译器通常通过一个子程序__main函数前面调用constructor,__main在被调用时会自动的插入到main函数的起始代码中。同样的是,GNU通过运行atexit来调用destructors,或者是通过函数exit来直接调用。

参考文档:

1 https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/4/html/Using_ld_the_GNU_Linker/sections.html

转载于:https://www.cnblogs.com/dylancao/p/9293447.html

GCC的__attribute__ ((constructor))和__attribute__ ((destructor))相关推荐

  1. 编译 / __attribute__(constructor)和__attribute__(destructor)

    一.前言 最近看代码,看到一个函数前面用 __attribute__((constructor)) 修饰,搜了整个程序,没发现哪个地方调用这个函数.如下: __attribute__((constru ...

  2. OC中的 __attribute__中关于__attribute__((cleanup))的研究

    首先__attribute__用于向编译器描述特殊的标识.检查或优化的,等等 而__attribute__((cleanup(...)))是其中的一中用法,为什么介绍这个呢?因为这函数很有趣..... ...

  3. __attribute__ 用法

    转自:http://www.cnblogs.com/astwish/p/3460618.html GNU C 的一大特色就是__attribute__ 机制.__attribute__ 可以设置函数属 ...

  4. __attribute__概述

    __attribute__ 关键字允许指定变量.类型和函数的属性 该关键字的格式如下所示 __attribute__((attribute1, attribute2, ...)) __attribut ...

  5. 在main函数前后执行的函数之 C语言

    在gcc中,可以使用attribute关键字,声明constructor和destructor,来指定了函数在main之前或之后运行,代码如下: 1 #include <stdio.h> ...

  6. 在linux上实现DllMain + 共享库创建方法

    DllMain可以在dll加载到进程.线程时调用,可以做些初始化.清理的工作 但在linux上没有专门的函数,可以使用gcc扩张属性__attribute__((constructor)) and _ ...

  7. __CTOR_LIST__和__DTOR_LIST__解释

    本文译至: http://gcc.gnu.org/onlinedocs/gccint/Initialization.html 如我们所知,在GCC通过给代码追加__attribute__((const ...

  8. linux 无法加载动态库,51CTO博客-专业IT技术博客创作平台-技术成就梦想

    比较懒,而且时间也不早了,就贴上英文,以后有机会在翻译吧. DLOPEN(3)     Linux Programmer's Manual  DLOPEN(3) NAME dladdr, dlclos ...

  9. linux动态库注册函数,linux下加载动态库函数

    比较懒,而且时间也不早了,就贴上英文,以后有机会在翻译吧. DLOPEN(3)     Linux Programmer's Manual  DLOPEN(3) NAME dladdr, dlclos ...

最新文章

  1. AngulerJS学习(五)按需动态载入文件
  2. 《Cortex-M0权威指南》之体系结构---异常和中断
  3. RocketMQ简介
  4. Delphi之virtual,dynamic,abstract
  5. java按钮随机移动_java – 使按钮移动触摸我们触摸的确切位置
  6. d soft php package,让程序飞起来之 Laravel OPcache Package
  7. .Net Discovery系列之三 深入理解.Net垃圾收集机制(上)
  8. 组态王中时间存access怎么存_组态王如何实现实时显示数据并且记录到Access数据库中?...
  9. Phobos勒索病毒完整处理过程
  10. 用Java实现Md5加密工具类
  11. 《生活中的魔法数学》读后感
  12. 微博相册下载助手v7.2 微博图片批量下载神器
  13. 基建狂魔谷歌,如何把数据中心“武装到牙齿”
  14. ASPX一句话及一句话客户端
  15. 不给移动一分钱!10个免费发短信的国外站点
  16. 如何快速生成gif动图表情包?教你制作gif表情包图片
  17. Android 超简单音乐播放器(九)搜索网络歌曲,获得热门榜单(GridView)(易源api的使用)(JSON的解析)(刷新)
  18. 计算机应用小数的转换,电脑计算器进位制换算怎么不能输入小数
  19. 淘宝新开店铺没有生意不会推广的苦衷与心得
  20. matlab 不规则 griddata,MATLAB 不规则随机数据点,画三维曲面图形,griddata, meshgrid...

热门文章

  1. java泛型范围_Java泛型范围
  2. 可用子网数要不要减2_子网数、主机数与子网掩码的关系
  3. python list中分段_python将list中的元素拼接为一个str
  4. 2017计算机绘图试题及答案,2017年度__电大(精编新版)计算机绘图期末复习试题及答案参考小抄.doc...
  5. 了解SQL Server SELECT INTO语句
  6. Python字符串转换为小写字母– str.lower()
  7. Java Hello World程序
  8. Java架构师具备的特点有哪些?
  9. 02C++namespace命名空间
  10. 世人都晓AI好 AI芯片知多少?