An argument in the comments section of this answer prompted me to ask this question.
In the following code, bar
points to a variable length array, so the sizeof
is determined at runtime instead of compile time.
int foo = 100;
double (*bar)[foo];
The argument was about whether or not using sizeof
evaluates its operand when the operand is a variable length array, making sizeof(*bar)
undefined behavior when bar
is not initialized.
Is it undefined behavior to use sizeof(*bar)
because I'm dereferencing an uninitialized pointer? Is the operand of sizeof
actually evaluated when the type is a variable length array, or does it just determine its type (how sizeof
usually works)?
Edit: Everyone seems to be quoting this passage from the C11 draft. Does anyone know if this is the wording in the official standard?
Yes, this causes undefined behaviour.
In N1570 6.5.3.4/2 we have:
The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.
Now we have the question: is the type of *bar
a variable length array type?
Since bar
is declared as pointer to VLA, dereferencing it should yield a VLA. (But I do not see concrete text specifying whether or not it does).
Note: Further discussion could be had here, perhaps it could be argued that *bar
has type double[100]
which is not a VLA.
Supposing we agree that the type of *bar
is actually a VLA type, then in sizeof *bar
, the expression *bar
is evaluated.
bar
is indeterminate at this point. Now looking at 6.3.2.1/1:
if an lvalue does not designate an object when it is evaluated, the behavior is undefined
Since bar
does not point to an object (by virtue of being indeterminate), evaluating *bar
causes undefined behaviour.