写这篇文章的原因是我在问答平台看到的一个问题:
C++内层循环中定义变量和在外面定义比影响大吗?
问题来自:http://ask.csdn.net/questions/176270
例如:
for(int i=0;i<999;i++) {
for(int j=0;j<999;j++);
}内层循环每次都定义j会造成多大的消耗呢?
此处我给出的回答是:
这个需要看你具体用什么编译器。不过主流编译器(如vs和gcc)这一块优化都比较好,不会反复分配变量。
看到答案和评论,好像有很多人对这个感兴趣,所以我打算给大家实测分享一下,于是写了如下代码进行测试:
#include <cstdio>
using namespace std;
void Test1()
{
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d,%d\n", int(i), int(j));
}
}
}
void Test2()
{
int i, j;
for (i = 0; i < 2; i++)
{
for (j = 0; j < 3; j++)
{
printf("%d,%d\n", int(i), int(j));
}
}
}
int main()
{
Test1();
Test2();
return 0;
}
OK,程序非常简单,Test1
和Test2
是两个循环,干相同的事情,就是在双重循环里打印一下 i
和 j
的值,差别只在于一个在循环外定义变量 j
,另一个在循环内定义变量 j
。
此处我使用g++
进行编译,优化等级是O0
(这是GCC
默认的优化等级,也是最低的优化等级)的:
g++ -O0 -g test.cpp
编译后,我将生成的Test1函数和Test2函数反汇编出来,得出的结果是这样的:
Test1
函数反汇编如下:
(gdb) disas /m Test1
Dump of assembler code for function Test1():
5 {
0x0804841d <+0>: push %ebp
0x0804841e <+1>: mov %esp,%ebp
0x08048420 <+3>: sub $0x28,%esp
6 for (int i = 0; i < 2; i++)
0x08048423 <+6>: movl $0x0,-0x10(%ebp)
0x0804842a <+13>: jmp 0x804845d <Test1()+64>
0x08048459 <+60>: addl $0x1,-0x10(%ebp)
0x0804845d <+64>: cmpl $0x1,-0x10(%ebp)
0x08048461 <+68>: jle 0x804842c <Test1()+15>
7 {
8 for (int j = 0; j < 3; j++)
0x0804842c <+15>: movl $0x0,-0xc(%ebp)
0x08048433 <+22>: jmp 0x8048453 <Test1()+54>
0x0804844f <+50>: addl $0x1,-0xc(%ebp)
0x08048453 <+54>: cmpl $0x2,-0xc(%ebp)
0x08048457 <+58>: jle 0x8048435 <Test1()+24>
9 {
10 printf("%d,%d\n", int(i), int(j));