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 风格)是否与参数匹配,编译时抛出格式错误警告。

常用类型:printfscanf

示例:

// 自定义打印函数,检查格式字符串(第 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(格式化字符串检查);

3、注意:__attribute__ 非标准语法,跨编译器(如 MSVC)需适配(MSVC 用 __declspec 替代)。

 
posted @ 2026-02-24 19:49  oTvTo  阅读(4)  评论(0)    收藏  举报