Chinaunix首页 | 论坛 | 博客
  • 博客访问: 990899
  • 博文数量: 158
  • 博客积分: 4380
  • 博客等级: 上校
  • 技术积分: 2367
  • 用 户 组: 普通用户
  • 注册时间: 2006-09-21 10:45
文章分类

全部博文(158)

文章存档

2012年(158)

我的朋友

分类: C/C++

2012-11-23 16:21:47

看到这样的C/C++代码
int tmp; // 代码一
while( ... )
{
    tmp = a;
    a = b;
    b = tmp;
}
...
确实有点无语,连C#er都知道这样的写法不好,因为M$在《XXX》中告诉他们tmp将无法得到优化。看来C/C++高估了使用者的等级,其实也需要一些幼稚园的启蒙读物。
正确的写法应该是
while( ... ) // 代码二
{
    int tmp = a;
    a = b;
    b = tmp;
}
...
差别在于代码二明确告诉编译器tmp的全部作用,而代码一中编译器只能保守的认为tmp还没完,这段代码执行完毕之后tmp还可能需要被用到,所以必须将它的值保存下来。
一个是全部的信息,一个部分信息,任何人都能猜得出哪个更会被编译器优化好。
之所以谈到“优化”,因为写出代码一的人大抵是认为代码二中tmp频繁定义会影响运行效率,……,如果真是这样想,嗯,也情有可原,虽然错误,但属于经过大脑思考过的。

[题外话:本来草民的blog也就是小圈子中聊聊,原本宁静,但现在访客中也有很黄很暴力的^_^,所以我必须浪费一些笔墨,把文章补充很多废话,否则_-_]
不得不加上的废话1:古老的C语言,用到的变量必须提前声明(编译器可以直接得到需要的栈空间尺寸),所以代码必须写成代码一的形式。
我在21世纪说的C语言肯定默认是现在的C语言,所以如果用的不是C99,或代码是过去传承下来的,那自然不在我“口伐”的对象中。
不得不加上的废话2:大部分编译器都能把代码一也优化好。
是的,如果我在代码中加上1万个int i001; int i002;的定义,编译器也会将它们优化没,但我却无法跟老板说因为编译器……,所以你就让我加上1万个无用的定义玩玩吧。
不得不加上的废话3:或许有---虽然我不敢确定---这样的编译器,它能优化代码一,却不能优化代码二。
如果是这样,那么代码一属于编译器依赖性优化,对于这样的优化,一般的编码规范是:a.提供一份非编译器依赖的代码注释,即代码二。b.在文档或代码中指明为什么必须进行这步优化,它适用于哪个版本的哪个编译器。差不多类似这样
#ifdef XXX编译的aaa.bbb.ccc.dddd版本
代码一
#else
代码二
#endif
不得不加上的废话4:代码一改为 register int tmp; 就OK了。
同“不得不加上的废话2”,做正确的事,而不是把错误的事做正确。
不得不加上的废话5:不就是一个优化嘛,不值得浪费时间。
是的,可惜我说的不是优化,我只是拿优化来说事。代码二是自然而然的算法体现(她是一个代码自解释的算法),而代码一不是,代码一本身无法解释为什么int tmp会定义在域外。此帖声讨的是为什么有人要舍简单取复杂,舍清晰取晦涩?(当然如果是误认为代码一会优化得更好的人不在此列)。

阅读(1481) | 评论(9) | 转发(0) |
给主人留下些什么吧!~~

网友评论2012-11-23 16:23:39

flyingzhang
通常情况下。。只要tmp是被声明成为函数局部变量 就没有什么好非议的。个人更prefer第一种写法 事实上 到目前为止还是会有一些compiler可能不会优化第二种法 不能总拿gcc和vc来说事。特别是如何while中的逻辑复杂一些的话 (当然 这种情况下 似乎是不是多一条栈顶指针移动的指令 也不太重要了 但可能恶果之一是compiler会少一个可用寄存器来导致生成的代码劣化 尽管循环中的变量外提是compiler通常情况下进行代码优化的第一步。)

网友评论2012-11-23 16:23:30

假骑士
如果一段代码里执行了很多循环
foo()
{
   for(i=0;...){}
   for(i=0;...){}
   ...
}
这时那种代码更合理呢? 偶个人感觉适合把int i;定义到循环外似乎更好些,不知对否?

网友评论2012-11-23 16:23:20

假骑士
代码二的好处是循环后,变量temp就可以消失了。
重复定义的问题,其实循环内,temp一直存在,不存在重复定义的问题。
另,实测了一下,这两段代码在VC++6里面的时间效率基本一致。

网友评论2012-11-23 16:23:07

非法用户
其实这根本就没有意义,只是个人风格不同而已,对此我既不反对也不赞同星星的说法.

例子:我喜欢将花摆在门边外面(左面),老婆喜欢把花摆在门边里面(右面).一好事之人,非要对此指指点点,一笑而置之不理!

网友评论2012-11-23 16:23:00

waterwalk
C89应该也可以写成代码2的形式吧。只要变量定义在块作用域开头就好了。