GCC编译器中__attribute__部分整理
__attribute__ 是 GCC/Clang 编译器提供的一个扩展特性(并非标准 C/C++ 语法),用于给函数、变量、类型等添加额外的编译期属性,编译器会根据这些属性做优化、检查或约束。它的基本语法是:
// 函数/变量/类型 后加属性
声明 __attribute__((属性1, 属性2));
// 类型定义时加属性
typedef struct { ... } 类型名 __attribute__((属性));
下面按常用场景分类讲解核心属性及其作用,优先覆盖实际开发中最常用的部分:
一、函数相关属性
1. noreturn
作用:告诉编译器该函数永远不会返回(比如 exit()、abort()),编译器会优化调用该函数后的代码(比如省略无用的清理逻辑),并避免警告。
示例:
void fatal_error(const char* msg) __attribute__((noreturn));
void fatal_error(const char* msg) {
printf("Error: %s\n", msg);
exit(1); // 无返回
}
2. const
作用:标记函数的返回值仅依赖输入参数,且无副作用(不修改全局变量、不调用其他有副作用的函数),编译器可做重复调用优化(比如缓存返回值)。
限制:函数不能有指针参数(避免间接修改外部数据),不能访问全局变量。
示例:
int square(int x) __attribute__((const)); int square(int x) { return x * x; // 仅依赖输入,无副作用 }
3. pure
作用:比 const 宽松,函数返回值依赖输入参数或全局变量,但无写操作(仅读)、无副作用,编译器同样可优化重复调用。
示例:
int get_global_count() __attribute__((pure));
int get_global_count() {
extern int global_count;
return global_count; // 仅读全局变量,无写操作
}
4. always_inline
作用:强制编译器内联该函数(忽略 -O 优化级别),适合频繁调用的小函数(减少函数调用开销)。
对比:inline 是建议内联,always_inline 是强制内联。
示例:
static inline int add(int a, int b) __attribute__((always_inline));
static inline int add(int a, int b) {
return a + b;
}
5. deprecated
作用:标记函数 / 变量为 “已废弃”,编译时若调用该函数,会抛出警告(提示开发者改用新接口)。
示例:
// 标记旧函数为废弃,并自定义警告信息
void old_api() __attribute__((deprecated("use new_api() instead")));
void old_api() { /* 旧逻辑 */ }
二、变量 / 数据相关属性
1. aligned(n)
作用:指定变量 / 类型的内存对齐字节数(n 需是 2 的幂),提升内存访问效率(比如硬件要求特定对齐)。
示例:
// 变量 buf 按 16 字节对齐
char buf[32] __attribute__((aligned(16)));
// 结构体按 8 字节对齐
typedef struct {
int a;
double b;
} Data __attribute__((aligned(8)));
2. packed
作用:取消结构体 / 联合体的自动内存对齐,强制按最小字节(1 字节)排列,减少内存占用(常用于网络协议、硬件寄存器映射)。
注意:可能降低访问效率,且部分平台不支持未对齐访问。
示例:
// 结构体紧凑排列,无填充字节
typedef struct {
char a; // 1 字节
int b; // 4 字节(无填充,直接跟在 a 后)
} Packet __attribute__((packed));
// 总大小:5 字节(默认对齐会是 8 字节)
3. section("name")
作用:将变量 / 函数放到指定的内存段(section),常用于嵌入式开发(比如将配置数据放到 Flash 特定区域)。
示例:
// 将 config 变量放到 "custom_data" 段
int config = 100 __attribute__((section("custom_data")));
三、类型相关属性
1. unused
作用:告诉编译器 “该变量 / 函数可能未被使用”,避免抛出 “未使用变量 / 函数” 的警告(比如调试用的临时变量)。
示例:
// 即使 tmp 未被使用,编译器也不报警
int tmp __attribute__((unused)) = 10;
2. format(类型, 格式化参数位置, 可变参数位置)
作用:检查函数的格式化字符串(如 printf/scanf 风格)是否与参数匹配,编译时抛出格式错误警告。
常用类型:printf、scanf。
示例:
// 自定义打印函数,检查格式字符串(第 1 个参数是格式串,第 2 个是可变参数)
void my_printf(const char* fmt, ...) __attribute__((format(printf, 1, 2)));
void my_printf(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
}
// 若调用 my_printf("%d", "abc"); 编译器会报警:格式串 %d 期望 int,实际传了字符串
四、其他常用属性
1. warn_unused_result
作用:强制要求调用者必须使用函数的返回值,否则编译警告(比如 fopen()、malloc() 这类返回值关键的函数)。
示例:
int check_error() __attribute__((warn_unused_result));
int check_error() {
return 1; // 返回错误码
}
// 若调用 check_error(); 无接收返回值,编译器报警
五、总结
1、__attribute__ 是 GCC/Clang 扩展,用于给编译单元(函数 / 变量 / 类型)加属性,核心作用是优化、检查、约束;
2、高频属性场景:
- 函数:
noreturn(无返回)、always_inline(强制内联)、deprecated(废弃警告); - 结构体:
packed(紧凑对齐)、aligned(n)(指定对齐); - 通用:
unused(屏蔽未使用警告)、format(格式化字符串检查);

浙公网安备 33010602011771号