2

Assume I wrote a type that is something like a static_string (just a pair of size_t and N chars where N is template int parameter). So my type can be safely memcopied and there is no need to run a destructor. But it has user provided copy constructor so it is not detected as trivially copyable by C++ language.

I would like to tell the users of my type they can memcopy my type and that there is no need to run a destructor.

I always assumed that I can just specialize type_traits but I recently learned it is UB to do so.

If there is no way to do this with type traits: is there a named concept in C++20 that my type satisfies so at least in comment I can use that instead of words?

P.S. I know it is a bad idea to write types like this, but some use cases exist: optimization, shared memory(where you do not want strings to heap alloc).

NoSenseEtAl
  • 28,205
  • 28
  • 128
  • 277
  • If your type is really trivially copyable, then `std::is_trivially_copyable::value` should be `true`, no? – N. Shead Mar 10 '20 at 05:08
  • Related: https://stackoverflow.com/questions/8513417/what-can-and-cant-i-specialize-in-the-std-namespace and https://stackoverflow.com/questions/25345486/why-specializing-a-type-trait-could-result-in-undefined-behaviour – Jerry Jeremiah Mar 10 '20 at 05:16
  • @N.Shead updated my question, for discussion see comments on this Q: https://stackoverflow.com/questions/60597850/is-boostbeaststatic-string-memcopyable-trivial-type – NoSenseEtAl Mar 10 '20 at 05:22
  • This may be useful as well, then: https://stackoverflow.com/questions/29777492/why-would-the-behavior-of-stdmemcpy-be-undefined-for-objects-that-are-not-triv That is, calling `memcpy` on a non-trivially copyable type may be a bad idea, unless done carefully. – N. Shead Mar 10 '20 at 05:52
  • AFAIK you don't have to do anything for this. If you class is like `class static_string { public: static_string(static_string const&) = default; ~static_string() = default; ...; };` then it will be detected as being trivial. – NathanOliver Mar 10 '20 at 12:47
  • @NathanOliver see my last edit: But it has user provided copy constructor so it is not detected as trivially copyable by C++ language. – NoSenseEtAl Mar 10 '20 at 13:19
  • 2
    @NoSenseEtAl Does it need a user provided copy constrcutor? If your class is like `class static_string { size_t size, size_t capacity, char data[N]; ...};` then the default will copy that correctly. – NathanOliver Mar 10 '20 at 13:21

2 Answers2

3

So my type can be safely memcopied and there is no need to run a destructor. But it has user provided copy constructor so it is not detected as trivially copyable by C++ language.

This is a contradiction. As far as the C++ language is concerned, if your type is not TriviallyCopyable, then it is not "safely memcopied". If memcopying is equivalent to a copy, then that must mean that copying the object is equivalent to a memcpy. If two operations are the same, then they must be the same.

There is no way to resolve this contradiction without sacrificing one of these. Either make all copying equivalent (memcpy and copy constructor/assignment) or memcpy must not be allowed.

The question is this: how important is trivial copyability compared to the optimization of only copying the characters that actually have a value in a copy constructor/assignment operator? You cannot have both. Personally, I would say that static strings should never be large enough that the cost of just copying the whole thing should matter all that much. And in the rare cases where that's actually important, provide a specialized function to do the copying.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
0

The answer is No. There is no "atomic" named concept in C++20 that satisfies your type. Of course you could define a user defined concept which satisfies your type. But this is not what you want. Since the question is about documentation I advise you to use words (not code) as a comment.

BlueTune
  • 1,023
  • 6
  • 18