简体   繁体   English

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

[英]How sizeof(array) works at runtime?

I have read that sizeof operator in C is interpreted at compile time and since at compile time compiler knows the array size and its type,sizeof is abled to compute the number of bytes occupied by array.But how is sizeof working for the following code:我读过 C 中的 sizeof 运算符是在编译时解释的,因为在编译时编译器知道数组大小及其类型,sizeof 能够计算数组占用的字节数。但是 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;
 }

Here array size is not known at compile time,then how is it working properly?这里的数组大小在编译时是未知的,那么它是如何正常工作的呢?

sizeof is always computed at compile time in C89.在 C89 中, sizeof总是在编译时计算。 Since C99 and variable length arrays, it is computed at run time when a variable length array is part of the expression in the sizeof operand.自 C99 和可变长度 arrays 起,当可变长度数组是sizeof操作数中表达式的一部分时,它是在运行时计算的。

Same for the evaluation of the sizeof operand: it is not evaluated in C89 but in C99 if the operand is of variable length array type it is evaluated.sizeof操作数的求值也是如此:它在 C89 中不被求值,但在 C99 中如果操作数是可变长度数组类型,它就会被求值。 For example:例如:

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

// n is now 6

Since you are applying sizeof to a variable-length array, whose size is not fully known at compile time, the compiler must generate code to do part of it at runtime.由于您将sizeof应用于可变长度数组,其大小在编译时并不完全已知,因此编译器必须生成代码以在运行时执行其中的一部分。

gcc 4.6.3's high level optimizers convert the code you showed to 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);

Does that explain what is going on under the hood?这是否解释了幕后发生的事情? (Don't be put off by the silly-looking number of temporary variables -- that's an artifact of the program being in static single assignment form at the point where I asked for an intermediate-code dump.) (不要被看起来很傻的临时变量数量吓倒了——这是在我要求中间代码转储时以static 单赋值形式出现的程序的产物。)

From the C99 standard:从 C99 标准:

6.5.3.4 6.5.3.4

The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. sizeof运算符产生其操作数的大小(以字节为单位),它可以是表达式或类型的括号名称。 The size is determined from the type of the operand.大小由操作数的类型决定。 The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated ;结果是 integer。如果操作数的类型是可变长度数组类型,则计算操作数 otherwise, the operand is not evaluated and the result is an integer constant.否则,不计算操作数,结果为 integer 常量。

In that case, sizeof() is evaluated at run time.在这种情况下, sizeof()在运行时进行计算。 The compiler, because it knows that the size of a is based on the value of n at the time of the array declaration, generates code to use the appropriate value of n to return a sensible value for sizeof() .编译器,因为它知道a的大小基于数组声明时n的值,所以生成代码以使用n的适当值来为sizeof()返回一个合理的值。

In C99, not all uses of sizeof() can be completely evaluated at compile time and reduced to a runtime constant.在 C99 中,并非所有sizeof()的使用都可以在编译时完全评估并减少为运行时常量。

I have read that sizeof operator in C is interpreted at compile time我读过 C 中的 sizeof 运算符在编译时被解释

sizeof is determined at compile time in all cases apart from for VLAs.除了 VLA 之外,所有情况下sizeof都是在编译时确定的。 For a VLA, sizeof is evaluated at runtime.对于 VLA, sizeof在运行时计算。

Regardless of whether sizeof is computed at compile time or runtime (or more formally speaking, whether its result is an integer constant expression), the result of sizeof is purely based on the type of its argument and not any hidden data accompanying the variable-length array itself.不管sizeof是在编译时还是运行时计算的(或者更正式地说,它的结果是否是一个 integer 常量表达式), sizeof的结果完全基于其参数的类型,而不是任何伴随可变长度的隐藏数据数组本身。 Of course when sizeof is applied to a variably-modified type, the generated program must keep track of that size somewhere.当然,当sizeof应用于可变修改类型时,生成的程序必须在某处跟踪该大小。 But it might simply recompute it if the expression was simple enough and the variables it originally derived the length from cannot have changed.但如果表达式足够简单并且它最初从中导出长度的变量不能改变,它可能会简单地重新计算它。 Or, it could store the size of the type somewhere (essentially in a hidden local variable), but this would not be connected to the VLA object in any observable way (for example, if you pass a pointer to the first element of the VLA to another function, that pointer cannot be used to recover the VLA length).或者,它可以将类型的大小存储在某处(基本上在隐藏的局部变量中),但这不会以任何可观察的方式连接到 VLA object(例如,如果您将指针传递给 VLA 的第一个元素到另一个 function,该指针不能用于恢复 VLA 长度)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM