sizeof(数组)如何在运行时工作?

我已经读过C中的sizeof运算符在编译时被解释,因为在编译时编译器知道数组大小及其类型,sizeof能够计算array占用的字节数。但是sizeof如何处理以下代码:

#include #include int main() { int n; scanf("%d",&n); int a[n]; int s=sizeof(a); printf("%d",s); return 0; } 

这里的数组大小在编译时是不知道的,那么它是如何正常工作的?

sizeof始终在C89的编译时计算。 由于C99和可变长度数组,它是在运行时计算的,当可变长度数组是sizeof操作数中表达式的一部分时。

对于操作数sizeof的评估也是如此:它不在C89中计算,但在C99中,如果操作数是可变长度数组类型,则计算它。 例如:

 int n = 5; sizeof (int [n++]); // n is now 6 

由于您将sizeof应用于可变长度数组,其大小在编译时未完全知晓,因此编译器必须生成代码以在运行时执行其中的一部分。

gcc 4.6.3的高级优化器将您展示的代码转换为

 scanf ("%d", &n); t12 = (long unsigned int) n; t13 = t12 * 4; __builtin_alloca (t13); t16 = (unsigned int) t12; t17 = t16 * 4; s18 = (int) t17; printf ("%d", s18); 

这能解释引擎盖下的情况吗? (不要被看似愚蠢的临时变量数量所拖延 – 这是我要求中间代码转储的程序中的静态单一赋值forms的工件。)

从C99标准:

6.5.3.4

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

我已经读过C中的sizeof运算符在编译时被解释

除了VLA之外,在所有情况下都在编译时确定sizeof 。 对于VLA,在运行时评估sizeof

在这种情况下,在运行时评估sizeof() 。 编译器,因为它知道a的大小是基于数组声明时的n的值,生成代码以使用适当的n值来返回sizeof()的合理值。

在C99中,并非所有sizeof()都可以在编译时完全评估并减少到运行时常量。

无论sizeof是在编译时还是运行时计算(或者更正式地说,它的结果是否是整数常量表达式), sizeof的结果纯粹基于其参数类型而不是任何伴随变量长度的隐藏数据数组本身。 当然,当sizeof应用于可变修改类型时,生成的程序必须在某处跟踪该大小。 但是如果表达式足够简单并且它最初导出长度的变量不能改变,它可能只是重新计算它。 或者,它可以在某处存储类型的大小(主要是在隐藏的局部变量中),但是这不会以任何可观察的方式连接到VLA对象(例如,如果您将指针传递给VLA的第一个元素)到另一个函数,该指针不能用于恢复VLA长度)。