copy elision causes different results

淺唱寂寞╮ 提交于 2019-12-11 00:06:35

问题


Suppose I have this hypothetical, odd and unintuitive situation

    #include <iostream>

    struct A
    {
      A()
      {
        member = 1;
      }

      A(const A &)
      {
        member = 2;
      }

      int member;
    };

    int main()
    {
      A a = A();
      A b = a;
      std::cout << a.member << std::endl;
      std::cout << b.member << std::endl;
      return 0;
    }

I know that copy elision means that a will be initialized with just the default constructor and that b will be initialized with the copy constructor. I also know that (on gcc at least) you can tell the compiler not to do any copy elision.

My question is there some way of having the compiler not use copy elision just for this class?

I realize that the answer in any real situation will be to find some other way 99.9% of the time, and I don't have one of those 0.01% cases (this is an actual hypothetical question, not a "hypothetical question")


回答1:


Copy elision is allowed by the standard and it is the single optimization that is not required to follow the As-If rule[#1], So you should not rely on the behavior.

You might use some compiler settings like in case of gcc, from the man page:

-fno-elide-constructor

The C++ standard allows an implementation to omit creating a temporary which is only used to initialize another object of the same type. Specifying this option disables that optimization, and forces G++ to call the copy constructor in all cases.

However, using this makes your code non portable across different compilers.


[#1]C++03 1.9 "Program execution:

conforming implementations are required to emulate (only) the observable behavior of the abstract machine.

The footnote further describes it in detail.

This provision is sometimes called the “as-if” rule, because an implementation is free to disregard any requirement of this International Standard as long as the result is as if the requirement had been obeyed, as far as can be determined from the observable behavior of the program. For instance, an actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no side effects affecting the observable behavior of the program are produced.




回答2:


RVO/NRVO is explicitly allowed by the Standard and generally a Good Thing™, and there are pretty much no good designs that are broken by it, so there's no reason for any compiler writer to implement such options.

I don't know of any compiler that allows you to turn it off on a case-by-case basis.



来源:https://stackoverflow.com/questions/9957695/copy-elision-causes-different-results

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!