解析在main函数之前调用函数以及对设计的作用详解

 更新时间:2020年4月25日 17:47  点击:1543
前几天为新员工写一个简单的测试框架,可让他们方便的写测试用例并且执行。期间遇到一个问题就是如何让他们增加测试用例而用不影响测试框架的代码?c++的单件模式可以解决这个问题,但是其中一个难点是要在main之前注册单件。c++可以通过构造函数来实现注册,c如何注册?
最后查了下资料,原来可以定义在main之前调用的函数!有了这个特性可以改善c的模块化设计。
特性介绍:
如果想定义在main函数之前调用的函数,可以在函数的声明之后加上一句“__attribute__((constructor))”,如下:
int before()__attribute__((constructor));
如果想定义在main函数之后调用的函数,可以在函数的声明之后加上一句“__attribute__((destructor))”,如下:
int after()__attribute__((destructor));
可以看得出来,应该类似于c++中的构造和析构。

一些细节问题:
写测试代码测试了一下这个程序,发现几点:
1、before在main之前调用,调用之前,各个全局变量已经完成初始化。也就是说,这些函数是在全局变量初始化之后,main函数之前调用的。这一点是非常重要的,否则可能会引起很多的问题。
2、after在main之后调用,但是有一点比较特殊,必须是在main中return的话才执行,否则,需要通过atexit执行某函数。这个特性目前对我没有太大的用处。
3、在main函数之前调用的函数可以声明为static。
4、在main函数之前调用的函数可以调用多个。这里就有一个问题,就是这些函数的调用顺序的问题。这个问题首先是一个设计的问题,也就是,我们应该设计这些函数为顺序无关的函数。另外,调用顺序和编译的顺序相关,我在linux下使用make进行编译,发现最后编译的源文件中的函数会最先调用。
5、可以在库(动态库和静态库)中定义这样的函数。

用对设计的作用:
1、可以优化c++中的单件模式。参考《设计模式》
单件模式有一个最大的特点就是可以在运行过程中连接单件。如果使用条件语句来决定使用哪个单件硬性限定了可能的单件集合。所以,书中引入了一个单件注册表的概念,书中对单件注册表的初始化采用的是如下的做法:
首先定义一个单件类,在单件类的构造函数中调用单件的注册函数注册自身:
复制代码 代码如下:

MySingleton::MySingleton()
{
...
Singleton::Register("MySingleton", this);
}

这个函数是怎么被调用的那?可以定义一个静态实例:
static MySingleton theSingleton;
这样就会在main函数之前调用MySingleton的构造函数来构造这个静态实例,从而达到像注册表注册的目的。
这个方案有个缺点:它能够成功存在一个前提,就是在theSingleton实例化之前,单件注册表列表必须存在,否则会失败。则其实只是一个可能失败的点,如果MySingleton还应用其他的全局变量,则可能这个时候这些全局变量还没有初始化。
解决这个问题的一个方案就是将单件注册的时间由构造函数移到main函数之前调用的函数中来。
定义函数:
复制代码 代码如下:

static void before_main()
{
Singleton::Register("MySingleton", &theSingleton);
}
声明:
staitc void before_main()__attribute__((constructor));

before_main会在main函数之前调用,而调用时全局变量已经全部初始化,这样就可以避免上面的问题。
其实单件不单单可以在c++(面向对象)中使用,也可以在c中使用。而且有了c的这个特性后,单件更好用。
2、构造插件开发框架,而不用对框架进行更改。
构造插件开发框架的一个问题是:如何新增一个插件而不用修改主框架代码就可以调用插件代码。一般情况下都会使用插件注册机制。也就是框架对外提供注册接口,插件使用这些接口进行注册。c要实行此功能,一个可行的方案是在插件中定义main之前执行的函数,在此函数中调用插件注册接口完成注册。(注:这里讨论的是插件的静态加载)。
3、一个模块有一些初始化工作要做,使用这种机制可以不更改main或者函数。
抛开插件框架,使用这个特性也可以对c的模块化进行很多优化。比如,可以把各个模块的初始化工作放在main之前进行从而防止对main的频繁修改。
注:本文描述的环境为linux c,c++。
[!--infotagslink--]

相关文章

  • 如何用Matlab和Python读取Netcdf文件

    这篇文章主要介绍了如何用Matlab和Python读取Netcdf文件,帮助大家更好的理解和学习使用python,感兴趣的朋友可以了解下...2021-02-20
  • 详解Matlab中 sort 函数用法

    这篇文章主要介绍了matlab中 sort 函数用法 的相关资料,需要的朋友可以参考下...2016-03-22
  • Matlab使用fft画出信号频谱图的方法

    这篇文章主要介绍了Matlab使用fft画出信号频谱图的方法,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-05-19
  • 将pycharm配置为matlab或者spyder的用法说明

    这篇文章主要介绍了将pycharm配置为matlab或者spyder的用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-06-09
  • MATLAB 如何求取离散点的曲率最大值

    这篇文章主要介绍了MATLAB 求取离散点的曲率最大值操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-16
  • C++ 17转发一个函数调用的完美实现

    这篇文章主要给大家介绍了关于C++ 17如何转发一个函数调用的完美实现方法,文中通过示例代码介绍的非常详细,对大家学习或者使用C++17具有一定的参考学习价值,需要的朋友们下面跟着小编来一起学习学习吧。...2020-04-25
  • Matlab实现数据的动态显示方法

    这篇文章主要为大家详细介绍了Matlab使用Plot函数实现数据动态显示方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-04-25
  • 简述Matlab中size()函数的用法

    size()函数用来获取矩阵的行数和列数。接下来通过本文给大家介绍matlab中size()函数的用法,需要的朋友一起学习吧...2016-03-22
  • Matlab制作视频并转换成gif动态图的两种方法

    这篇文章主要介绍了Matlab制作视频并转换成gif动态图的两种方法,第一种方法使用movie(f)直接取生成AVI视频文件,相对来说比较简单,需要的朋友可以参考下...2020-04-25
  • 使用pycallgraph分析python代码函数调用流程以及框架解析

    这篇文章主要介绍了使用pycallgraph分析python代码函数调用流程以及框架解析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-03-06
  • MATLAB Delaunay算法提取离散点边界的方法

    这篇文章主要为大家详细介绍了MATLAB Delaunay算法提取离散点边界的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-04-25
  • C++如何调用matlab函数

    这篇文章主要介绍了C++如何调用matlab函数的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下...2020-04-25
  • 基于python实现matlab filter函数过程详解

    这篇文章主要介绍了基于python实现matlab filter函数过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-09
  • C#调用Matlab生成的dll方法的详细说明

    这篇文章详细介绍了C#调用Matlab生成的dll方法,有需要的朋友可以参考一下...2020-06-25
  • JavaScript实现显示函数调用堆栈的方法

    这篇文章主要介绍了JavaScript实现显示函数调用堆栈的方法,实例分析了JavaScript显示函数调用堆栈的具体作用与使用方法,需要的朋友可以参考下...2016-04-23
  • 解决python调用matlab时的一些常见问题

    这篇文章主要介绍了解决python调用matlab时的一些常见问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-24
  • 基于C++内存分配、函数调用与返回值的深入分析

    本篇文章是对C++中的内存分配、函数调用与返回值进行了详细的分析介绍,需要的朋友参考下...2020-04-25
  • C++调用Matlab函数求特征值

    这篇文章主要为大家详细介绍了C++调用Matlab函数求特征值,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-04-25
  • Java如何调用Matlab程序

    这篇文章主要介绍了Java如何调用Matlab程序的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-06
  • matlab、python中矩阵的互相导入导出方式

    这篇文章主要介绍了matlab、python中矩阵的互相导入导出方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-06-02