跳到主要内容
🔍

代码示例: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. 纪律声明:本课程不通过运行多线程数据竞争代码来演示(未定义行为,观察输出无教学价值),
    #    该结论由语言标准条文保证,而非某次运行的偶然结果。