[cfe-dev] Guaranteed copy elision and GNU ?: operator

Ronald Wampler via cfe-dev cfe-dev at lists.llvm.org
Thu Oct 19 18:34:00 PDT 2017


On Tue, Oct 17, 2017 at 3:46 PM, Ronald Wampler <rdwampler at gmail.com> wrote:
> Hello,
>
> I recently came across an issue when using the gnu conditional
> operator (?:) in C++17. In C++14, the code below when compiled with
> Clang 5 outputs 42 as expected, but in C++17 the output is 0. In
> C++17, I believe the copy constructor for shared_ptr is being elided
> and so the ref count is not incremented and the underlying ptr gets
> deleted. If the first operand is cast to an rvalue (e.g.,
> std::move(makeSharedIntWrapper(42,true)), the behavior is as expected
> (since we are disabling the copy elision). Since this is an GNU
> extension, is it OK to not elide the copy in this case?
>
> I didn't test to see what gcc does since I don't have ready access to gcc7.

I was able to confirm that gcc7 has the same behavior as above.

>
> #include <memory>
> #include <iostream>
>
> struct int_wrapper {
>     int_wrapper(const int& x) : x(new int(x)) {}
>     ~int_wrapper() { delete x; }
>     int *x;
> };
>
> static std::shared_ptr<int_wrapper> makeSharedIntWrapper(int x, bool t) {
>     return t ? std::make_shared<int_wrapper>(x) :
> std::shared_ptr<int_wrapper>();
> }
>
> int main(int argc, const char * argv[]) {
>     auto s = makeSharedIntWrapper(42, true) ?:
> std::make_shared<int_wrapper>(17);
>     std::cout << *s.get()->x << std::endl;
>
>     return 0;
> }



More information about the cfe-dev mailing list