sizeof在可变长度数组上的行为(仅限C)

CCo*_*der 15 c sizeof

我的问题是sizeof()当传递参数是一个动态数组变量长度数组时,究竟如何表现.

我们来看一个例子:

int fun(int num_of_chars)
{
    char name_arr[num_of_chars] = {0};

    /* Do something*/

    return sizeof(name_arr);
}
Run Code Online (Sandbox Code Playgroud)

在这个例子中,很明显返回值不是编译时常量.因为大小取决于运行时的值num_of_chars.

引用C99标准(6.5.3.4):

sizeof操作者产生其操作数的大小(以字节为单位),其可以是表达或类型的括号名称.大小由操作数的类型确定.结果是整数.如果操作数的类型是可变长度数组类型,则计算操作数; 否则,不评估操作数,结果是整数常量.

我从[....操作数被评估....]中可以理解的是,当传递的参数sizeof()动态数组变量长度数组时,sizeof()'表现得像'一个函数而不是一个运算符.

我的理解是对的吗?

Jan*_*dec 8

它仍然表现为运营商.Cast也是运算符,也会评估它的参数,*或者也是&.作为运算符是句法类别.这不会改变.

重要的区别在于它表现为表达式,而在其他情况下它表现为常量.


更新:我在下面评论说我不明白为什么评估有所不同,但现在我意识到有两种方法可以用可变长度数组编写sizeof.您可以传递声明为变量lenght数组的变量:

int a[x];
sizeof(a)
Run Code Online (Sandbox Code Playgroud)

在这种情况下,评估a确实没有区别.但是你也可以使用一个类型作为参数

sizeof(int[x])
Run Code Online (Sandbox Code Playgroud)

并且在这种情况下,结果是x * sizeof(int)x必须进行评估.我想这就是规范提到它的原因.

  • @H2CO3:请阅读问题。它引用标准说如果操作数是可变长度数组,则对其进行评估。也就是说,C99 中可变长度数组类型的唯一表达式是如此声明的变量和评估没有可观察到的效果,所以我不确定为什么要区分(C++ 是另一回事,但即使 C++11 也不包括这个特征)。 (2认同)
  • @H2CO3:事实上,我现在意识到,当您将可变长度数组 _type_ 传递给 `sizeof` 时,该表达式会被评估,并且可能会产生可观察到的副作用。更新了答案。 (2认同)
  • 如果“sizeof”下的表达式有副作用,则求值可能会产生任意巨大的差异。像`int a[x][x], i = 0; a[i++] 的大小;`。变量“i”应该递增。 (2认同)

小智 5

我的问题是当传递的参数是一个动态数组时,sizeof()的行为是多少.

  1. 嗯,你宁可意味着一个"可变长度阵列"(VLA).

  2. 它的行为几乎完全相同:它以字节为单位返回数组的大小.

sizeof()'表现得像'一个函数,而不是一个运算符.

不,它从来都不是一个功能.唯一改变的是,如果在VLA上使用,则此运算符不会产生编译时常量,否则会产生.