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()函数执行前(或动态库加载时)自动执行该函数 / 在程序退出时执行。 - 典型场景:全局初始化、注册机制。