任何一们面向对象语言里都会涉及构造函数这一律念,只是实现的方式各有差别。须要这main函数以前执行一段代码是很是容易的事情,只须要声明一对象的全局变量,在构造函数能够随心所欲干你想干的事情。然而,对于面向过程的语言好比C,须要实现全局的构造函数就比较奇葩。固然gcc会有很优雅的解决方式,VC则猥琐点。git
其实在main函数里面调用一下就能够了,是的,这样是能够,可是对于框架的实现来讲,这倒是不太好的,客户使用起来不自由。固然也能够说,我是屌丝,我能够装逼点。github
gcc实现
gcc 实现是很是简单的事情。在全局构造函数前叫如下编译器属性便可:
attribute((constructor))框架
vc实现
vc的实现比较奇葩,VC自己没有相似·attribute·这样的属性,你须要将全局函数编译到某个特定的代码段里面。MSDN对于这部分有详细的说明:CRT Initialization
简单来讲就是将你的全局构造函数的函数指针编译到·.CRT$XCU·段里面。如何编译到·.CRT$XCU·段?VC有VC的语法。函数
// 声明在段·\.CRT$XCU·里面生成代码 #pragma section("\.CRT$XCU",read) // 声明须要调用的函数 __declspec(allocate("\.CRT$XCU")) void (\_\_cdecl *a)(void) = func; // 调用的函数实现 void func(void){}
以上实现能够用下面实现:单元测试
#ifdef _MSC_VER #define __CCALL __cdecl #define __func__ __FUNCTION__ #define snprintf _snprintf #pragma warning(disable:4996) // this is very violent #pragma section(".CRT$XCU",read) #define __CONSTRCT(a, b) \ void __CCALL __##a##__##b##__ ## 520hjm(void); \ __declspec(allocate(".CRT$XCU")) \ void (__CCALL * __ctor__##a##__##b##__ ## 520hjm)(void) = \ __##a##__##b##__ ## 520hjm; #else #define __CCALL #define __CONSTRCT(a, b) __attribute__((constructor))
仿照gtest的简易单元测试ctest就是用的这方面的知识。测试
这里显示效果不是很好,我的网站那里效果好点http://luoguochun.cn/2014/06/25/c-constructor/网站