__attribute__
2026/7/6大约 2 分钟
GCC __attribute__
__attribute__ 是 GCC/Clang 提供的编译器扩展,用来给变量、函数、类型附加特殊属性。
基本语法:
__attribute__((属性))
__attribute__((属性(参数)))嵌入式中常见的有:
packed
aligned
unused
weak
section一、packed:取消结构体填充
struct Frame
{
uint8_t cmd;
uint32_t timestamp;
} __attribute__((packed));普通结构体可能存在对齐填充:
cmd 1 字节
padding 3 字节
timestamp 4 字节使用 packed 后:
cmd 1 字节
timestamp 4 字节常用于:
- 协议报文
- Flash 数据结构
- 硬件定义的数据布局
注意:取消对齐可能导致未对齐访问,某些 MCU 上访问效率下降甚至产生异常。
二、aligned:指定对齐
struct Buffer
{
uint8_t data[64];
} __attribute__((aligned(32)));表示该对象至少按 32 字节边界对齐。
常用于:
- DMA 缓冲区
- Cache line 对齐
- 特殊内存区域
例如:
0x20000000 ✅
0x20000020 ✅
0x20000040 ✅三、unused:告诉编译器“这个东西故意没用”
void isr_handler(int irq_num __attribute__((unused)))
{
handle_interrupt();
}irq_num 没有使用,但不会产生 unused 警告。
也可以修饰变量:
static int debug_flag __attribute__((unused));四、weak:弱符号
STM32 启动文件中非常常见。
默认实现:
void UART_IRQHandler(void)
__attribute__((weak));
void UART_IRQHandler(void)
{
while (1);
}用户自己定义同名函数:
void UART_IRQHandler(void)
{
// 实际中断处理
}链接时,普通强符号会覆盖 weak 符号。
所以启动文件可以提前提供默认中断函数,用户无需修改启动文件。
核心:
weak 默认实现
↓
用户提供同名强实现
↓
链接器选择强实现五、section:指定变量/函数所在段
例如 Bootloader 中:
const uint32_t app_version
__attribute__((section(".app_version"))) = 0x00010001;函数也可以:
void isr_vector_table(void)
__attribute__((section(".isr_vector")));最终由链接脚本决定:
变量/函数
↓
指定 section
↓
链接脚本
↓
放入指定 Flash / RAM 地址常用于:
- Bootloader
- 固定 Flash 分区
- 中断向量表
- 特殊 RAM 区域
六、核心理解
__attribute__
↓
告诉编译器:“这个对象需要特殊处理”
↓
packed → 取消填充
aligned → 指定对齐
unused → 消除未使用警告
weak → 弱符号,可被覆盖
section → 指定存储段
__attribute__不是 C 标准语法,而是 GCC/Clang 的扩展;嵌入式中主要用于控制内存布局、链接行为和编译器行为。

