首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C語言在main前後執行函數:GCC屬性與MSVC段映射兩大方案

     編輯:關於C

GCC/Clang方案:構造/析構屬性

__attribute__((constructor)) void before_main() {
    printf("%s\n", __FUNCTION__);
}

__attribute__((destructor)) void after_main() {
    printf("%s\n", __FUNCTION__);
}

int main(int argc, char **argv) {
    printf("%s\n", __FUNCTION__);
    return 0;
}

輸出順序:before_main → main → after_main

支持多個構造/析構函數,按定義順序/逆序執行。

MSVC方案:CRT初始化段映射

#pragma data_seg(".CRT$XIU")  // 初始化段:XCU~XCUZ之間任意字母排序
static void (*before[])(void) = { before_main };
#pragma data_seg(".CRT$XPU")  // 終止段:XPU~XPUZ之間
static void (*after[])(void) = { after_main };
#pragma data_seg()

段命名規則:

  • .CRT$XCU:C++全局對象構造函數
  • .CRT$XIU:用戶定義初始化(排在XCU後)
  • .CRT$XPU:用戶定義終止(排在XPZ前)

跨平台統一封裝

#ifdef _MSC_VER
#define CONSTRUCTOR(f) \
    static void f(void); \
    #pragma data_seg(".CRT$XIU") \
    static void (*f##_ptr)(void) = f; \
    #pragma data_seg() \
    static void f(void)
#define DESTRUCTOR(f) \
    static void f(void); \
    #pragma data_seg(".CRT$XPU") \
    static void (*f##_ptr)(void) = f; \
    #pragma data_seg() \
    static void f(void)
#elif defined(__GNUC__)
#define CONSTRUCTOR(f) __attribute__((constructor)) static void f(void)
#define DESTRUCTOR(f) __attribute__((destructor)) static void f(void)
#endif

應用場景

  • 庫自動初始化(如日志、內存池、線程池)
  • 註冊工廠函數、插件掛載
  • 檢測運行環境、設置信號處理
  • 析構時刷新緩存、釋放共享資源

注意事項

  1. 構造函數運行時main未開始,不可依賴主程序初始化的資源
  2. 異常處理:構造函數拋出異常導致程序終止
  3. 動態庫加載順序影響構造執行順序
  4. 嵌入式系統需確認啟動代碼支持.init_array/.fini_array
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved