沒有太多的解釋,但我懷疑這是一些逗號運算符的編譯器優化。逗號操作的值是最後一個表達式的值。編譯器知道sizeof是一個一元運算符,並且帶有逗號操作,所以除了最後一個表達式(不管最後一個是否是對VLA的引用)之外,它都不用去評估它。
我寫了一些測試程序(在Ubuntu 9.04的gcc 4.3.3):
$貓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測試。 c
$ 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
請注意缺少字符串文字和第二個printf()
調用。
$ 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測試alt.c
$貓測試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
可能在某處證明,但我不知道在哪裏看。
這是關於C而不是C++的問題。在C++中不存在VLA。 – 2010-08-24 07:22:34
哦,有人把它標記爲C++。壞人。 – 2010-08-24 07:46:29