另外作为一个人我的观察也是一样的汇编代码.请检查图像,其中汇编代码对于i和i = i 1 –
还有另一个link说,以前以前增量运算符比加法和赋值更快,但现在编译器优化i和i = i 1是相同的.
有没有任何官方文件/论文,我们可以参考确认什么是正确的? (我通常会使用信用卡和一个人在Stackoverflow上接受的答案,在我提供的链接上找不到这样的东西).
解决方法
a = ++i; // a is set to the result of i+1 a = i++; // make a copy of i,compute i+1,save the copy of i in a
没有优化,汇编代码将如下所示:
a = ++i; a = i++; MOV eax,(i) MOV eax,(i) PUSH eax ADD eax,1 ADD eax,1 MOV (i),eax MOV (i),eax POP eax MOV (a),eax MOV (a),eax
现在,通过优化,结果与C中相同,其中运算符仅适用于整数和指针.
和 – 在那里,因为大多数处理器在写入C时有一个INC和一个DEC指令.所以如果要使用索引寄存器,这些指令将被应用:
char a[256]; ...init 'a' in some way... int sum =0; for(int i = 0; i < 100; ++i) { sum += a[i]; }
这可以用(6502)中的简单INC来完成:
LDA #00 LDY #00 LOOP: CLC ADC ($80),Y INY <-- ++i or i++ CPY #100 BCC LOOP
请注意,在C中,我们有另一个符号来增加一个变量:
i += 1;
如果您需要将寄存器增加1以上,这是实用的:
i += 3;
或者每次加倍注册:
i += i; // (equivalent to i *= 2; or i <<= 1; in C++)
问题:为什么INC和DEC不与所有80×86一起使用?
有一段时间,ADD reg,1和SUB reg,1指令比INC reg和DEC reg更快.在过去,它更快,因为指令较小,我们没有缓存(或很少).今天,任何一条指令可能大致相同.
Intel Optimization Reference,section 3.5.1.1 Use of the INC and DEC Instructions
从另一个更新的评论来看,它看起来像是在较新的处理器中修正了英特尔文档的缓慢.因此,使用或不使用这些指令应取决于目标处理器,如果事先知道的话.
正如phresnel在评论中指出的那样,我和我之间的区别对许多人来说可能不清楚.对于一个整数,优化是非常微不足道的,绝对会发生,甚至是使用-O0.然而,这是一个不同的故事.有一个类,两个增量运算符清楚地表明我需要一个副本(即使data_只是一个整数,尽管在这种情况下你也可以做:return data_ – 它仍然需要一个很好的隐藏的副本!):
class A { public: A& operator ++ () // ++i -- no copy { ...apply the ++ operation to 'data_'... return *this; // return a reference to this } A operator ++ (int) // i++ -- needs a temporary copy { // remember that the 'int' is totally ignored in the function,// its only purpose is to distinguish '++i' from 'i++' A copy = *this; // here we need a copy ++*this; return copy; // and here we return said copy } private: some_type_t data_; };
请注意,现代C编译器不会在i函数中生成两个副本,因为可以优化返回值,无需额外的副本.
如果使用i,如Is there a performance difference between i++ and ++i in C++?(phresnel提到的链接),两种情况之间的差异可以明显较慢