Issue: definition of variable length array (VLA) / known constant size seems to be recursive.
C11, 6.2.5 Types, 23 (emphases added):
A type has known constant size if the type is not incomplete and is not a variable length array type.
C11, 6.7.6.2 Array declarators, 4 (emphases added):
If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type.
These quotes can be pseudo-coded as:
is_KCS(T) = !is_INCOMPL(T) && !is_VLA(T)
is_VLA(T) = !(is_ICE(S(T)) && is_KCS(ET(T)))
Here we see that:
is_VLA
depends on is_KCS
, which depends on is_VLA
(and so on)is_KCS
depends on is_VLA
, which depends on is_KCS
(and so on)Questions:
In C2X (n3299.pdf) the quotes above a bit changed, but the issue remains.
Sure, it's recursive. No, it's not a problem, because the recursion terminates.
First of all, there's an implicit check you're missing (since S(T)
is only defined for arrays):
is_KCS(T) = !is_INCOMPL(T) && !is_VLA(T);
is_VLA(T) = !( isARRAY(T) && is_ICE(S(T)) && is_KCS(ET(T)) );
With this change, you'll reach a type that isn't an array type, a type that's an array type without an integer constant expression for size, or an incomplete type.
Not only is it not a defect, it's necessary. Take a look at the following example:
typedef int ET[n];
ET a[4];
aka
int a[4][n];
Is a
a VLA? Yes, because its element type (ET
/int [n]
) is a VLA type. To determine if a
is a VLA, we needed to (recursively) check if ET
/int [n]
is a VLA type.