Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is std::is_trivially_copyable wrong?

Considering cppreference and the current c++ working draft, a class is trivially copyable if:

  1. Every copy constructor is trivial or deleted
  2. Every move constructor is trivial or deleted
  3. Every copy assignment operator is trivial or deleted
  4. Every move assignment operator is trivial or deleted
  5. at least one copy constructor, move constructor, copy assignment operator, or move assignment operator is non-deleted
  6. Trivial non-deleted destructor

    • http://en.cppreference.com/w/cpp/concept/TriviallyCopyable
    • http://en.cppreference.com/w/cpp/types/is_trivially_copyable
    • https://github.com/cplusplus/draft/blob/master/papers/n4750.pdf (page 215)

So I came up with this code sample:

#include <type_traits>

struct non_trivially_copyable {
  non_trivially_copyable(non_trivially_copyable const&) = delete;
  non_trivially_copyable& operator=(non_trivially_copyable const&) = delete;
  non_trivially_copyable(non_trivially_copyable &&) = delete;
  non_trivially_copyable& operator=(non_trivially_copyable &&) = delete;
};

int main()
{
    return std::is_trivially_copyable<non_trivially_copyable>::value;
}

My class does not satisfy requirement number 5. Still it gives me the result that my class non_trivially_copyable is trivially copyable. I tested it on some online compilers:

  • https://godbolt.org/g/9s4fr9
  • https://wandbox.org/permlink/sEJYdi5aIDMzsjGY
  • https://onlinegdb.com/SyFyTBrx7
  • http://coliru.stacked-crooked.com/a/93b6ea4d202092a6

I doubt that all implementations are wrong; so why do I get this result?

like image 494
phön Avatar asked Jun 06 '18 12:06

phön


People also ask

Is trivially copyable C++?

A trivially copyable class is a class that: has no non-trivial copy constructors, has no non-trivial move constructors, has no non-trivial copy assignment operators, has no non-trivial move assignment operators, and has a trivial destructor.

Is array trivially copyable?

Trivially copyable types have no non-trivial copy operations, move operations, or destructors. Generally, a copy operation is considered trivial if it can be implemented as a bitwise copy. Both built-in types and arrays of trivially copyable types are trivially copyable.

What is trivially constructible?

Trivially constructible from is defined as construction from values of the given types that does not do any operation not considered "trivial" (see paragraph 2 here). int is a trivially copyable type, so int is trivially copyable from itself. Therefore, std::is_trivially_constructible_v<int, int> is true.


1 Answers

This was changed in C++17; before that, non_trivially_copyable would have been trivially copyable. Your class is indeed not trivially copyable in C++17, by the part of the standard you refer to yourself.

However, it appears libstdc++ and libc++ were not updated to reflect that yet. So to answer your question directly: those two implementations are indeed wrong. Note that your godbolt link shows that MSVC does get it right.

As this was considered a defect (see CWG 1734), this is supposed to change for implementations of older revisions of C++, too.


As far as I know, one core motivation for the change in the standard was to make memcpy-ing around atomics and mutexes illegal.

like image 80
Baum mit Augen Avatar answered Nov 14 '22 05:11

Baum mit Augen