具有可变长度数组类型的Sizeof运算符 [英] Sizeof operator with variable-length array type

查看:211
本文介绍了具有可变长度数组类型的Sizeof运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 cppreference


如果表达式的类型是可变长度数组类型,则 表达式
被评估为
,其运行时计算的数组大小为

这意味着:如果表达式的类型是VLA类型,则评估表达式。例如:

  #include< stdio.h> 

int main(){
int i = 0;
int a [i];
printf(%zu\\\
,sizeof(a [i ++]));
printf(%d \\\
,i); //在这里,打印0而不是1
return 0;





$ b因此,根据参考文献,这里 i 变成 1 。但是,使用我的GCC编译器, i 打印为 0



请参阅 Wandbox演示

解决方案

首先,请注意数组的大小不能为零,无论它是否为VLA。所以你的代码调用未定义的行为。



C11 6.7.6.2/5


如果size是一个不是整型常量表达式的表达式:/ - /...每次评估它的值都应该大于零。







至于实际的问题, a [i ++] code> 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);

返回0;
}

这里 i 结束因为第一个 sizeof 因VLA而被评估,但 j 仍然为1,因为 - j 是普通数组 sizeof 的一部分。


According to cppreference:

If the type of expression is a variable-length array type, expression is evaluated and the size of the array it evaluates to is calculated at run time.

It means: if the type of expression is a VLA type, then expression is evaluated. For example:

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

So, according to the reference, here i becomes 1. But, with my GCC compiler, i prints as 0.

See Wandbox Demo.

解决方案

First of all, please note that an array cannot have size zero, be it a VLA or not. So your code invokes undefined behavior.

C11 6.7.6.2/5

"If the size is an expression that is not an integer constant expression:" /--/ "...each time it is evaluated it shall have a value greater than zero."


As for the actual problem, a[i++] is of type int, not of VLA type.

In order to get the side-effect, you must involve the VLA array type itself, such as sizeof(a). Only then is the operand evaluated for side effects. One example to illustrate this:

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

Here i ends up as 0 since the first sizeof is evaluated because of the VLA, but j remains 1 because --j was part of a sizeof for a regular array.

这篇关于具有可变长度数组类型的Sizeof运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆