arraysclanguage-lawyervariable-length-array

What is the type of `1 ? 0 : (int(*)[f()])0`?


Probably, there is a contradiction is the C standard for VM types used in conditional operator. Assume:

int f(void) { return 42; }

Now, what is the type of a following expression?

1 ? 0 : (int(*)[f()]) 0

It's value must be equal to NULL but I am not sure what is the type. The int(*)[f()] is a pointer to VLA of size f(). However, to complete this VM type the size expression f() must be evaluated. The problem is that it belong to a branch of ternary operator which is not evaluated. From 6.5.15p4:

The second operand is evaluated only if the first compares unequal to 0; the third operand is evaluated only if the first compares equal to 0

Rules of the conditional operator require the combination of 0 pointer be the type of the other branch 6.5.15p6:

... if one operand is a null pointer constant, the result has the type of the other operand; ...

How to solve this contradiction? Possible solutions are:

The rules of composite type suggest that this may be UB but I am not sure if those rules apply for this case. I look for an answer that cites the specification of C17 but wording from upcoming C2X is fine as well.


Solution

  • It looks that it is Undefined behavior.

    The similar question was asked to C standardization committee in Defect Report: VLAs and conditional expressions. The question was about following code:

    int r = (c1()
                   ? (z1(), (int (*)[d1()])p1())
                   : (z2(), (int (*)[])p2()))[a][b];
    

    asking:

    The type of the conditional expression involves the size expression d1() that's only evaluated in one part of the expression, and this information is needed to evaluate the array reference even when c1() returns false.

    To my understanding, dereferencing (...)[a][b] requires the type of conditional expression which requires evaluation of d1() even though it does not come from the evaluated branch.

    The answer from the committee can be found in minutes from London 2007 meeting, page 21 saying:

    There are no rules for specifying a composite type when it depends on an expression and the expression is not evaluated. The proposal makes an implicitly undefined behavior explicitly undefined.

    General consensus is that implicitly undefined is satisfactory, and we should issue an RR stating this (therefore making it explicit but only in an external document).

    Proposed Committee Response: The standard does not speak to this issue, and as such the behavior is undefined.