Reputation: 5290
sizeof
operand will evaluate the the operand if it is a variable-length array.
6.5.3.4, p2: If the type of the operand is a variable length array type, the operand is evaluated;
Yet this code is working, and I'm assuming it is defined:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
struct test
{
struct test* t;
int i;
};
int main(void)
{
int r = ( rand() % 100 ) + 1;
assert( r > 0 );
struct test* a[r];
for( size_t i = 0; i < r; i++ )
{
a[i] = NULL;
}
printf("%zu\n" , sizeof( a[0]->i ) );
//printf("%d\n", a[0]->i ); //this will of course crash the program
return 0;
}
sizeof
operand evaluated?printf
, given the context?The program seems to be correct with any amount of additional deferences:
struct other
{
int i;
};
struct test
{
struct other* t;
};
int main(void)
{
int r = ( rand() % 100 ) + 1;
assert( r > 0 );
struct test* a[r];
for( size_t i = 0; i < r; i++ )
{
a[i] = NULL;
}
printf("%zu\n" , sizeof( a[0]->t->i ) );
//printf("%d\n", a[0]->t->i ); //this will of course crash the program
return 0;
}
Upvotes: 2
Views: 203
Reputation: 78923
The operand of
sizeof a[0]->i
is not a VLA and is thus not evaluated. Neither would be
sizeof a[0]
only constructs like
sizeof a
need to evaluate its argument at runtime, because the size of that animal is not known at compile time.
Edit: Such an evaluation can be erroneous, of course. If you have
double (*p)[n];
so a pointer to a VLA. Then
sizeof *p
is a run time expression and erroneous if you didn't initialize p
properly.
Upvotes: 3
Reputation: 122383
a
itself is a VLA. However, a[0]->i
is not, its type is int
.
So sizeof( a[0]->i )
is simply sizeof(int)
. sizeof
here is a compile time operator, a[0]->i
is not evaluated, the code is defined.
Upvotes: 3