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

Hal Finkel via cfe-dev cfe-dev at lists.llvm.org
Wed Oct 25 11:09:04 PDT 2017


[+Richard]


On 10/19/2017 08:34 PM, Ronald Wampler via cfe-dev wrote:
> 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.

You mean that it prints 0 or 42?

  -Hal

>
>> #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;
>> }
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

-- 
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory




More information about the cfe-dev mailing list