bundled-skills/super-code/c/SKILL.md
Language-specific super-code guidelines for c.
npx skillsauth add FrancoStino/opencode-skills-antigravity cInstall 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.
// ❌ malloc without checking return value
char *buf = malloc(size);
strcpy(buf, src);
// ✅
char *buf = malloc(size);
if (!buf) return -ENOMEM;
memcpy(buf, src, size);
// ❌ Casting malloc result (unnecessary in C, hides missing #include)
int *p = (int *)malloc(n * sizeof(int));
// ✅
int *p = malloc(n * sizeof *p);
// ❌ free without nulling (dangling pointer risk in long-lived scope)
free(ptr);
// ... later code might use ptr
// ✅
free(ptr);
ptr = NULL;
// ❌ Forgetting to free on early-return paths
char *a = malloc(100);
char *b = malloc(200);
if (!b) return -1; // leaks a
// ✅ — single cleanup label
char *a = NULL, *b = NULL;
a = malloc(100);
if (!a) goto cleanup;
b = malloc(200);
if (!b) goto cleanup;
// ... use a, b ...
cleanup:
free(b);
free(a);
Use sizeof *ptr instead of sizeof(Type) — it stays correct when the type changes.
// ❌ Manual array size tracking
void process(int *arr, int len) { ... }
process(data, 10);
// ✅ — pass size alongside pointer, or use a struct
typedef struct { int *data; size_t len; } IntSlice;
// ❌ Pointer arithmetic where array indexing is clearer
*(arr + i) = value;
// ✅
arr[i] = value;
// ❌ VLA in production code (stack overflow risk, optional in C11+)
int arr[n];
// ✅
int *arr = malloc(n * sizeof *arr);
if (!arr) return -ENOMEM;
// ... use arr ...
free(arr);
// ❌ Using magic numbers for error returns
if (do_thing() == -1) { ... }
// ✅ — define or use named error codes
#include <errno.h>
if (do_thing() < 0) {
perror("do_thing");
return errno;
}
// ❌ Deeply nested error checks
int r1 = step1();
if (r1 == 0) {
int r2 = step2();
if (r2 == 0) {
int r3 = step3();
// ...
}
}
// ✅ — early return / goto cleanup
if (step1() < 0) goto fail;
if (step2() < 0) goto fail;
if (step3() < 0) goto fail;
return 0;
fail:
cleanup();
return -1;
goto cleanup is idiomatic C for resource teardown — don't avoid it out of principle.
// ❌ strcpy without bounds checking
strcpy(dest, src);
// ✅
strncpy(dest, src, sizeof(dest) - 1);
dest[sizeof(dest) - 1] = '\0';
// or better: snprintf(dest, sizeof(dest), "%s", src);
// ❌ strcmp misuse
if (str == "hello") { ... } // compares pointers, not content
// ✅
if (strcmp(str, "hello") == 0) { ... }
// ❌ Building strings with repeated strcat (O(n²))
char result[1024] = "";
for (int i = 0; i < n; i++) {
strcat(result, items[i]);
}
// ✅ — track write position
char result[1024];
int pos = 0;
for (int i = 0; i < n && pos < (int)sizeof(result); i++) {
pos += snprintf(result + pos, sizeof(result) - pos, "%s", items[i]);
}
Prefer snprintf over sprintf — always.
// ❌ Bare struct requiring `struct` keyword everywhere
struct point { int x, y; };
struct point p = {1, 2};
// ✅
typedef struct { int x, y; } Point;
Point p = {1, 2};
// ❌ Uninitialized struct
Point p;
use(p.x); // UB
// ✅
Point p = {0};
// ❌ Magic integer constants
if (state == 3) { ... }
// ✅
typedef enum { STATE_IDLE, STATE_RUNNING, STATE_DONE } State;
if (state == STATE_DONE) { ... }
// ❌ Macro where inline function works (no type safety, double eval)
#define MAX(a, b) ((a) > (b) ? (a) : (b))
MAX(x++, y) // x incremented twice if x > y
// ✅
static inline int max_int(int a, int b) { return a > b ? a : b; }
// ❌ No include guard
// my_header.h
struct Foo { int x; };
// ✅
#ifndef MY_HEADER_H
#define MY_HEADER_H
struct Foo { int x; };
#endif
// or: #pragma once (widely supported, not standard)
Keep macros for conditional compilation and constants. Use static inline for logic.
| Anti-pattern | Preferred |
|---|---|
| sprintf | snprintf with buffer size |
| gets | fgets (gets is removed in C11) |
| Casting malloc result | let implicit void* conversion work |
| sizeof(Type) in malloc | sizeof *ptr |
| VLA for large/runtime arrays | heap allocation |
| void* callbacks without context param | pass void *ctx alongside function pointer |
| Global mutable state | pass state through struct pointers |
| assert for runtime error handling | proper error return codes |
| Missing const on read-only pointer params | const char *str |
| Mixing signed/unsigned in comparisons | use consistent types, cast explicitly |
data-ai
Snapshot a site's SEO state and detect ranking, indexation, metadata, canonical, robots, schema, and on-page regressions over time.
development
Coordinate focused subagents on substantial work, keep their ownership non-overlapping, and integrate verified results. Use for large-scope Codex tasks; keep trivial work with the coordinator.
data-ai
Use when an owner asks to find a cofounder or project partner. Assess only that agent's own owner and rank only approved profiles other agents posted for their own owners.
devops
Install, configure, verify, repair, update, and uninstall Hyprland on Fedora Linux with GPU-aware detection (NVIDIA/AMD/Intel).