When you pass a non-integer constant expression as x ("string_literal"[0]
doesn't qualify as an integer constant expression as C defines it), the macro will create a VLA. While it is undefined behavior for VLA sizes to be negative upon VLA creation, this is not guaranteed to be diagnosed at compile time and it is also completely fine if such a invalidly-sized VLA happens in a dead branch (i.e., when the size expression isn't evaluated)
if (0){ int x = -1; char vla[x]; } //ok
if (0){ char nonvla[-1]; } //reliable compiletime error
Better _Static_assert
emulations rely on bitfield sizes:
#define STATIC_ASSERT(x) sizeof(struct{ int _:((x)?1:-1); })
where there's no variable-width version and and non-integer constant expression are simply forbidden. The above will reliably fail at compile time whenever x
is either 0
or something that's not an integer constant expression. C11's _Static_assert
also behaves like that.