Is the following code:
#include <stdio.h>
void case1(int array[][printf("hello ")][printf("world ")]) {}
int i = 0;
void case2(int array[][i++][i++]) {}
int main(void) {
case1(0);
case2(0);
printf("%d\n", i);
}
supposed to:
world hello 2
like on gcc14.2.1 ?hello world 2
like on clang18.1.8 ?Are the evaluation of VLA dimensions sizes unsequenced, indeterminably-sequenced, with some sequence? Is there a sequence point?
I tried reading https://port70.net/~nsz/c/c11/n1570.html , https://port70.net/~nsz/c/c23/n3220.pdf , https://en.cppreference.com/w/c/language/eval_order and https://en.cppreference.com/w/c/language/array but found nothing relevant.
Here are some relevant paragraphs from the C Standard (C23):
6.5.2.2 Function calls
[...]
- There is a sequence point after the evaluations of the function designator and the actual arguments but before the actual call. Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function.
6.8 Statements and blocks
[...]
Semantics
[...]
- A full expression is an expression that is not part of another expression, nor part of a declarator or abstract declarator. There is also an implicit full expression in which the non-constant size expressions for a variably modified type are evaluated; within that full expression, the evaluation of different size expressions are unsequenced with respect to one another. There is a sequence point between the evaluation of a full expression and the evaluation of the next full expression to be evaluated.
This seems to imply the following responses to your questions:
Are the evaluation of VLA dimensions sizes unsequenced, indeterminably-sequenced, with some sequence?
As explicitly stated in the above paragraph, the evaluation of the VLA dimensions sizes are unsequenced with respect to one another.
Is there a sequence point?
No there does not seem to be a sequence point, at least not according to the quoted paragraph: there is an implicit full expression in the type definition, but the VLA dimensions are just expressions within this full expression so the last phrase there is a sequence point between the evaluation of a full expression and the evaluation of the next full expression to be evaluated does not apply. There does not seem to be much space for interpretation in this context: void case2(int array[][i++][i++]) {}
seems to invoke undefined behavior when the function is called, just like printf("%d\n", i++ * i++)
would.
Note however that there is a sequence point between the evaluation of printf("hello ")
and printf("world ")
in the call to case1(0)
, which makes them indeterminately sequenced rather than unsequenced.
Is the code supposed to:
world hello 2
like on gcc14.2.1 ?
This behavior is not guaranteed but possible for the world hello
part, but undefined behavior is invoked when case2
is called.
hello world 2
like on clang18.1.8 ?
Same answer: This behavior is possible for the hello world
part, but undefined behavior is invoked when case2
is called.
- be implementation defined behavior? for
case1
? forcase2
?- be undefined behavior? for
case1
? forcase2
?
for case1
as the evaluation of both printf
statements is unsequenced: it is possible for conforming implementations to exhibit different behavior (as observed) but it is also possible for a given conforming implementation to exhibit different behavior on different runs!
The output is unpredictable, so the behavior is not strictly implementation defined, yet it does not seem to fit the definition of undefined behavior per the C Standard.
Note that the second and third array dimensions for the array
argument of function case1
would be defined as 6
in all cases.
for case2
, the behavior is undefined because i
is modified and read twice within the same full expression without a sequence point.
Note that at least one of the dimensions of the array
argument would evaluate to 0
, which would also invoke undefined behavior.
The language of the C Standard paragraph quoted above was the same in C17 but was less specific in previous editions of the C Standard: the phrase about the expressions defining the VLA dimensions being unsequenced was missing.