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

GCC 屬性語法詳解:__attribute__ 完整指南與實戰示例

     編輯:關於C語言

GCC `__attribute__` 語法權威指南:從語法規則到四大實戰場景

GCC 擴展屬性 `__attribute__` 是 C/C++ 進階開發利器,用於編譯器優化提示、代碼檢查、符號控制、ABI 兼容等。本文梳理官方文檔語法規則,並通過四個高頻屬性(`alias`、`deprecated`、`format`、`weak`)實戰演示。

語法基礎

__attribute__ (( attribute-list ))
// attribute-list: 逗號分隔的屬性序列
// 屬性形式:
//   1. 空(忽略)
//   2. 單詞:unused, noreturn, const 等
//   3. 單詞 + 參數:format(printf, 1, 2), alias("oldname")

屬性可出現於:標籤後、struct/union/enum 定義、聲明符前、參數聲明、類型限定符中等位置,作用於實體(函數/變量/類型/參數)。

實戰 1:`alias` —— 為符號創建別名

void foo() { printf("In %s\n", __func__); }
void _foo() __attribute__((alias("foo"))); // 聲明別名

int main() { _foo(); } // 輸出 "In foo"

場景: 庫版本兼容、內部實現與公開 API 解耦、glibc 大量使用(如 `_strong_alias` 宏)。

實戰 2:`deprecated` —— 標記棄用接口

__attribute__((deprecated("foo() 已棄用,請用 bar()")))
void foo() { ... }

int main() { foo(); } // 編譯警告:warning: 'foo' is deprecated: foo() 已棄用...

作用: 編譯期發現舊接口調用,平滑遷移 API。

實戰 3:`format` —— 格式化字符串檢查

void my_log(const char *fmt, ...)
    __attribute__((format(printf, 1, 2))); // 第1參數fmt, 第2參數起檢查

void test() {
    my_log("%d %s", 123);      // 警告:格式要求 2 參數,僅給 1
    my_log("%s", 123);         // 警告:%s 需 char*,傳 int
}

原型參數: `format(archetype, string-index, first-to-check)`
`archetype`:`printf`/`scanf`/`strftime`/`strfmon` 等;
`string-index`:格式字符串參數位置(從 1 計);
`first-to-check`:首個被檢查參數位置。

實戰 4:`weak` —— 弱符號機制

// lib.c
void __attribute__((weak)) default_handler() { puts("default"); }

// app.c
void default_handler() { puts("custom"); } // 強定義覆蓋弱定義

// 鏈接時:若 app.c 定義,用 custom;否則用 default,不報重定義錯誤

場景: 庫提供默認實現,應用可選覆蓋;中斷向量表、鉤子函數預留。

其他高頻屬性速查

屬性作用對象用途
noreturn函數函數永不返回(exit/abort/長跳轉),優化調用點
unused變量/參數/函數抑制「未使用」警告
packedstruct/union取消對齊填充,節省空間/匹配硬件佈局
aligned(n)變量/類型/字段指定 n 字節對齊(SIMD、DMA、緩存行)
cleanup(func)自動變量作用域結束自動調用 func(RAII 模擬)
constructor/destructor函數main 前/後自動執行(模塊初始化/清理)

注意事項

  • C++ 模板/重載/name mangling 下屬性語義複雜,建議僅用於聲明而非嵌套聲明符。
  • 屬性不參與類型系統,`typeid` 無法區分帶不同屬性的類型。
  • 跨編譯器移植:MSVC 用 `__declspec`,Clang 支持 GCC 語法,可用宏封裝:
    `#define ATTR(x) __attribute__((x))` / `#define ATTR(x) __declspec(x)`
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved