c++ - 是不是更喜欢预增量而不是后增量?

标签 c++ optimization

过去首选预增量,因为类上的重载后增量需要返回表示增量前对象状态的临时拷贝。

这似乎不再是一个严重的问题(只要内联到位),因为我的旧 C++ 编译器 (GCC 4.4.7) 似乎将以下两个函数优化为相同的代码:

class Int {
    //...
public:
    Int (int x = 0);
    Int & operator ++ ();
    Int operator ++ (int) {
        Int x(*this);
        ++*this;
        return x;
    }
};

Int & test_pre (Int &a) {
    ++a;
    return a;
}

Int & test_post (Int &a) {
    a++;
    return a;
}

这两个函数的最终程序集是:

    .cfi_startproc
    .cfi_personality 0x3,__gxx_personality_v0
    pushq   %rbx
    .cfi_def_cfa_offset 16
    .cfi_offset 3, -16
    movq    %rdi, %rbx
    call    _ZN3IntppEv
    movq    %rbx, %rax
    popq    %rbx
    .cfi_def_cfa_offset 8
    ret
    .cfi_endproc

If nothing is inlined, however, there seems to still be a benefit to preferring pre-increment to post-increment, since test_post is forced to call out into operator++(int).

让我们假设 operator++(int) 被内联为一个惯用的复制构造函数,调用预增量,并返回拷贝,如上所示。如果复制构造函数是内联的或默认的复制构造函数实现,那么编译器是否有足够的信息来优化后增量,以便test_pretest_post 变成相同的功能?如果没有,还需要什么其他信息?

最佳答案

是的。对于内置类型应该无关紧要。对于此类类型,编译器可以轻松分析语义并优化它们——如果这不会改变行为。

但是,对于类类型,它可能(如果不是确实)很重要,因为在这种情况下语义可能更复杂。

class X { /* code */ };

X x;

++x;
x++; 

最后的两个调用可能完全不同并且可能执行不同的事情,就像这些调用一样:

x.decrement(); //may be same as ++x (cheating is legal in C++ world!)
x.increment(); //may be same as x++

所以不要让自己陷入语法糖的陷阱。

关于c++ - 是不是更喜欢预增量而不是后增量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30036749/

相关文章:

c++ - 使用 CUDA 并行化四个或更多嵌套循环

Python XML 解析算法速度

java - 用于实现循环构造的替代代码库

c++ - 用时间检查数据?

c++ - 返回新的 BinarySearchTree - 缺少类模板的参数列表

c++ - 在 Windows XP-7 中禁用蓝牙支持

c - 从循环中删除开关

c++ - 实现一个条件变量来解决多线程忙等待

python - 从 numpy 矩阵中最优提取列

javascript - 在 IE 中 Javascript 的执行速度比 Firefox、Safari 和 Chrome 慢