In C++20, the concept of POD is deprecated, supposedly because it is a meaningless composite trait of being trivial and standard-layout. However, the definition of POD in the C++20 draft is not exactly "both trivial and standard-layout"; it is actually:
A POD class is a class that is both a trivial class and a standard-layout class, and has no non-static data members of type non-POD class (or array thereof). A POD type is a scalar type, a POD class, an array of such a type, or a cv-qualified version of one of these types.
In other words, not only is a POD type both trivial and standard-layout, but it is also recursively so.
Is this recursive requirement redundant? In other words, if a type is both trivial and standard-layout, is it automatically recursively trivial and standard-layout as well? If the answer is "no", then what is an example of a standard-layout, trivial type that fails to be POD?
A POD type (which stands for Plain Old Data type) is a type whose characteristics are supported by a data type in the C language, either cv-qualified or not. This includes scalar types, POD classes and arrays of any such types.
A trivial type is a type whose storage is contiguous (trivially copyable) and which only supports static default initialization (trivially default constructible), either cv-qualified or not. It includes scalar types, trivial classes and arrays of any such types.
A standard-layout type is a type with a simple linear data structure and access control that can easily be used to communicate with code written in other programming languages, such as C, either cv-qualified or not. This is true for scalar types, standard-layout classes and arrays of any such types.
Trivial typesWhen a class or struct in C++ has compiler-provided or explicitly defaulted special member functions, then it is a trivial type. It occupies a contiguous memory area. It can have members with different access specifiers. In C++, the compiler is free to choose how to order members in this situation.
In C++20, the concept of POD is deprecated, supposedly because it is a meaningless composite trait of being trivial and standard-layout.
Incorrect. The term POD is being deprecated because it no longer matters:
The term POD no longer serves a purpose in the standard, it is merely defined, and restrictions apply for when a few other types preserve this vestigial property.
Essentially, a type which is both trivial and standard layout doesn't gain any abilities beyond what being trivial and being standard layout provide on their own. The combination of the two doesn't make the type special, and the two properties don't really have much to do with one another.
Standard layout is about the layout of its non-empty subobjects being well-defined (as well as its empty base class subobjects not disturbing the type's layout). Triviality is about whether the object has some meaning beyond the block of bits that it stores (and whether it is conceptually a valid object if it is initialized with an arbitrary block of bits).
If I'm making a template that takes a type T
, and I want to see if I can memcpy
objects of that type, I don't care about the layout of its members; I want to know if it is TriviallyCopyable. Similarly, the correctness of offsetof
does not care in the slightest if the class has a user-provided copy constructor. All it cares about is if the layout of member subobjects happens in a clear, standard-enforced order.
Basically, people looked around and realized that nothing in C++ is left that specifically needs the intersection of triviality and standard layout. So we don't need to reserve a term for it. Those few places where the standard expressly states that some type will be "POD" can simply be replaced by "trivial and standard layout", as appropriate.
Is this recursive requirement redundant?
Since both of the constituent requirements are individually recursive, the intersection of the two is recursive as well. So there is no explicit need to state that all subobjects are also POD. This was more than likely just a case of a copy-and-paste oddity, where the original definition said something like "all non-static data members must be POD types" and they just kept that statement as is.
Standard layoutness depends on standard layoutness of non-static members:
[class.prop]
A class S is a standard-layout class if it:
has no non-static data members of type non-standard-layout class (or array of such types) or reference,
...
Triviality also depends on triviality of non-static members. For conciseness, I've quoted only the rule for the default constructor, but the other special member functions have similar wording:
[class.default.ctor]
A default constructor is trivial if it is not user-provided and if:
- ...
- for all of the non-static data members of its class that are of class type (or array thereof), each such class has a trivial destructor.
As far as I can tell, the explicit requirement of PODness to apply to members is redundant, since it also implicitly follows from the requirements of being standard layout and trivial.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With