Reference Class Member Triviality

Viewed 91

Let's say, for reasons of my own, I want a class to have a non-static reference member. I would think that this type should be easily optimized out of most code that uses it. Therefore, I assert its triviality in a unit test.

Clang and GCC agree that the class is trivial, but MSVC disagrees. Who is right, and why, according to the standard?

#include <type_traits>

struct example {
    int& r;
};


// Clang and GCC let this pass
// MSVC fires this assertion
static_assert(
    std::is_trivial<example>::value,
    "example is not trivial"
);
1 Answers

According to C++17 [class]/6, for a class to be trivial, among other requirements, it has to have at least one non-deleted default constructor. The example class's default constructor is deleted, so example is not a trivial class.

Before C++17, the situation is somewhat less clear. It was required for a trivial class to have a trivial default constructor, and it was not clear whether a deleted default constructor qualifies as trivial. Richard Smith asked in CWG 1928 whether special member functions that are defaulted and implicitly deleted are trivial. The Committee's response was:

CWG feels that the triviality of a deleted function should be irrelevant. Any cases in which the triviality of a deleted function is observable should be amended to remove that dependency.

Subsequently, the resolution of CWG 1496 resolved this issue in the case of trivial classes: it no longer matters whether a deleted default constructor qualifies as trivial, because in C++17, the definition says that all default constructors (in case there are multiple) must be either trivial or deleted and at least one must be non-deleted.

It seems that GCC and Clang may have been considering deleted default constructors as trivial, and haven't been updated with the C++17 definition of "trivial class". You should file bug reports.

Related