任何一們面嚮對象語言裏都會涉及構造函數這一律念,只是實現的方式各有差別。須要這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/網站