0

I didn't quite understand the two comments below by @goodbyeera and @user743382 in this answer in SO.

Comment by @goodbyeera:

@hvd: In that sense, wouldn't the compiler perform memcpy optimization for plain {} definition too?

Comment by @user743382:

@goodbyeera It's allowed, but it may be significantly harder for the compiler to detect that it's possible. A field-by-field assignment in the copy constructor function body may look to the compiler as if it should avoid copying any internal padding bytes.

Alexander
  • 2,581
  • 11
  • 17
  • 1
    I'm unable to discern what you are unable to quite understand from the comments. If nothing else, the *as-if* rule definitely allows the compiler to use `memcpy`, but the compiler detecting that is an option may be more difficult. You'd have to look as the assembly to be sure. (I did not downvote.) – Eljay May 23 '21 at 23:30
  • @Eljay Why would it be more difficult to detect that is an option? What do the padding bytes have to do with this? – Alexander May 23 '21 at 23:43
  • 1
    More difficult to detect because the class will no longer be [`std::is_trivial`](https://en.cppreference.com/w/cpp/types/is_trivial). I do not know what the padding bytes have to do with this. – Eljay May 24 '21 at 00:02

1 Answers1

1

Why would it be more difficult to detect that is an option? What do the padding bytes have to do with this?

Imagine you have the following class definition:

class Foo
{
    char a;
    int b;

public:
    Foo (const Foo& other)
    {
        a = other.a;
        b = other.b;
    }
};

Now, if you had allowed the compiler to synthesize a default copy constructor, it would most likely implement it as an 8-byte memcpy, since it knows that the padding bytes between a and b (which are inserted for alignment purposes) are not important. Said memcpy will be inlined and is probably 2 machine instructions.

However, with a user-defined copy constructor as shown, the compiler might think, "oh look, he's copying each member variable indivdually, I'd better respect that", and therefore generate sub-optimal code. Whether it does or not, you could test on Godbolt (I didn't, sorry).

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
  • Another example would be a class that contains an instance of another class, with user-defined default constructor and assignment operator, but the definition of those functions are not visible to the compiler (e.g. defined in a different compilation unit) The compiler has no basis to assume that the copy construction of `Foo` has the same effect as a single `memcpy()` call. – Peter May 24 '21 at 00:13
  • @Peter Certainly, although I don't think that is what the OP was getting at. – Paul Sanders May 24 '21 at 00:15