具有可变长度数组类型的Sizeof运算符

msc*_*msc 13 c gcc sizeof variable-length-array

根据cppreference:

如果表达式的类型是可变长度数组类型, 则计算表达式,并在运行时计算它计算的数组的大小.

这意味着:如果表达式的类型是VLA类型,则计算表达式.例如:

#include <stdio.h>

int main() {
    int i = 0;
    int a[i];
    printf("%zu\n",sizeof(a[i++]));
    printf("%d\n",i); // Here, print 0 instead of 1
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

所以,根据参考,这里i变成了1.但是,使用我的GCC编译器,i打印为0.

请参阅Wandbox演示.

Lun*_*din 19

首先,请注意,阵列的大小不能为零,无论是否为VLA.所以你的代码会调用未定义的行为.

C11 6.7.6.2/5

"如果大小是一个不是整数常量表达式的表达式:"/ - /"......每次计算它时,它的值应大于零."


至于实际问题,a[i++]是类型int,而不是VLA类型.

为了获得副作用,您必须参与VLA数组类型本身,例如sizeof(a).只有这样才能评估操作数的副作用.一个例子来说明这一点:

#include <stdio.h>

int main() {
    int i=1, j=1;
    int a[i][j];
    int b[1][1];

    (void) sizeof(a[--i]);
    (void) sizeof(b[--j]);
    printf("%d %d", i, j);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这里i结束了作为0,因为第一sizeof是由于VLA的评价,但j仍然保持为1,因为--j是的一部分sizeof为一个规则阵列.


Upr*_*ted 9

示例中sizeof的表达式是int,而不是vla.如果它是vla,那么一切都会起作用:

#include <stdio.h>

int main() {
    int i = 5;
    int a[i][i];
    printf("%zu\n",sizeof(a[--i]));
    printf("%d\n",i); // Here, print 4
    return 0;
}
Run Code Online (Sandbox Code Playgroud)