0

I would expect the following code to print copy called twice. Once for the creation of f2 and once for the creation of f3. But for some reason, it is only printed once. Why is this? Is there some type of optimization going on? If so, is there a way to disable it without compiler flags?

struct Foo
{
    Foo() = default;
    Foo(Foo const&) { std::cout << "copy called" << std::endl; }
};

Foo test()
{
    Foo f1;
    Foo f2(f1);

    return f2;
}

int main()
{
    Foo f3(test());
}
zoecarver
  • 5,523
  • 2
  • 26
  • 56
  • *If so, is there a way to disable it without compiler flags?* -- Why would you want to disable it? If it's because your real code has side-effects that are undesirable because of the optimization, then your code is flawed. – PaulMcKenzie May 18 '19 at 03:38
  • No, it is because I want to be able to implement reference counting. – zoecarver May 18 '19 at 03:40
  • How is the optimization stopping reference counting from working correctly? It shouldn't have any effect. – PaulMcKenzie May 18 '19 at 03:41
  • Because in a more complex piece of code it was (or I thought it was) causing the number of destructions to be different than the number of constructions and that was causing it to destroy the pointer before it should have. – zoecarver May 18 '19 at 03:43
  • Well, you just confirmed my original point. Your code was flawed. How does `std::shared_ptr` accomplish this? That is also reference counted. Bottom line is that you should never write code assuming a copy would be done, and base a set of business logic on that assumption. The compiler is free to optimize copies away. – PaulMcKenzie May 18 '19 at 03:44
  • [From the docs](https://en.cppreference.com/w/cpp/language/copy_elision). The first sentence sums it all up about side-effects. – PaulMcKenzie May 18 '19 at 03:49
  • I would like to qoute the notes section of the cppreference link mentioned by @PaulMcKenzie, ```Copy elision is the only allowed form of optimization (until C++14)one of the two allowed forms of optimization, alongside allocation elision and extension, (since C++14) that can change the observable side-effects. Because some compilers do not perform copy elision in every situation where it is allowed (e.g., in debug mode), programs that rely on the side-effects of copy/move constructors and destructors are not portable.``` – Hemil May 18 '19 at 04:03

0 Answers0