https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80738

David Stone <david at doublewise dot net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |david at doublewise dot net

--- Comment #6 from David Stone <david at doublewise dot net> ---
All of the standard library types in C++ have a hand-written version of
std::swap to work around the problem. Fundamental types do not need anything
set to 0 in the middle so they don't show the problem. The simplest case to
show this would probably be a struct containing a unique_ptr (although it
applies to any resource-owning type that doesn't have a swap written
specifically for it):

```
#include <memory>
#include <utility>

struct wrapper {
        std::unique_ptr<int> ptr;
};

void slow(wrapper & lhs, wrapper & rhs) {
        std::swap(lhs, rhs);
}

void fast(wrapper & lhs, wrapper & rhs) {
        std::swap(lhs.ptr, rhs.ptr);
}
```

At `-O3`, this generates the assembly

```
slow(wrapper&, wrapper&):
        mov     rax, QWORD PTR [rdi]
        mov     QWORD PTR [rdi], 0
        mov     rdx, QWORD PTR [rsi]
        mov     QWORD PTR [rsi], 0
        mov     QWORD PTR [rdi], rdx
        mov     rdi, QWORD PTR [rsi]
        mov     QWORD PTR [rsi], rax
        test    rdi, rdi
        je      .L1
        mov     esi, 4
        jmp     operator delete(void*, unsigned long)
.L1:
        ret
fast(wrapper&, wrapper&):
        mov     rax, QWORD PTR [rdi]
        mov     rdx, QWORD PTR [rsi]
        mov     QWORD PTR [rdi], rdx
        mov     QWORD PTR [rsi], rax
        ret
```

Where `fast` is better only because the C++ standard library maintainers
hand-wrote a faster version.

Reply via email to