[英]evaluation of operand in sizeof operator
As sizeof operator evaluates operand if it's a VLA so I tried to test it as : 由于sizeof运算符会评估操作数(如果它是VLA),因此我尝试将其测试为:
#include<stdio.h>
int main(void)
{
int sz=20,i=0,j=0;
int arr[sz];
printf("%d\n",sizeof((++i,sz)));
printf("%d\n",sizeof((++j,arr)));
printf("%d\n%d\n",i,j);
}
I thought that i won't increment as sz is not VLA but j would increment as arr is VLA. 我以为我不会增加,因为sz不是VLA,但j会增加,因为arr是VLA。
But in the output, none of the i and j incremented. 但是在输出中,i和j都不增加。
Quoting my answer to another question : 引用我对另一个问题的回答 :
The "conversion" is due to the subtraction operator. “转换”归因于减法运算符。 You can see a similar, and perhaps more surprising, result with the comma operator: 使用逗号运算符可以看到类似的结果,也许更令人惊讶:
printf("%zu\\n", sizeof(1, a));
will also print
sizeof(int *)
, because of the comma operator resulting in a getting used in a value context. 也将打印sizeof(int *)
,因为逗号运算符导致在值上下文中使用它。
Basically, due to the comma operator, the type of arr
is a pointer, and the size of the VLA doesn't come into the picture. 基本上,由于逗号运算符的缘故, arr
的类型是指针,并且VLA的大小不会出现在图片中。 See my linked answer for details. 有关详细信息,请参见我的链接答案。
Not much of an explanation but I suspect it's some compiler optimization for the comma operator. 没有太多的解释,但我怀疑它是针对逗号运算符的一些编译器优化。 The value of a comma operation is the value of the last expression. 逗号运算的值是最后一个表达式的值。 With the compiler knowing sizeof is a unary operator and presented with a comma operation, it doesn't bother to evaluate any but the last expression (regardless whether the last was a reference to a VLA or not). 使编译器知道sizeof是一元运算符,并带有逗号运算符,因此除了最后一个表达式(不管最后一个是否引用VLA)之外,它都不会去求值。
I wrote some test programs (gcc 4.3.3 on Ubuntu 9.04): 我编写了一些测试程序(在Ubuntu 9.04上为gcc 4.3.3):
$ cat test.c # with sizeof $ cat test.c#与sizeof
#include <stdio.h>
int main(void)
{
int x = 0;
printf("%d\n",
sizeof( printf("%s%d\n", "comma!", ++x), x));
}
$ gcc -S test.c $ gcc -S test.c
$ cat test.s $ cat test.s
.file "test.c"
.section .rodata
.LC0:
.string "%d\n"
.text
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $36, %esp
movl $0, -8(%ebp)
movl $4, 4(%esp)
movl $.LC0, (%esp)
call printf
addl $36, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.ident "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
.section .note.GNU-stack,"",@progbits
Note the absences of the string literals and the second printf()
call. 请注意缺少字符串文字和第二个printf()
调用。
$ cat test-alt.c # without sizeof $ cat test-alt.c#不带sizeof
#include <stdio.h>
int main(void)
{
int x = 0;
printf("%d\n",
( printf("%s%d\n", "comma!", ++x), x));
}
$ gcc -S test-alt.c $ gcc -S test-alt.c
$ cat test-alt.s $ cat test-alt.s
.file "test-alt.c"
.section .rodata
.LC0:
.string "comma!"
.LC1:
.string "%s%d\n"
.LC2:
.string "%d\n"
.text
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $36, %esp
movl $0, -8(%ebp)
addl $1, -8(%ebp)
movl -8(%ebp), %eax
movl %eax, 8(%esp)
movl $.LC0, 4(%esp)
movl $.LC1, (%esp)
call printf
movl -8(%ebp), %eax
movl %eax, 4(%esp)
movl $.LC2, (%esp)
call printf
addl $36, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.ident "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
.section .note.GNU-stack,"",@progbits
It may be documented somewhere but I wouldn't know where to look. 它可能记录在某处,但我不知道在哪里看。
sizeof evaluates at compile time. sizeof在编译时求值。 In C99 for variable length arrays it will wait until runtime. 在C99中,对于可变长度数组,它将一直等到运行时。 Check this answer to a similar question. 选中此答案以解决类似问题。
Compiler knows the array size: it is obviously 20. I don't think that sz is VLA. 编译器知道数组大小:显然是20。我不认为sz是VLA。 Try to use use array size as function parameter, for eaxmple: 尝试使用数组大小作为函数参数,例如:
void Function(int size) { int arr[size]; ... }
BTW, to understand what happens, it is recommended to read Assembly code produced by compiler. 顺便说一句,要了解会发生什么,建议阅读编译器生成的汇编代码。 Check whether sizeof is replaced by a constant already at compile time. 检查在编译时sizeof是否已被常量替换。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.