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() 則不會。exit(),解構子仍會執行清理。此機制僅限 GCC/Clang 支援,MSVC、其他編譯器不支援。跨平台專案建議以標準 C 方式(手動呼叫 init/cleanup 函式)實作,或以巨集條件編譯隔離 GCC 專屬代碼。