可变长度数组的{size}评估

时间:2015-08-19 06:42:35

标签: c language-lawyer c99 c11 variable-length-array

sizeof操作数将评估操作数是否为可变长度数组。

  

6.5.3.4,p2:如果操作数的类型是可变长度数组类型,则计算操作数;

然而,这段代码正在运作,我假设它已定义:

#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. 是否定义了代码?
  2. 是否评估了sizeof操作数?
  3. 不应该评估取消引用指针吗?
  4. 鉴于上下文,第一个和第二个printf之间有什么区别?
  5. 该计划似乎是正确的任何额外的差异:

    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;
    }
    

2 个答案:

答案 0 :(得分:3)

a本身就是VLA。但是,a[0]->i不是,其类型为int

所以sizeof( a[0]->i )只是sizeof(int)sizeof这里是编译时运算符,未评估a[0]->i,代码已定义。

答案 1 :(得分:2)

的操作数
sizeof a[0]->i

不是VLA,因此不予评估。

也不会
sizeof a[0]

只有像

这样的结构
sizeof a

需要在运行时评估其参数,因为在编译时不知道该动物的大小。

编辑:当然,这样的评估可能是错误的。如果你有

double (*p)[n];

所以指向VLA的指针。然后

sizeof *p
如果没有正确初始化p

是一个运行时表达式并且是错误的。