一键导入
ddev-c-pro
用于 C 语言项目的编写、审阅、重构和调试。当代码库为 .c/.h 且以 C 编译时,优先使用本 skill 而非 C++ 相关 skill。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
用于 C 语言项目的编写、审阅、重构和调试。当代码库为 .c/.h 且以 C 编译时,优先使用本 skill 而非 C++ 相关 skill。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
在当前会话里按已写好的实现计划顺序执行任务时使用
在已有规格或多步骤任务需求、且在动代码之前使用。若上游 ddev-pc-test 已产出测试用例,自动走 TDD 流程:先实现测试 demo 代码(红灯),再实现被测代码(绿灯),测试覆盖不到的部分直接开发。
文档审查技能。将文档审查任务派发给独立子代理,重点审查文档基于代码改动的合理性、说明正确性、前后一致性、错漏和逻辑谬误,以及 AI 实现过程中产生的决策记录(implementation-notes.md)。当用户需要审查技术文档、spec文档、设计文档、计划文档、API文档、README 或任何与代码改动相关的文档时使用。
代码修改场景下,spec 文档确认后,需要继续以图优先方式梳理结构体定义、数据流和流程时使用
在代码修改前需要编写 spec 文档且应优先用图表达边界、入口、流程和改动关系时使用(仅限代码改动场景,非项目级架构文档初始化)
在代码实现完成后、准备结束任务或进入发布前使用,用来核对代码实现是否与 spec 文档以及 detail 文档一致,并通过代码质量审查、清理、编码规范和注释审查后给出最终验收结论
| name | ddev-c-pro |
| description | 用于 C 语言项目的编写、审阅、重构和调试。当代码库为 .c/.h 且以 C 编译时,优先使用本 skill 而非 C++ 相关 skill。 |
资深 C 语言工程师。帮助编写、审阅、重构、调试 C 代码,关注正确性、可移植性、内存安全及 API 设计。 不要假设是 C++,除非用户明确要迁移。
int module_init(const module_cfg_t *cfg);.c 对应一个 .h,内部类型和函数不出现在 header。_status_t 或 _ret_t 枚举。(MODULE_ID << 8) | ERROR_CODE,方便跨模块定位。const char *module_strerror(module_status_t code) 用于调试输出。0 成功,-1/ERR_GENERIC 通用失败,-2/ERR_INVALID_ARG 参数错误。// 推荐:参数封装 + 返回码 + 调用方传 buffer
typedef enum {
MODULE_OK = 0,
MODULE_ERR_INVALID_ARG,
MODULE_ERR_BUSY,
MODULE_ERR_TIMEOUT,
MODULE_ERR_OVERFLOW,
} module_status_t;
module_status_t module_encode(const input_t *in, uint8_t *out, size_t out_cap, size_t *out_len);
memset + 逐字段赋值。
// 推荐
module_cfg_t cfg = { .baud = 115200, .parity = PARITY_NONE };
// 禁止
module_cfg_t cfg;
memset(&cfg, 0, sizeof(cfg));
cfg.baud = 115200;
cfg.parity = PARITY_NONE;
uint16_t 非 short)。uint8_t reserved[N]。static 辅助函数。if/else 超过 4 个固定分支改用 switch、表驱动或状态机。inline 函数:仅用于 ≤ 5 行的简单访问器/包装器;≥ 10 行的实现不要放 .h。typedef void (*uart_rx_cb_t)(uint8_t byte, void *user_data);
void uart_set_rx_callback(uart_t *u, uart_rx_cb_t cb, void *user_data);
...)禁止在公开 API 中使用,调试日志可用 __attribute__((format(printf, ...))) 做编译期格式检查。__attribute__((const)) 或 __attribute__((pure)) 辅助编译器优化。malloc/free)。volatile 仅用于:MMIO 寄存器、ISR 与主循环间共享的标志变量。volatile 不保证原子性 —— 多字节变量在 ISR 中读写必须配合临界区保护。volatile sig_atomic_t 或 _Atomic__disable_irq() / __enable_irq() 临界区static)或堆,不放函数局部栈。.bss 零初始化 / .data 带初值 / .noinit 复位后保留。static_assert(sizeof(buffer) >= MIN_REQUIRED, "...") 做编译期验证。goto 统一清理出口(唯一允许的 goto 用法)。许多嵌入式固件工程会对标准库函数做二次封装,增加边界检查、错误日志、内存池管理或平台适配。编写、审查或计划代码时,必须先检查工程中是否存在标准库函数的替代封装,优先使用工程封装而非裸调标准库。
| 标准库函数 | 典型工程封装 | 工程封装的常见增强 |
|---|---|---|
malloc / calloc | os_malloc / pvPortMalloc / mod_mem_alloc | 内存池、对齐、失败日志 |
free | os_free / vPortFree / mod_mem_free | 内存池回收、指针置 NULL |
memcpy / memmove | mod_memcpy_s / safe_memcpy | 长度校验、重叠检查 |
memset | mod_memset / 无替代(通常直接使用) | — |
strcpy / strncpy | mod_strcpy_s / safe_strcpy | 缓冲区大小强制传入 |
strcat / strncat | mod_strcat_s / safe_strcat | 剩余空间检查 |
strlen | 通常直接使用 / mod_strnlen | 最大长度限制 |
sprintf / snprintf | mod_snprintf / log_snprintf | 截断检测、返回值校验 |
sscanf | mod_sscanf / 无替代 | 输入校验 |
fopen / fclose | mod_fs_open / fs_fopen | 文件系统抽象、错误映射 |
fread / fwrite | mod_fs_read / fs_fwrite | 重试、超时、错误恢复 |
printf | log_info / LOG_INFO / 无替代 | 日志级别、模块标签 |
assert | MOD_ASSERT / configASSERT | 平台特定断言行为 |
在开始编写代码或做审查之前,必须:
docs/architecture/stdlib-wrappers.md 存在,先读取该文档,了解工程中已有的全部替代封装*.h 中的内存分配/字符串操作/文件 I/O 封装函数malloc 替代(如 os_malloc),禁止直接使用 mallocstrcpy/strcat/sprintfblockeddocs/architecture/stdlib-wrappers.md)不存在或已过期,应在审查意见中标注 need-info,建议先运行 ddev-arch 的标准库审计步骤引入或使用第三方库(如 FatFs、lwIP、mbedTLS、FreeRTOS、protobuf-c 等)时,禁止让第三方库直接裸调标准库函数。必须通过适配层注入工程的替代封装,确保第三方库运行在工程统一的内存/IO/断言体系内。
适配方式(按优先级):
// FatFs 示例:在 ffconf.h 中重定向
#define ff_memalloc(n) os_malloc(n)
#define ff_memfree(p) os_free(p)
// FreeRTOS 示例:在 FreeRTOSConfig.h 中重定向
#define configASSERT(x) MOD_ASSERT(x)
// mbedTLS 示例:在 mbedtls_config.h 中重定向
#define MBEDTLS_PLATFORM_MEMORY
#define mbedtls_calloc(n, s) os_calloc(n, s)
#define mbedtls_free(p) os_free(p)
thirdparty/<libname>/<libname>_port.c,实现第三方库期望的接口签名,内部转发到工程封装:
// thirdparty/lwip/lwip_port.c
#include "os/heap.h"
// lwIP 期望的内存分配函数 → 转发到工程封装
void *mem_malloc(mem_size_t size) { return os_malloc((size_t)size); }
void mem_free(void *ptr) { os_free(ptr); }
强制约束:
_port.c 或配置头文件中),不直接修改第三方库原始文件blockeddocs/architecture/stdlib-wrappers.md 中必须记录每个第三方库的适配策略// 模块自身头文件必须最先 include,确保不依赖 include 顺序
#include "module_under_test.h"
#include <stdint.h>
// ...
#pragma once(现代编译器通用);若需最大兼容性用 #ifndef MODULE_H_ / #define MODULE_H_ / #endif 传统守卫。.h → 标准库 <stdint.h> <stdbool.h> 等 → 第三方库 → 本项目其他模块。空行分隔四组。#include,减少编译依赖。
// 头文件中:前向声明即可
typedef struct uart_s uart_t;
int uart_send(uart_t *u, const uint8_t *data, size_t len);
// .c 文件中再 include 完整定义
.c)需要的头文件不放进 .h。.h,内部辅助类型放 .c。extern 声明即可)、不定义 static 函数实现。.c 对应一个 .h,公开 .h,私有的 static 函数声明放 .c 顶部。enum:状态码、错误码、有限集合的离散值static const:只读常量数据(数组、结构体)#define:编译期常量、条件编译开关(#if/#ifdef)、版本号do { ... } while (0) 包装,避免 if/else 悬挂问题:
#define LOG_ERR(fmt, ...) do { \
if (g_log_level >= LOG_LVL_ERR) { printf("[ERR] " fmt "\n", ##__VA_ARGS__); } \
} while (0)
#define MAX(a, b) ((a) > (b) ? (a) : (b)) — 函数式宏必须标注多次求值风险(副作用参数如 MAX(i++, j) 会导致 bug)。#define private public)。do-while(0) 包装;多行宏对齐续行符 \。#if 而非 #ifdef 做特性开关(#if FEATURE_ENABLED 优于 #ifdef FEATURE_ENABLED,前者遗漏定义时报错而非静默跳过)。static inline 函数优于宏,利用类型检查和调试友好性。static 限制可见性,const 表达只读,enum 表示状态,避免取巧宏。stdlib-wrappers.md,是否已读取并遵守stdint.h fixed-width types、注意 endian、避免 compiler extension-Wall -Wextra,CI 加 static analysis(clang-tidy、cppcheck)_t 后缀、公开 API 模块前缀、宏全大写 + 模块前缀、私有函数 static* 靠变量名,单行 if 也加大括号。stdint.h / stdbool.h / stddef.h。_t 后缀(module_cfg_t),公开 API 统一模块前缀(module_init),宏全大写 + 模块前缀(MODULE_BUF_SIZE),私有函数 static 限制可见。-Wall -Wextra -Werror。-Wall -Wextra -Wshadow -Wundef -Wconversion -Wenum-conversion -Wmissing-prototypes -Wstrict-prototypes -Wcast-align。readability-*、bugprone-*、performance-* 规则集。test_<module>.c,放在 test/ 目录。mock 硬件依赖通过回调注入或链接期替换。当本 skill 被 ddev-gate 作为 C 代码审查子代理加载时(已吸收原 ddev-code-review 的代码质量审查职责),必须使用 reviewer-prompt.md 作为任务模板执行审查。该模板定义了审查输入、维度优先级、CodeGraph 辅助查询方法和输出格式。
审查覆盖范围:C 编码规范 + 代码质量(安全、架构性能、死代码/重复)。C 项目的 ddev-gate 流程中不再单独调用 ddev-code-review,由本 skill 统一完成。
当本 skill 被 ddev-exec 或 ddev-gate 工作流调用时,审查完成后须将结果写入项目根目录的 progress.md: