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

Arthur O'Dwyer <arthur.j.odwyer at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |arthur.j.odwyer at gmail dot 
com

--- Comment #6 from Arthur O'Dwyer <arthur.j.odwyer at gmail dot com> ---
(I got here from
https://stackoverflow.com/questions/47464819/uninitialized-copy-memcpy-memmove-optimization)

Jonathan, you wrote:
> The point of the condition is to decide whether to use std::copy, because for 
> trivially-copyable types that is optimized to memmove. But unlike 
> std::uninitialized_copy, std::copy calls no constructors, so the type must be 
> trivially default constructible, and if an exception is thrown, it calls no 
> destructors, so the type must be trivially destructible as well. So we can 
> only use the memmove optimization for types which [...]

What do you mean "if an exception is thrown"? If we call std::copy from here,
then it's because we are taking the memmove path. memmove never throws
exceptions, so how can we be worried about what happens "if an exception is
thrown"?

That is, the following code 100% definitely never attempts to destroy a `B`
object, so why does it matter that `B`'s destructor is non-trivial?

// https://godbolt.org/z/w7nTe5
struct A {
    int i;
    A() = default;
    A(const A&) = default;
    ~A() = default;
};
struct B {
    int i;
    B() = default;
    B(const B&) = default;
    ~B() {}
};

void copyAs(A *p, A *q, int n) {
    std::uninitialized_copy(p, p+n, q);  // successfully uses memmove
}
void copyBs(B *p, B *q, int n) {
    std::uninitialized_copy(p, p+n, q);  // fails to use memmove
}

Reply via email to