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

Hal Finkel via cfe-dev cfe-dev at lists.llvm.org
Wed Oct 25 16:35:10 PDT 2017


On 10/25/2017 02:54 PM, Ronald Wampler wrote:
> On Wed, Oct 25, 2017 at 2:09 PM, Hal Finkel <hfinkel at anl.gov> wrote:
>> [+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?
> It prints 42 when compiled with c++14 and 0 with c++17 (c++1z).
>
> I also submitted this with a simpler case as
> https://bugs.llvm.org/show_bug.cgi?id=35039

To ask the obvious question, given that this is a GNU extension, has 
this been raised with the GCC developers? I imagine that we do want to 
match GCC's behavior in this regard.

  -Hal

>
> Ron
>>   -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
>>

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




More information about the cfe-dev mailing list