plugins/languages/c/skills/error/SKILL.md
C error-handling conventions: errno/perror/strerror_r usage, goto cleanup resource pattern, safe string operations (snprintf, strncpy + NUL terminator, memcpy with length checks), explicit error-code enums, [[nodiscard]] for critical returns, and integer overflow guards (size multiplication, INT_MAX limits). Use when designing error paths, propagating failures across layers, or hardening against silently-ignored returns. Triggers on "errno", "goto cleanup", "strcpy 替代", "snprintf", "整数溢出", "错误码设计", "defensive coding", "[[nodiscard]]".
npx skillsauth add lazygophers/ccplugin c-errorInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
goto cleanup 集中释放;free(NULL) 安全无需判空。errno 在可能被覆盖前保存到本地变量。strcpy / sprintf / strcat / gets;用 snprintf / strncpy + NUL / memcpy。snprintf 返回值需同时判断 < 0(编码错误)和 >= sizeof(dest)(截断)。[[nodiscard]](C23)或 __attribute__((warn_unused_result))。signal();信号注册一律 sigaction(细节见 c-posix)。FILE *f = fopen(path, "r");
if (!f) { perror("fopen"); return -1; }
// 保存 errno,因为后续清理可能覆盖
int saved = errno;
cleanup();
errno = saved;
// 线程安全
char buf[256];
strerror_r(errno, buf, sizeof buf);
fprintf(stderr, "fail: %s\n", buf);
goto cleanup 标准模板int process(const char *in_path, const char *out_path) {
int rc = -1;
FILE *in = NULL, *out = NULL;
char *buf = NULL;
if (!(in = fopen(in_path, "r"))) { perror("open in"); goto out; }
if (!(out = fopen(out_path, "w"))) { perror("open out"); goto out; }
if (!(buf = malloc(BUFSZ))) { perror("malloc"); goto out; }
size_t n;
while ((n = fread(buf, 1, BUFSZ, in)) > 0)
if (fwrite(buf, 1, n, out) != n) { perror("write"); goto out; }
if (ferror(in)) { perror("read"); goto out; }
rc = 0;
out:
free(buf);
if (out) fclose(out);
if (in) fclose(in);
return rc;
}
typedef enum {
ERR_OK = 0,
ERR_NULL_PTR = -1,
ERR_NO_MEM = -2,
ERR_INVALID_ARG = -3,
ERR_IO = -4,
ERR_OVERFLOW = -5,
} ErrorCode;
#if __STDC_VERSION__ >= 202311L
[[nodiscard]]
#else
__attribute__((warn_unused_result))
#endif
ErrorCode do_thing(const char *in, char *out, size_t cap);
char dst[64];
// snprintf — 同时判断错误与截断
int n = snprintf(dst, sizeof dst, "id=%d name=%s", id, name);
if (n < 0 || (size_t)n >= sizeof dst) return ERR_OVERFLOW;
// strncpy 必须手动补 NUL
strncpy(dst, src, sizeof dst - 1);
dst[sizeof dst - 1] = '\0';
// memcpy(已知精确长度时最快)
size_t len = strlen(src);
if (len >= sizeof dst) return ERR_OVERFLOW;
memcpy(dst, src, len + 1);
C11 Annex K(strcpy_s 等 _s 系列)仅可选实现,不可移植,不推荐。
#include <stdckdint.h> // C23:标准的 ckd_add/ckd_mul/ckd_sub
// C23
size_t total;
if (ckd_mul(&total, n, sizeof(T))) return ERR_OVERFLOW;
// 兼容写法
static inline bool safe_mul(size_t a, size_t b, size_t *r) {
if (a && b > SIZE_MAX / a) return false;
*r = a * b; return true;
}
// GCC/Clang 内置(已有 10+ 年)
size_t r;
if (__builtin_mul_overflow(n, sizeof(T), &r)) return ERR_OVERFLOW;
perror / strerror_r 出错点。(void) cast 必须有注释解释为何忽略。(void) + 注释)goto cleanupsnprintf 同时判断错误 + 截断ckd_* / __builtin_*_overflow / 手写守卫[[nodiscard]] 或 warn_unused_result<stdckdint.h> 草案 — https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3096.pdf__builtin_*_overflow — https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.htmlstrerror_r — https://pubs.opengroup.org/onlinepubs/9699919799/functions/strerror.htmltools
UI/UX 与布局设计——做界面布局/结构/导航/组件/交互的设计决策。触发:做UI/UX/布局/排版/导航/组件/交互/栅格/响应式/图表选型/字体配对。按媒介路由 HTML/Web、原生 App(iOS/Android/桌面)、CLI、TUI。需后端动态系统不适用;配色/主题/色板走姊妹 skill design-color。
tools
主题与配色设计——做颜色搭配/调色板/主题/品牌色阶/暗模式的设计决策。触发:选配色/调色/主题/色板/品牌色/暗模式/对比度/色盲/UI风格。按媒介路由 HTML/Web(CSS变量)、原生App(平台token)、CLI(ANSI)、TUI(真彩/256/16降级)。保证可访问性(对比度/色盲安全)。需后端动态系统不适用;UI/UX 布局/组件/交互走姊妹 skill design-uiux。
tools
跨任意组件(plugin/skill/agent/command)的验证驱动优化循环纪律 skill。当用户要优化某个已有组件却无明确方向、或要防止改了反而更差(自评乐观偏差 / 多维同改归因失效 / 为凑分加废话膨胀)、或要把一套通用「评分→单变量改→改后验证严格更好才留否则回滚→触顶停」的纪律套到任意组件上时使用。管优化过程本身的纪律(validation gate / ratchet / 独立验证 / 触顶停),不评单组件深度(交 skill-dev),不查插件接线(交 plugin-dev)。仅手动 /optimize-any 触发。
data-ai
两层规则记忆 (基于 .skein/spec)。planning 时 recall 召回相关规则、task finish 后 sediment 沉淀学习 + prune 自动精简过期/重复/断链规则。core 常驻硬规 + recall 按需召回, 经判定门自动写盘 (不逐次问用户)。产出 .skein/spec 下 core/recall 规则文件 + index。另支持空仓 bootstrap 播种规则基线、记忆大面积失效 (大重构/换栈) 时 reconstruct 可逆归档后按项目类型分型重建、maintain 手动体检 (超预算/stale/断链/重复/废弃, --apply 自动修复)、auto-fix (Stop hook 写 .pending-fix 标记 → main 派 skein-specer bg 跑 maintain --apply 全自动修, 断链只报告)。