代码示例:1.3.11 C11 嵌入式相关特性
全部示例均标注编译命令、适用环境与实测状态;完整验证记录见《03.5-代码编译运行验证记录》。
examples/ex1-register-macros.c · uint32_t 寄存器宏 + _Static_assert 编译期校验
/* ex1-register-macros.c —— uint32_t 寄存器宏 + _Static_assert(1.3.11) * 编译:gcc ex1-register-macros.c -o ex1 -std=c11 -Wall -Wextra -Wpedantic */ #include <stdio.h> #include <stdint.h> _Static_assert(sizeof(uint32_t) == 4, "uint32_t must be exactly 4 bytes"); static volatile uint32_t reg_ctrl = 0; #define REG_SET_BIT(reg, bit) ((reg) |= (1u << (bit))) #define REG_CLEAR_BIT(reg, bit) ((reg) &= ~(1u << (bit))) #define REG_TOGGLE_BIT(reg, bit) ((reg) ^= (1u << (bit))) #define REG_IS_SET(reg, bit) (((reg) >> (bit)) & 1u) int main(void) { REG_SET_BIT(reg_ctrl, 3); printf("set bit3: 0x%08X\n", (unsigned)reg_ctrl); REG_TOGGLE_BIT(reg_ctrl, 0); printf("toggle bit0: 0x%08X\n", (unsigned)reg_ctrl); printf("is_set bit3=%u bit0=%u\n", REG_IS_SET(reg_ctrl, 3), REG_IS_SET(reg_ctrl, 0)); REG_CLEAR_BIT(reg_ctrl, 3); printf("clear bit3: 0x%08X\n", (unsigned)reg_ctrl); return 0; }examples/ex2-atomic-counter.c · C11 _Atomic 原子计数器(与 volatile 对比的单线程语义演示)
/* ex2-atomic-counter.c —— C11 _Atomic 原子计数器(1.3.11) * 编译:gcc ex2-atomic-counter.c -o ex2 -std=c11 -Wall -Wextra -Wpedantic * 说明:单线程演示 _Atomic 语义;volatile 只保证内存访问不保证原子性, * 多线程并发下的数据竞争见 ex3 conceptual(不运行危险代码)。 */ #include <stdio.h> #include <stdatomic.h> _Atomic int atomic_counter = 0; volatile int volatile_counter = 0; int main(void) { atomic_fetch_add(&atomic_counter, 1); atomic_fetch_add(&atomic_counter, 1); printf("atomic_counter = %d\n", atomic_load(&atomic_counter)); volatile_counter = volatile_counter + 1; printf("volatile_counter = %d\n", volatile_counter); printf("atomic_is_lock_free = %d\n", atomic_is_lock_free(&atomic_counter)); return 0; }examples/ex3-volatile-notes.txt · volatile 不能替代互斥锁/原子的机理(conceptual:静态讲解,不运行)
# 1.3.11 ex3(conceptual 讲解文本,不编译不运行):volatile 不能替代互斥锁/原子 # 依据:C11 标准 N1570 §5.1.2.4(数据竞争)、§6.7.3(volatile)、§7.17(原子库) # # 1. volatile 的真实语义:对"每次访问"的约束—— # 编译器不得把对该对象的读写优化掉/缓存进寄存器/与其它 volatile 访问重排; # 它不提供:原子性、内存序、互斥。 # # 2. 为什么 volatile 不能保证并发安全: # volatile int x; x++ 实际是三步:读 x → 加一 → 写 x。 # 线程 A 与 B 同时执行时,两个线程可能都读到旧值 0,各自写回 1——一次更新丢失。 # volatile 只保证"每一步都真去内存",不保证"三步之间没有别人插入"。 # # 3. 正确方案分层(本章核心结论): # - 单变量简单共享(计数/标志位翻转)→ C11 原子:_Atomic int 或 atomic_fetch_add; # - 多变量/多步操作的互斥(银行转账式的复合操作)→ 互斥锁(5.3 pthread 展开); # - volatile 的正当用途 → 内存映射寄存器(MMIO)与信号处理共享标志(5.4 展开)。 # # 4. 纪律声明:本课程不通过运行多线程数据竞争代码来演示(未定义行为,观察输出无教学价值), # 该结论由语言标准条文保证,而非某次运行的偶然结果。