2

Consider the following example:

#include <iostream>
#include <memory>
#include <boost/optional.hpp>

struct X {
    boost::optional<std::unique_ptr<int>> foo(int i) {
        std::unique_ptr<int> t(new int{i});
        return t;

        // every compiler works with:
        // return std::unique_ptr<int>(new int{i});
    }
};

struct Y {
    X x;

    boost::optional<std::unique_ptr<int>> bar(int i) {
        return x.foo(i);
    }
};


int main()
{
    Y{}.bar(42);   
}

I have two chained copy-elidable returns of a non-copyable object. gcc 5.2 compiles it fine. But neither gcc 4.8 nor clang 3.7 like it, due to actually trying to perform the copy. Which compiler is right? I'm assuming gcc intentionally changed to allow this behavior, which seems particularly useful for cases like this.

Barry
  • 286,269
  • 29
  • 621
  • 977
  • Seems to be implementation defined, so all of them. See http://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization?rq=1 – Captain Giraffe Feb 17 '16 at 17:20
  • which version of boost are you using? – rici Feb 17 '16 at 17:31
  • @barry: It doesn't compile with older versions (at least, not with 1.54) so maybe there will be a hint there. – rici Feb 17 '16 at 19:26
  • Is it just about `foo`? That behavior's [due to a DR](http://stackoverflow.com/questions/25875596/can-returning-a-local-variable-by-value-in-c11-14-result-in-the-return-value-b/25876175#25876175). I assume that the older version issue is simply that `boost::optional` didn't have move-only type support then. – T.C. Feb 18 '16 at 06:12
  • @T.C. Same boost version (1.59) - it has move support, it's the compiler versions that I was changing. I guess gcc5.2 implements that DR but clang3.7 does not? – Barry Feb 18 '16 at 15:27

0 Answers0