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;
}
sizeof
操作数?printf
之间有什么区别?该计划似乎是正确的任何额外的差异:
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;
}
答案 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
,是一个运行时表达式并且是错误的。