通过一个简单的例子介绍一下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()退出时执行。
下面给出一个简单的例子:
 #include <stdio.h>

 void __attribute__((constructor)) funcBeforeMain()
{
printf("%s...\n", __FUNCTION__);
} void __attribute__((destructor)) funcAfterMain()
{
printf("%s...\n", __FUNCTION__);
} int main()
{
printf("main...\n");
return ;
}

运行结果:

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

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

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

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

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

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

       __CTOR_LIST__ = .;
LONG((__CTOR_END__ - __CTOR_LIST__) / - )
*(.ctors)
LONG()
__CTOR_END__ = .;
__DTOR_LIST__ = .;
LONG((__DTOR_END__ - __DTOR_LIST__) / - )
*(.dtors)
LONG()
__DTOR_END__ = .;

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

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

参考文档:

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

GCC的__attribute__ ((constructor))和__attribute__ ((destructor))的更多相关文章

  1. gcc中__attribute__ ((constructor(101)))做成.a库成功链接

    1.cpp:------------------------------------------------ #include int test() __attribute__ ((construct ...

  2. __attribute__ ((default)) 和 __attribute__ ((hidden))

    制作一个共享库 /* a.h */ int func(); /* a.c */ #include <stdio.h> #include "a.h" int func() ...

  3. 构造函数constructor 与析构函数destructor(一)

    构造函数定义:构造函数c++中在创建对象时自动调用,用来初始化对象的特殊函数. (1)构造函数的名字必须与类的名字相同,不能有返回值,哪怕是void 也不行. (2)通常情况下构造函数应声明为公有函数 ...

  4. 构造函数constructor 与析构函数destructor(五)

    我们知道当调用默认拷贝构造函数时,一个对象对另一个对象初始化时,这时的赋值时逐成员赋值.这就是浅拷贝,当成员变量有指针时,浅拷贝就会在析构函数那里出现问题.例如下面的例子: //test.h #ifn ...

  5. 构造函数constructor 与析构函数destructor(四)

    拷贝构造函数:拷贝构造函数就是在用一个类对象来创建另外一个类对象时被调用的构造函数,如果我们没有显示的提供拷贝构造函数,编译器会隐式的提供一个默认拷贝构造函数. 拷贝构造函数的定义是X(const X ...

  6. 构造函数constructor 与析构函数destructor(三)

    (1)构造函数初始化列表: 1 class Test{ 2 int i; 3 public: 4 Test(int vi):i(vi){}//这里的从冒号开始,到右大括号结束,这一段是构造函数初始化列 ...

  7. 构造函数constructor 与析构函数destructor(二)

    (1)转换构造函数 转换构造函数的定义:转换构造函数就是把普通的内置类型转换成类类型的构造函数,这种构造函数只有一个参数.只含有一个参数的构造函数,可以作为两种构造函数,一种是普通构造函数用于初始化对 ...

  8. iOS宏和__attribute__

    本文目录 iOS宏的经典用法 Apple的习惯 __attribute__ iOS宏的经典用法 1.常量宏.表达式宏 #define kTabBarH (49.0f) #define kScreenH ...

  9. __attribute__

    转来的: http://www.cnblogs.com/astwish/p/3460618.html __attribute__ 你知多少? GNU C 的一大特色就是__attribute__ 机制 ...

随机推荐

  1. mac电脑使用技巧和相关快捷键

    移动与选取 1. 光标移动 刚从 Windows 转过来的时候可能会发现,Mac 上没有 Home 和 End 键.其实,直接这样就好了: Cmd + ←  移至行首 (Home)Cmd + →  移 ...

  2. mysql约束以及数据库的修改

    一.约束 1.约束保证数据完整性和一致性. 2.约束分为表级约束和列级约束. (1)表级约束(约束针对于两个或两个以上的字段使用) (2)列级约束(针对于一个字段使用) 3.约束类型有: (1)NOT ...

  3. python11 装饰器与闭包

    一.装饰器定义 本质:一种函数,为其他函数增加新功能 原则: 1.不修改被修饰函数的源代码 2.不修改被修饰函数的调用方式 需要技能:装饰器=高阶函数+函数嵌套+闭包 二.高阶函数 定义:函数接收的参 ...

  4. Eclipse 新建 Maven web 项目

    File --> New --> Maven Project --> 选择存放路径 --> 选择骨架 --> 输入Maven坐标 --> 初步成型,下面还要配置 1 ...

  5. 分布式一致性的基石---Paxos算法(1)

    分布式一致性的基石---Paxos算法(1) Paxos算法是由微软的工程师Lamport提出,Lamport依靠Paxos算法获得图灵奖: Paxos算法旨在解决相互信任的分布式系统中,多个节点能快 ...

  6. AX_Query

    static void example(Args _args)  {      SysQueryRun     queryRun = new SysQueryRun(querystr(KTL_Sale ...

  7. SHELL脚本学习-自动生成AWR报告

    自动生成AWR报告,每个小时生成一次. #编辑脚本:vim awr_auto.sh #oracle用户下执行 #!/bin/bash # 每个小时执行一次,自动生成AWR报告 source ~/.ba ...

  8. kenlm的使用

    1.训练模型 install_path/bin/lmplz -o -S % -T /temp <text >text.arpa -o  表示n_gram 中的n(必选) -S  内存使用( ...

  9. 静态链接库与动态链接库----C/C++

    http://blog.csdn.net/freestyle4568world/article/details/49817799

  10. oracle分区表的使用和查询

    本文参考了 https://blog.csdn.net/mzglzzc/article/details/46300645 一  创建和使用分区表 1.范围分区(RANGE)范围分区将数据基于范围映射到 ...