Clang compiles this C function:
struct foo {
char member[];
};
long test(struct foo zst, long t, long u, long v, long w, long x, long y,
long z) {
return z;
}
To this assembly code on x86-64 Linux (Godbolt):
test:
mov rax, qword ptr [rsp + 16]
ret
In the LLVM IR, struct foo zst is passed by pointer, despite being zero-sized.
In contrast, GCC emits:
test:
mov rax, qword ptr [rsp + 8]
ret
GCC's assembly for this function matches what both GCC and clang emit for this:
struct foo {
char member[0];
};
long test(struct foo zst, long t, long u, long v, long w, long x, long y,
long z) {
return z;
}
The same issue exists for unions.
This is inconvenient for Rust, where it is common practice to map both C flexible array members and C zero-length array members to the same Rust construct (a zero-length Rust array).
Clang compiles this C function:
To this assembly code on x86-64 Linux (Godbolt):
In the LLVM IR,
struct foo zstis passed by pointer, despite being zero-sized.In contrast, GCC emits:
GCC's assembly for this function matches what both GCC and clang emit for this:
The same issue exists for
unions.This is inconvenient for Rust, where it is common practice to map both C flexible array members and C zero-length array members to the same Rust construct (a zero-length Rust array).