【MOOC注】学过C语言的请进来,相信吗?但我信了,目瞪口呆......
我的第一份工作是C语言的嵌入式软件开发,公司内部有严格的C语言编程规范,因此并没被此类问题烦恼过。
对于i++和++i的问题,规范规定使用++i的形式。因为这样不需要保存初始值,可以节省一条汇编指令。所以我一直都是用下面的方式:
for (int i = 0; i < 100; ++i)
其实这样写没有i++顺手,经常敲错还要回去改。
至于节省了哪条指令,今天我动手实验了一下,发现编译器其实可以发现i的初始值有没有被人使用,否则就不会保存那个临时变量。
以上代码经过编译会变成下面的汇编指令,可以看出.L3的地方有个100次的循环,换成使用i++的方式后,编译出来的汇编指令也是完全一样。
所以对于内置数据类型,++i和i++几乎是没有区别的。(对于类对象,例如STL里面的迭代器(iterator),尤其是自己开发的类型,重载这两个操作符的性能可能会有不同,不过在强大的编译器面前,好像凡事没有绝对。)
本来事情也许到这里就结束了,但见证奇怪的时刻即将到来。我原本打算想用苹果系统截个漂亮一点的图,但发现Apple编译器的结果却是这样的!
我能不能说一句粗话,“简直亮瞎了我的钛合金狗眼啊”。您老人家就这样直接返回5050啦!
结论:
编译器功能太强大,想搞砸都不行了!
注:以上结果分别在Ubuntu和OS X上使用gcc -std=c99 -O2 -S *.c
命令进行O2级优化编译。Ubuntu gcc 4.8.2,Apple LLVM version 6.1.0
转载自:图灵社区