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

GCC 編譯器下實現 C 語言建構子與解構子屬性

     編輯:關於C語言

使用 GCC 屬性在 C 語言中實現建構子/解構子機制

C 語言本身沒有類別與物件,但 GCC 提供函式屬性 __attribute__((constructor)) 與 __attribute__((destructor)),讓指定函式在 main() 執行前自動執行、在 main() 結束或呼叫 exit() 後自動執行,模擬 C++ 的建構子/解構子行為。

基本語法


// 宣告處標記
void begin(void) __attribute__((constructor));
void end(void) __attribute__((destructor));

// 或定義處標記
__attribute__((constructor)) void begin(void) { /* 初始化碼 */ }
__attribute__((destructor)) void end(void) { /* 清理碼 */ }

執行順序示範


#include <stdio.h>

void begin(void) __attribute__((constructor));
void end(void) __attribute__((destructor));

int main(void) {
    printf("Inside main()\n");
    return 0;
}

void begin(void) { printf("In begin()\n"); }
void end(void) { printf("In end()\n"); }

輸出:


In begin()
Inside main()
In end()

多重建構子/解構子與優先權

可指定優先權數值(整數),建構子優先權越小越早執行,解構子優先權越大越早執行(LIFO)。


void begin_0(void) __attribute__((constructor(101)));
void end_0(void) __attribute__((destructor(101)));
void begin_1(void) __attribute__((constructor(102)));
void end_1(void) __attribute__((destructor(102)));
void begin_2(void) __attribute__((constructor(103)));
void end_2(void) __attribute__((destructor(103)));

執行順序:


In begin_0()
In begin_1()
In begin_2()
Inside main()
In end_2()
In end_1()
In end_0()

注意:優先權 0~100 保留給實作內部使用,建議使用 101 以上數值避免警告。

運作原理

  • 程式真正進入點是啟動程式碼(_start/crt0),而非 main。
  • 啟動程式碼初始化執行環境,依優先權呼叫 .ctors 區段的建構子函式,再呼叫 main。
  • main 返回後,啟動程式碼依優先權呼叫 .dtors 區段的解構子函式。
  • exit() 同樣觸發解構子;_exit()/abort() 則不會。

實務應用場景

  1. 全域資源自動初始化/清理:動態配置的全域連結串列頭、陣列、檔案描述符,在建構子配置,解構子釋放。
  2. 函式庫自動初始化:將多個庫的初始化函式封裝為建構子,清理函式封裝為解構子,應用程式只需連結該檔案,無需手動呼叫初始化/清理 API。
  3. 錯誤處理:建構子中發現嚴重錯誤可直接 exit(),解構子仍會執行清理。

可移植性警告

此機制僅限 GCC/Clang 支援,MSVC、其他編譯器不支援。跨平台專案建議以標準 C 方式(手動呼叫 init/cleanup 函式)實作,或以巨集條件編譯隔離 GCC 專屬代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved