我的 C23 约定:[[nodiscard]]、更规整的联合体与显式底层类型的枚举
来源:abner.page — 2026-10-15
📋 概述
Abner 总结了给 zig build 加上 -std=c23 之后自然长出来的三条约定。第一,用 [[nodiscard]] 强制调用方接管绘制函数返回的矩形,漏接就是业务逻辑 bug;确有不需要返回值的少数场景,就改用 [[maybe_unused]] 取代老的 UNUSED() 宏,甚至形成 [[maybe_unused]] auto _ = foo() 这种写法。第二,他提醒指定初始化并不会清空联合体成员:C23 之前的 {0} 只保证时间戳那种第一个成员归零,GCC 与 Clang 在联合体清零上的行为甚至大约一年前互相交换过,最稳的做法是用空花括号 {} 全量初始化后再逐字段赋值,并在设计联合体时把最大成员放最前。第三,C 的枚举底层类型会在常量放不下时被自动调整,他引用 Jens Gustedt 的建议,改用 enum options : int 显式写清底层类型。
🔑 核心要点
- 用 [[nodiscard]] 强制调用方接管绘制函数返回的矩形,漏接就是业务逻辑 bug
- 少数确实不需要返回值的地方改用 [[maybe_unused]],由此删掉了老的 UNUSED() 宏
- 新写法随之出现:[[maybe_unused]] auto _ = foo(),社区还给出配套宏版本
- 指定初始化不会清空联合体成员,作者误以为 date 会归零而付了代价
- GCC 与 Clang 的联合体清零行为大约一年前互相交换过,标准只要求第一个成员归零
- 正解是用空括号 {} 整体初始化后再逐字段赋值,并把联合体最大成员放在最前;枚举则显式写 enum options : int
💡 金句
C23 的初始化永远会初始化整个联合体——注意是空括号,不是括号里写 0,{ 0 } 的行为和 C23 之前一样。
👍 0
👎 0
← 返回 Lobsters 首页