大多数 C 编译器会尽可能优化所有内容。
如果您想真正了解使用标志进行编译以查看汇编代码并查看它在做什么。就像有人说的那样,如果它是一个简单的类型(没有构造函数),特别是如果你使用所有文字,编译器可能只会在每次迭代时将一个固定值移动到一个寄存器中,或者即使没有任何改变也不会打扰迭代之间的变量
我刚刚检查了您的示例如下所示,并且还对其进行了更改以修改循环中的变量,您可以看到汇编代码如何生成更改。
在第一个例子中,注意 LBB0_1 处的循环,它只是一条 movl 指令。
在第二个示例中,它仍然非常简单,但是即使没有使用结果,它仍然会将内容保存在堆栈中。我添加了一些 cmets 来解释循环在做什么。
$ cc -fno-asynchronous-unwind-tables -S dummy.c
int main(void) {
for(;;) {
int y = 1 + 2 + 3;
}
}
$ cat dummy.s
.section __TEXT,__text,regular,pure_instructions
.macosx_version_min 10, 12
.globl _main
.align 4, 0x90
_main: ## @main
## BB#0:
pushq %rbp
movq %rsp, %rbp
movl $0, -4(%rbp)
LBB0_1: ## =>This Inner Loop Header: Depth=1
movl $6, -8(%rbp)
jmp LBB0_1
.subsections_via_symbols
$ cc -fno-asynchronous-unwind-tables -S dummy.c
int main(void) {
int i = 0;
for(;;) {
int y = i + 2 + 3;
i++;
}
}
$ cat dummy.s
.section __TEXT,__text,regular,pure_instructions
.macosx_version_min 10, 12
.globl _main
.align 4, 0x90
_main: ## @main
## BB#0:
pushq %rbp
movq %rsp, %rbp
movl $0, -4(%rbp)
movl $0, -8(%rbp) ## i = 0
LBB0_1:
movl -8(%rbp), %eax ## y = i
addl $2, %eax ## y += 2
addl $3, %eax ## y += 3
movl %eax, -12(%rbp) ## -12(rbp) = y
movl -8(%rbp), %eax ## eax = i
addl $1, %eax ## i++
movl %eax, -8(%rbp) ## -8(rbp) = i
jmp LBB0_1
.subsections_via_symbols