【问题标题】:Behavior of sizeof on variable length arrays (C only)sizeof 在可变长度数组上的行为(仅限 C)
【发布时间】:2013-02-06 09:35:45
【问题描述】:

我的问题是当传递的参数是 动态数组 可变长度数组时,sizeof() 的行为究竟如何。

让我们考虑一个例子:

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

    /* Do something*/

    return sizeof(name_arr);
}

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

引用 C99 标准 (6.5.3.4):

sizeof 运算符产生其操作数的大小(以字节为单位),可能是 表达式或类型的括号名称。大小由 操作数的类型。结果是一个整数。如果操作数的类型是 变长数组类型,对操作数求值;否则,操作数是 未计算,结果是一个整数常量。

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

我的理解对吗?

【问题讨论】:

  • sizeof() 仍然是运算符;当参数是可变长度数组时,它不再生成编译时常量。
  • 你的代码能编译吗?我收到 variable-sized object may not be initialized 错误

标签: c sizeof


【解决方案1】:

它仍然充当运算符。 Cast 也是运算符并且还评估它的参数,*& 也是如此。作为一个操作符是一个句法范畴。这不会改变。

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


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

int a[x];
sizeof(a)

在这种情况下,评估a 确实没有区别。但您也可以使用 type 作为参数,即

sizeof(int[x])

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

【讨论】:

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

我的问题是当传递的参数是动态数组时 sizeof() 的行为究竟如何。

  1. 好吧,您的意思是“可变长度数组”(VLA)。

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

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

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

【讨论】:

  • 因为有些人在这里受挫。
猜你喜欢
  • 2015-11-12
  • 1970-01-01
  • 2018-07-17
  • 2015-12-18
  • 2014-07-27
  • 2019-01-10
  • 2018-03-10
  • 2021-07-11
相关资源
最近更新 更多