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

时间:2012-04-09 19:02:28

标签: c sizeof

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

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

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

6 个答案:

答案 0 :(得分:27)

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

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

int n = 5;
sizeof (int [n++]); 

// n is now 6

答案 1 :(得分:14)

由于您将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);

这能解释引擎盖下的情况吗? (不要被看似愚蠢的临时变量数量所拖延 - 这是我要求中间代码转储时程序的static single assignment形式的工件。)

答案 2 :(得分:7)

来自C99标准:

6.5.3.4

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

答案 3 :(得分:2)

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

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

答案 4 :(得分:2)

  

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

除了VLA之外,在所有情况下都在编译时确定

sizeof。对于VLA,sizeof在运行时进行评估。

答案 5 :(得分:1)

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