0

I want know when I can memcpy an object in C++.

Thanks to this answer (When is a type in c++11 allowed to be memcpyed?) I know I can safely do this if object is TriviallyCopyable. However, this is very strong restriction. Moreover, In my use case, I do not care, if a copy of an object made through memcpy would be the same as copy created using copy constructor.

The only thing I require is that after I memcpy an object to some memory address, I can treat this memory as original object.

Would it be enough if an object would satisfy StandardLayout requirement or it has to be TriviallyCopyable even in my use case? And if StandardLayout is not enough, what could break if I used that? It guarantess fixed object layout, right?

Igor
  • 1,307
  • 1
  • 10
  • 19
  • 3
    Why do you want _`memcopy()`_ in favor of proper copy constructors with c++ in first place? Sounds like you have a XY problem. – πάντα ῥεῖ Oct 11 '18 at 19:49
  • 1
    What is your use-case? Why do you think you need to use memcpy at all? –  Oct 11 '18 at 19:49
  • 3
    No, it is not enough. If the object is not *TriviallyCopyable* then the behavior is unspecified and possibly undefined. – NathanOliver Oct 11 '18 at 19:50
  • *"The only thing I require is that after I memcpy an object to some memory address, I can treat this memory as original object."* Based on this it sounds like a move may be more appropriate than a copy. – 0x5453 Oct 11 '18 at 19:50
  • You can do a memcpy if the object is trivially copyable. That is a very strong restriction. You cannot do a memcpy if the object is not trivially copyable. Hence the very strong restriction. – Eljay Oct 11 '18 at 19:50
  • 1
    Consider using `std::copy` -- these days the common implementations of this is will `memcpy` when appropriate. – Cory Nelson Oct 11 '18 at 19:51
  • 5
    You read a duplicate of your question which gives an exact answer, and now you're asking a question of the form "I don't like that answer, can I ignore it and maybe get away with it?" The standard says what is allowable; if you don't obey it, then you're in unspecified/undefined behavior, at which point you're not *really* writing C++ anymore. Failing to follow the rules means nasal demons, and you don't want those. – ShadowRanger Oct 11 '18 at 19:52
  • TriviallyCopyable is a strong restriction. Yes. But that's what you *have* to adhere to. `memcpy` just blindly copies bits, it does not care for constructors, destructors, vtables, etc. You simply *cannot* copy any non-trivial C++ object with `memcpy` and expect sane results. Just *don't* use `memcpy` in C++ and you'll live a more happy life. – Jesper Juhl Oct 11 '18 at 19:52
  • One restriction that will exist is that the object must be [trivially destructible](https://en.cppreference.com/w/cpp/types/is_destructible), otherwise the destructor may rely on invariants that are not held when the object representation is copied. – Paul Belanger Oct 11 '18 at 19:52
  • 3
    C++20 [`[[trivially_relocatable]]`](https://quuxplusone.github.io/blog/2018/07/18/announcing-trivially-relocatable/) will make this a lot easier. – HolyBlackCat Oct 11 '18 at 19:53
  • 1
    I think it needs to be pointed out, but pedantically, even if `TriviallyCopyable` is met, you can't still use the destination memory as if it was an instance of the type unless that storage refers to an object of that type. –  Oct 11 '18 at 19:54
  • Even TriviallyCopyable may not be memcpyed to any address of byte buffer you happen to have and hope that it will work like original object. The address must be properly aligned. – Öö Tiib Oct 11 '18 at 19:54
  • One think to consider is the the compiler "knows" you can't do what you are trying to do (the standard says it's not allowed) so the optimiser may generate legal code that does not account for how you initialise (memcpy) the object. – Richard Critten Oct 11 '18 at 19:55
  • 2
    Just use `std::copy()` and let ***it*** decide how to optimize the copying (it will use `memmove` / `memcpy` where appropriate). – Galik Oct 11 '18 at 19:58
  • If you truly do not care, `memcpy` to your heart's content. The only downside is your program probably won't work. – user4581301 Oct 11 '18 at 20:01
  • @NeilButterworth My use case is something like undo log. I want to save object using memcpy, and then possibly restore it. I do not want to use copy ctor, because it might have some side effects - I want to restore the object in the same exact state it was when I saved it. – Igor Oct 11 '18 at 20:05
  • What is the exact problem with the lifecycle, that is not calling any constructor? It is just that compiler can do some optimizations? – Igor Oct 11 '18 at 20:06
  • @user4581301 There is good chance it works, because compilers are more libertarians than the commitee: https://godbolt.org/z/4XrYGY. – Oliv Oct 11 '18 at 20:10
  • @Igor, Compilers don't do optimizations after you perform a memcpy. This is not standard, but accepted (at least by gcc and clang). Verify it. Don't focus on what is written in the standard when you deal with object's memory representation. – Oliv Oct 11 '18 at 20:12
  • So, what wrong exactly could happen if I don't call a constructor on bytes which I treat as some object? – Igor Oct 11 '18 at 20:15
  • @Oliv I have hard time imagining when it won't work (assumig StandardLayout) – Igor Oct 11 '18 at 20:19
  • @ShadowRanger it's not that I'm ignoring the answer. I thought that my use case with slighly smaller restrictions might chnage something. [[trivially_relocatable]] which HolyBlackCat suggested sounds like a good solution. – Igor Oct 11 '18 at 20:27
  • @Igor I think it will always work, but compiler are allowed to do hard optimization, maybe consider this code:https://godbolt.org/z/VVCz9N. Also what you try to do is actually done in android code. So just do it, and when there will be [[trivialy_relocatable]], your code will be standard compliant. – Oliv Oct 11 '18 at 20:33
  • @Oliv Do you know where exactly it is used in android code? It would be nice to have some example – Igor Oct 11 '18 at 20:42
  • @Igor I saw it in a question for which I gave an answer, I think during the previous 3 month, but I can't find it anymore! – Oliv Oct 11 '18 at 22:00
  • @Igor "_I want to save object using memcpy, and then possibly restore it._" If such object contains a pointer to some memory (e.g. `std::string`, `std::vector`, etc.), and during the time period between the "saving", and "restoration", such memory was re-allocated (the previous memory was `delete`d, and new memory was allocated), or the pointed-at memory was changed, would such an action (restoration of the object via `memcpy`), would be successful? Copy-Constructs are specifically meant to copy the entire object. What side effects are you afraid of? – Algirdas Preidžius Oct 11 '18 at 22:10

0 Answers0