【问题标题】:++i versus i++ : is there any difference on any modern compiler? [duplicate]++i 与 i++ :任何现代编译器有什么区别吗? [复制]
【发布时间】:2011-06-28 12:34:09
【问题描述】:

可能重复:
Is there a performance difference between i++ and ++i in C++?

我明白:

i++;

应该接受比

更多的指令
++i;

因为它会生成一个您不需要使用的中间结果,所以人们将“++i”放在对中间结果没有用处的代码行上。

但是,编译器非常聪明,它们可以判断结果是否正在使用。他们可以说出各种各样的事情。但它们不是魔法

所以我很好奇 - 在现代编译器中,选择一种方式而不是另一种方式实际上很重要,还是它会简单地编译成相同的机器代码?

【问题讨论】:

  • 这取决于i 是什么...请记住,在C++ 中,++ 两个运算符都可以重载。
  • 你总是可以使用 i++ 编译一个程序,然后除了使用 ++i 之外的同一个程序,看看生成的程序集是否相同。
  • @Jake:这只有在你已经知道汇编的情况下才有效。

标签: c++ c compiler-construction


【解决方案1】:

int 上使用它并不重要。但是,当使用迭代器或其他重载operator++ 的对象时,它可能仍然会产生影响。

【讨论】:

  • 他在询问编译指令等;你能用生成的程序集或类似的东西来支持你的主张吗?
  • @Azure:如果运算符被重载(尤其是如果编译器不知道重载的实现),它无法决定用预增量替换后置是否有区别(就副作用而言,重载导致 - 是的,那将是可怕的代码,但仍然......)。
【解决方案2】:

这对本机类型没有影响,但可以对用户定义的类型(即类、结构、枚举等)产生一些影响,因为用户可以重载运算符和后缀之一(@987654321 @) 有时可能会慢一些。

【讨论】:

  • 你能为枚举重载运算符吗?哇...
  • @Billy:您也可以在 C++98 中为枚举类型重载运算符。
  • 当使用枚举作为标志时,这对于重载operator&operator| 特别方便。 -- 枚举运算符也可以在 C++98 中重载,但当然只能作为非成员。
【解决方案3】:

在 C 中,应该没有区别。编译器足够聪明,可以在不使用时优化掉多余的副本。在 C++ 中,它可以产生巨大的差异,因为如果 i 定义的变量可以是分别定义 operator++ 的前缀和后缀版本的类型,这使得编译器无法删除一般情况。因此,即使不使用,编译器也无法删除副本。

为了保持一致性,我会使用前缀形式,除非您必须使用后缀形式。 (尽管我认为后缀形式“更漂亮”)

【讨论】:

    【解决方案4】:

    Visual C++ 似乎在每种情况下都输出相同的代码:

        i++;
    
    00AB149C  mov         eax,dword ptr [i]  
    00AB149F  add         eax,1  
    00AB14A2  mov         dword ptr [i],eax  
    
        ++j;
    
    00AB14A5  mov         eax,dword ptr [j]  
    00AB14A8  add         eax,1  
    00AB14AB  mov         dword ptr [j],eax  
    

    【讨论】:

    • 这并不意味着编译器不能优化两个版本中的多个版本,也不意味着它会始终生成相同的代码。
    • 问题是在现代编译器上是否存在差异。根据经验,没有。
    猜你喜欢
    • 2013-05-22
    • 1970-01-01
    • 2017-10-23
    • 1970-01-01
    • 2011-08-06
    • 2010-10-11
    • 2016-05-13
    • 2014-01-24
    • 2011-03-21
    相关资源
    最近更新 更多