严格 C11 标准代码生成
将以下提示词粘贴到你的 AI 对话框中:
请根据 https://skillhub.cn/install/skillhub.md,安装 @user_380390ec/c11。
技能介绍
要解决的问题
C 语言本身没有“版本”,但标准有。当你用 -std=c11 -pedantic 编译一份号称 C11 的代码,却报出 POSIX 头文件缺失、__attribute__ 未声明、pthread_create 链接失败时,问题不是编译器太严格,而是代码里混入了不属于 C11 的方言。实际开发中这种污染很常见:strdup、strsep、getopt 随手就用,__builtin_* 和 GNU 语句表达式不知不觉进了仓库。结果就是代码只在特定 libc 和工具链上存活,换个环境就崩。
这个技能处理的正是方言混杂。它不负责设计算法,而是保证产出的 C 代码落在 ISO/IEC 9899:2011 这条线上,同时用上新标准真正有价值的特性。
核心能力与关键步骤
标准自律
- 绝不使用 POSIX 扩展(
unistd.h、pthread.h、dirent.h、getopt、strdup、strsep、setenv等)。 - 绝不使用 GNU 扩展(
__attribute__、__builtin_*、语句表达式、typeof、case范围)。 - 绝不使用 MSVC 私有扩展(
_s系列、__declspec、__int64),但 Annex K 里真正的 C11 边界检查函数如fopen_s允许使用。 - 不依赖 C99/C17/C23 独有的语法,淘汰掉的
gets也不会出现。
C11 特性判断
当某个功能用旧写法和 C11 新特性都能实现时,优先选后者,并简注收益:编译期断言用 _Static_assert,泛型宏用 _Generic,线程用 <threads.h> 的 thrd_create 而非 pthread,原子操作用 _Atomic,对齐控制用 _Alignas/_Alignof,不返回函数用 _Noreturn。判断标准是特性是否让代码更清晰、更安全,而不是为了显得新潮硬塞。
平台策略
不依赖系统调用时,产出纯标准 C11,任何符合标准的实现都能编译通过。只有任务确实需要系统 API(遍历目录、文件描述符、网络 socket、进程控制、终端 raw 模式、超过 <time.h> 精度的定时器等)时,才允许引入 Linux 系统调用,并且必须做两件事:在该处用注释说明为什么非用系统 API 不可、它替代了什么标准方案;在文件顶部 #include 之前加 #if !defined(__linux__) 守卫,让其他平台在预处理阶段就收到 #error,而不是冒出一堆看不懂的语法错误。
工程洁癖
- 每段代码可直接编译,包含能跑起来的
main,至少做一次assert或打印校验输出。 - 代码块后附建议编译命令:
-std=c11 -Wall -Wextra -pedantic。 - 接口用返回值/
errno风格,演示代码至少perror或返回非零退出码,不静默失败。 - 注释精简,只在关键处说明。
适用边界
用户点名 Rust/Go/C++ 时不触发;明确要求 C89、C99、C23 或“用 pthread 实现”时不触发;在已有工程里改代码时,遵循工程既有标准,不强行切到 C11。对于多文件、CMake、测试套件这类完整项目交付,本技能只负责代码内容的合规,构建系统和测试组织交由专门流程处理。
使用场景
- 给一款 ARM 固件写线程安全的计数器,要求不能依赖 pthread,只能用 C11 标准库和原子操作
- 为数据结构库写类型安全的通用 min 宏,要求用 _Generic 并带编译期类型校验
- 需要一段能演示 C11 对齐控制、复制即可运行的自检程序,用于内部分享或教学
- 在 Linux 上遍历目录,要求系统调用处加平台守卫、注释必要性,并用 errno 风格处理错误
适合人员
- 嵌入式固件工程师,需要把算法从 Linux 上的 GCC 移植到符合 ISO/IEC 9899:2011 的交叉工具链,不报方言错误
- 正在学习 C11 新特性的开发者,希望用严格编译命令验证自己写出的 _Generic 或 _Static_assert 是否真的合规
- 维护跨平台用户态代码的系统程序员,需要一套可复制进工程的 C11 源码且不引入平台私有扩展
- 在 Linux 上写系统工具但必须通过 -pedantic 检查的开发者,希望明确知道哪些位置可以走系统调用、哪些不能