arrayscrecursionlanguage-lawyervariable-length-array

Is definition of variable length array (VLA) / known constant size recursive?


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:

Questions:

  1. Is definition of variable length array (VLA) / known constant size indeed recursive?
  2. If yes, then is it a defect in the standard?

In C2X (n3299.pdf) the quotes above a bit changed, but the issue remains.


Solution

  • 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.