| name | c23-legacy-code-fix |
| source | auto-skill |
| extracted_at | 2026-06-04T19:37:16.709Z |
| description | A systematic approach to fix C23/Clang warnings in legacy C code, including zero-length arrays, void pointer arithmetic, and flexible array members. |
Fixing C23/Clang Warnings in Legacy C Code
This skill documents the correct C23-standard replacement patterns for common GNU C extensions that Clang warns about under -Wpedantic, -Wvariadic-macros, -Wgnu-*, -Wextra-semi, -Wzero-length-array, etc. Do not suppress warnings via Makefile flags or _Pragma hacks — fix the root cause.
Replacement Patterns
1. Zero-size Arrays [0] → Flexible Array Members []
Warning: -Wzero-length-array
struct foo { int len; char data[0]; };
struct foo { int len; char data[]; };
Exception: Flexible array members inside a union are also a GNU extension (-Wgnu-flexible-array-union-member). For union members, use a single-element array [1] instead:
union { struct kmem_cache *memcg_caches[0]; struct { ... }; };
union { struct kmem_cache *memcg_caches[1]; struct { ... }; };
2. Void Pointer Arithmetic
Warning: -Wgnu-pointer-arith
void *p = ...;
p + offset;
(char *)p + offset;
unsigned long addr = (unsigned long)obj;
unsigned long base = (unsigned long)stack;
return (addr >= base) && (addr < base + THREAD_SIZE);
Important: When comparing pointers after casting one side, both sides must be the same type to avoid -Wcompare-distinct-pointer-types. Using unsigned long arithmetic is the safest pattern for kernel pointer comparisons.
3. Extra Semicolons
Warning: -Wextra-semi (outside function) or -Wextra-semi (inside struct)
- Outside function: Remove trailing
; after inline function definitions.
- Inside struct from macro: Remove trailing
; after macro invocations that expand to struct members.
4. Forward Enum Declarations
Warning: -Wpedantic (ISO C forbids forward references to enum types)
C23 does not allow forward-declared enums. Fix by either:
- Including the header that defines the enum fully (preferred)
- Removing the redundant forward declaration if the definition is already visible
5. Empty Structs
Warning: -Wgnu-empty-struct
When conditional compilation (#ifdef) can produce an empty struct, add a dummy field for the disabled case:
struct acpi_dev_node {
#ifdef CONFIG_ACPI
void *handle;
#else
char dummy_field;
#endif
};
6. GNU Array Range Initializer [0 ... N-1]
Warning: -Wgnu-designator
.flags = { [0 ... __DMA_ATTRS_LONGS-1] = 0 },
.flags = { 0 },
{ 0 } zero-initializes the entire array; the range syntax is unnecessary when all elements are zero.
7. Void Function Returning Void Expression
Warning: -Wpedantic
static inline void dma_free_writecombine(...) {
return dma_free_attrs(...);
}
static inline void dma_free_writecombine(...) {
dma_free_attrs(...);
}
8. Redeclared Enum
Warning: -Wgnu-redeclared-enum
Remove the redundant forward declaration if the full enum definition is already in scope via an include.
Process
- Categorize warnings from build output by type (zero-length arrays, void pointer arithmetic, extra semi, etc.)
- Find all affected files — grep for the pattern across the project
- Fix each category systematically using the replacement patterns above
- Watch for cascading issues — e.g., removing
##__VA_ARGS__ causes trailing comma; must use __VA_OPT__
- Verify by rebuilding — some fixes (like
__VA_OPT__) may reveal deeper usage patterns