Pergunta

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")

Foi útil?

Solução

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.

Outras dicas

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top