Skip to content

GCC __attribute__ 常用速查手册

本文档总结了 C/C++ 开发(尤其是系统编程与性能优化)中高频使用的 GCC 属性。

基本语法__attribute__((attribute-list))位置:通常放在函数声明的分号前,或变量定义的末尾。


一、 优化辅助 (Optimization Hints)

告诉编译器函数的行为(副作用),帮助其进行更激进的 ADCE、DSE 和 CSE。

1. pure

  • 含义:函数没有副作用(不修改全局变量/内存),但可能读取全局变量。返回值仅依赖于参数和全局变量。
  • 效果:允许编译器进行公共子表达式消除 (CSE)循环外提
  • 典型场景strlen(), get_global_config_value().

2. const

  • 含义:比 pure 更严格。函数不读也不写全局内存。返回值仅依赖于参数
  • 效果:编译器可以将多次调用折叠为一次(计算结果复用)。
  • 典型场景abs(), sin(), sqrt(), 简单的数学计算。
  • 注意const 函数不能读取指针指向的内容(因为那也是内存)。

3. malloc

  • 含义:告诉编译器该函数返回的指针指向一块“全新”的内存,不与任何现存指针重叠 (No Alias)
  • 效果:极大优化别名分析 (Alias Analysis),帮助 DSE 消除冗余存储。
  • 典型场景:自定义的内存分配器 my_malloc().

4. alloc_size(N) / alloc_size(A, B)

  • 含义:配合 malloc 使用,告诉编译器返回内存的大小是第 N 个参数(或 A * B)。
  • 效果:允许编译器进行缓冲区溢出检查 (Object Size Checking) 和更精确的内存优化。

5. hot

  • 含义:标记函数或代码路径为“热点”(频繁执行)。
  • 效果:编译器会进行更激进的优化(如内联),并将其代码段放在 .text.hot 节,利用 I-Cache 局部性。

6. cold

  • 含义:标记函数或路径为“冷门”(几乎不执行,如错误处理)。
  • 效果:优化器会为了减小体积而非速度进行优化,并将其移到 .text.unlikely,避免污染指令缓存。

二、 内联控制 (Inlining Control)

直接干预函数调用的展开行为。

1. always_inline

  • 含义:强制内联,即使在 -O0 下或函数体很大时也生效(除非递归)。
  • 效果:消除函数调用开销,暴露函数体给调用者的优化 Pass。
  • 典型场景:极小的 wrapper 函数、关键路径上的短函数。

2. noinline

  • 含义:禁止内联。
  • 效果:保持独立的栈帧。
  • 典型场景:调试方便、破坏栈溢出攻击、或者是为了分割冷热代码。

3. flatten

  • 含义:将该函数调用的所有子函数(只要代码可见)全部内联到该函数中。
  • 效果:相当于对该函数树下的所有调用强制 always_inline
  • 典型场景:性能极其敏感的核心计算核(Kernel)。

三、 代码布局与链接 (Layout & Linkage)

控制符号的可见性、生命周期和物理存储位置。

1. visibility("hidden") / visibility("default")

  • 含义:控制动态链接库 (DSO) 中符号的可见性。
  • 效果hidden 类似 static,符号不对外导出。能减少 PLT/GOT 跳转开销,显著提升加载速度和运行性能。
  • 建议:编译库时默认全藏 (-fvisibility=hidden),只对 API 加 default

2. used

  • 含义:告诉编译器“该变量/函数被使用了”,即使静态分析认为没人调用它。
  • 效果防止被 GlobalDCE 删除
  • 典型场景:被内联汇编引用、被硬件中断调用、或调试标记。

3. unused

  • 含义:告诉编译器该变量可能不被使用。
  • 效果消除“未使用变量”的警告(不会影响优化,只是为了通过 -Werror)。

4. section("name")

  • 含义:将函数或变量放入指定的 ELF 段 (Section)。
  • 效果:用于底层系统编程,如放入特定的内存区域(DMA 缓冲区、TCM 等)。

5. weak

  • 含义:定义弱符号。如果链接时发现同名的强符号,则使用强符号;否则使用这个。
  • 典型场景:库函数提供默认实现,允许用户覆盖(Override)。

6. alias("target")

  • 含义:给函数起个别名。

四、 内存对齐与结构 (Memory & Type)

控制变量和结构体的内存布局,影响缓存行利用率。

1. packed

  • 含义:取消结构体成员间的填充 (Padding),紧密排列。
  • 效果:节省内存,但可能导致非对齐访问(性能下降或硬件异常)。
  • 典型场景:网络协议头、硬件寄存器映射、文件格式解析。

2. aligned(N)

  • 含义:强制变量或结构体的起始地址按 N 字节对齐。
  • 效果:利用 SIMD 指令(通常要求 16/32/64 字节对齐),或避免 Cache Line 伪共享 (False Sharing)。
  • 典型场景__attribute__((aligned(64))) 用于多线程下的锁或原子变量。

五、 检查与诊断 (Diagnostics & Safety)

帮助编译器发现潜在 Bug。

1. format(archetype, string-index, first-to-check)

  • 含义:告诉编译器该函数接受类似 printf/scanf 的格式化字符串。
  • 效果:编译器会检查参数类型是否与格式化字符串匹配。

2. nonnull(N, ...)

  • 含义:告诉编译器第 N 个参数不能为 NULL。
  • 效果:编译器可能会利用此信息删除函数内部的 NULL 检查代码(DCE),或发出警告。

3. warn_unused_result

  • 含义:如果调用者不检查该函数的返回值,发出警告。
  • 典型场景realloc, open, 涉及资源分配或错误码的函数。

4. deprecated("message")

  • 含义:标记函数已过时。
  • 效果:调用时编译报警,提示迁移。

5. constructor / destructor

  • 含义:在 main() 函数执行前(或动态库加载时)自动执行该函数 / 在程序退出时执行。
  • 典型场景:全局初始化、注册机制。