4

So.. How can we call something like memcpy(dataCopy, data, length); to copy abstract data T?

Or if abstract T is not safe lets say we know that T is a POD (plain old data, basically a C struct) - is it possible to copy it?

Rella
  • 65,003
  • 109
  • 363
  • 636

3 Answers3

3

Do you mean working for some arbitrary C++ type T? Unless you know that T is a POD (plain old data, basically a C struct) type, it is not safe to copy objects of type T with memcpy. That would prevent T's copy constructor from running, for example, which might lead to an incorrect copy (trying to memcpy an std::vector would not copy the data buffer, for example).

Jeremiah Willcock
  • 30,161
  • 7
  • 76
  • 78
  • @Jeremiah: Does that mean that if POD has pointers, is it "safe" to copy object with `memcpy`? Would it really be a copy of the original object? What kind of *copy* would it be? – Nawaz Jan 23 '11 at 05:00
  • @Nawaz -- If the POD has pointers, the copy would be valid (i.e., the same as you would get using an assignment operation). Like in C, the copy would be shallow, so the objects that the pointers point to wouldn't be copied. – Jeremiah Willcock Jan 23 '11 at 05:05
  • @Jeremiah: If that kind of copy is *safe* according to you, then what is wrong with copying non-POD with `memcpy`? – Nawaz Jan 23 '11 at 05:07
  • @Nawaz -- `memcpy` on non-PODs is not allowed according to the C++ standard, while doing it on PODs is allowed (but it does with it does in C, meaning a shallow copy). The `std::vector` thing was an example of why you might not want a shallow copy, since copying a vector is supposed to copy the contained data, and the copy constructor preserves that invariant. – Jeremiah Willcock Jan 23 '11 at 05:11
  • @Jeremiah: Why do you mean by *"not allowed according to the C++ Standard"*? Why is it not allowed? – Nawaz Jan 23 '11 at 05:14
  • @Jeremiah: *"since copying a vector is supposed to copy the contained data"*. And copying a POD which has pointers, is not supposed to copy the data pointed to by the pointers? Really? – Nawaz Jan 23 '11 at 05:15
  • @Nawaz -- Although http://codeidol.com/cpp/cpp-coding-standards/Dont-memcpy-or-memcmp-non-PODs/ (warning: hard to navigate) has some more information, the basic reason is that `memcpy` may not preserve class invariants. Remember as well that because of `private` members, you may not be able to "fix up" an object such as a `vector` to satisfy its invariants again, and trying to do that breaks the class's abstraction anyway. – Jeremiah Willcock Jan 23 '11 at 05:21
  • @Jeremiah: If you copy `class { int a,b,c; char x,y,z; public: void f() {/*****/} };` with `memcpy`, what invariants will it break? – Nawaz Jan 23 '11 at 05:29
  • @Nawaz -- that one won't break any invariants, and is allowed by C++0x (I don't remember about C++03). The case where it would be problematic is if your class had a nontrivial default constructor, copy constructor, and/or assignment operator. – Jeremiah Willcock Jan 23 '11 at 05:42
  • @Jeremiah: So it all depends on how the non-POD is defined, and what kind of copy one wants. Anyway, nice talking to you. :-) – Nawaz Jan 23 '11 at 05:45
  • @Nawaz -- In case you want more details, the "trivially copyable" section on page 219 of http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3225.pdf explains the exact C++0x requirements. – Jeremiah Willcock Jan 23 '11 at 05:47
  • 1
    lets say we know that T is a POD - is it possible to copy it? – Rella Jan 23 '11 at 11:36
3

You cant do that reliably. If it was so easy, possible and reliable, then programmers would not be overloading operator=() and writing copy-constructor.

If you want to make a copy of your object, then either overload operator=(), or write copy-constructor, or do both!

Nawaz
  • 353,942
  • 115
  • 666
  • 851
0

This could be dangerous depending on the type of T. If T is a POD type, then everything's all right. Otherwise, I suggest you simply call T's copy constructor (or use a clone pattern if it's not possible).

Etienne de Martel
  • 34,692
  • 8
  • 91
  • 111