this
this

Reputation: 5290

sizeof evaluation of a variable-length array

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;
}
  1. Is the code defined?
  2. Is the sizeof operand evaluated?
  3. Shouldn't evaluation dereference the pointer?
  4. What is the difference between the first and second 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

Answers (2)

Jens Gustedt
Jens Gustedt

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

Yu Hao
Yu Hao

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

Related Questions