What
gen-c lowers a fixed-size array parameter to a bare pointer:
fn fixed(a: [4]u8) -> u8 { return a[0]; }
uint8_t fixed(uint8_t* a);
The length is gone. A caller passing a two-element array compiles silently.
The other two backends keep it: gen-rust emits [u8; 4], gen-verilog/Zig
keep [4]u8. C is the one column that drops it -- the same cross-backend
divergence pattern as #3403 and #3423.
Measured, not assumed
The obvious spelling does not fix it. Apple clang 21, -Wall -Wextra,
passing a 2-element array where 4 are required:
| prototype |
diagnostic |
void f(uint64_t a[4]); |
(silence) |
void f(uint64_t a[static 4]); |
warning: array argument is too small; contains 2 elements, callee requires at least 4 [-Warray-bounds] |
A plain [N] parameter decays to a pointer and checks nothing. Only
[static N] carries the contract.
Population
Counted by the emitter itself, over all 651 specs (583 of which emit C):
- 51 parameters in 24 functions across 12 files.
Concentrated in specs/ternary/bitnet_* (28), specs/vsa/ops (9) and
specs/compiler/lexer (3).
Scope
This is a guard for future and out-of-repo callers -- compiling the generated
corpus today produces 0 -Warray-bounds, so it finds no existing defect.
Its value is that the next short call is rejected instead of accepted.
Constraints found while scoping
What
gen-clowers a fixed-size array parameter to a bare pointer:The length is gone. A caller passing a two-element array compiles silently.
The other two backends keep it:
gen-rustemits[u8; 4],gen-verilog/Zigkeep
[4]u8. C is the one column that drops it -- the same cross-backenddivergence pattern as #3403 and #3423.
Measured, not assumed
The obvious spelling does not fix it. Apple clang 21,
-Wall -Wextra,passing a 2-element array where 4 are required:
void f(uint64_t a[4]);void f(uint64_t a[static 4]);warning: array argument is too small; contains 2 elements, callee requires at least 4 [-Warray-bounds]A plain
[N]parameter decays to a pointer and checks nothing. Only[static N]carries the contract.Population
Counted by the emitter itself, over all 651 specs (583 of which emit C):
Concentrated in
specs/ternary/bitnet_*(28),specs/vsa/ops(9) andspecs/compiler/lexer(3).Scope
This is a guard for future and out-of-repo callers -- compiling the generated
corpus today produces 0
-Warray-bounds, so it finds no existing defect.Its value is that the next short call is rejected instead of accepted.
Constraints found while scoping
param_type_to_calso spells struct fields, where[static N]is asyntax error -- the fix has to be narrowed to parameter position, the same
narrowing the
*T->&mut Tlowering needed in fix(rust-backend): prefix the dereference, and give an out-pointer a safe type #3423.[static 0]is not valid C, so a[0]Tparameter must keep the pointer.#defines it earlier.