简体   繁体   中英

c++: May POD types contain const non-pointer members?

#include <iostream>

struct A {
  const int test_;
};

static_assert(std::is_pod<A>::value, "must be POD type");

int main()
{
    std::cout<<"Hello World";
    return 0;
}

On Clang and GCC std::is_pod<A>::value is true , while on ICC and MSVC it is false .

If const int test_; is replaced with either int test_; or const int* test_ then it also passes on ICC and MSVC.

What does the standard say?

N4659

12/10

A POD struct is a non-union class that is both a trivial class and a standard-layout class, and has no non-static data members of type non-POD struct, non-POD union (or array of such types).

For trivial

12/6

A trivial class is a class that is trivially copyable and has one or more default constructors

There is no available default constructor.

Further, for trivially copyable, the requirements include

12/6.2

that has at least one non-deleted copy constructor, move constructor, copy assignment operator, or move assignment operator

Since you include a const int , it's not trivially copyable (no assignment operators), so it is not a pod

^ I was wrong, it is copyable by having the constructors. I misread the "or" as "and"

One of the requirements for POD type is to be a trivial type.

[class]
10 A POD struct 109 is a non-union class that is both a trivial class and a standard-layout class, and has no non-static data members of type non-POD struct, non-POD union (or array of such types). where trivial type

while trivial is defined in the same section as

6 A trivial class is a class that is trivially copyable and has one or more default constructors (15.1), all of which are either trivial or deleted and at least one of which is not deleted.

Since A has a field with const-qualifier which requires mandatory initialization, its implicitly declared default constructor is deleted. Therefore A is not trivial type and not a POD type. So VS and ICC are correct here. But it is probably not a big deal since POD trait became deprecated in C++20 and should be avoided in code using preceding standards.

You can find an explanation of what is_pod tests for and what it does not test for here: https://en.cppreference.com/w/cpp/types/is_pod A description of what PODTypes are is here: https://en.cppreference.com/w/cpp/named_req/PODType

To meet the test of POD, the type has to be:

both trivial and standard-layout

TrivialType is defined here: https://en.cppreference.com/w/cpp/named_req/TrivialType

Standard Layout Type here: https://en.cppreference.com/w/cpp/named_req/StandardLayoutType

TrivialType further defines two requirements:

  • TriviallyCopyable
  • If the type is a class type or array thereof, the class has one or more eligible default constructors, all of which are trivial.

Trivially Copyable is defined here: https://en.cppreference.com/w/cpp/named_req/TriviallyCopyable

Based on this: http://www.cplusplus.com/reference/type_traits/is_trivially_copyable/ and Does a c++ struct have a default constructor? , it is clear that since implicit constructors are used, the struct is trivially copyable. Also see: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf page 41.

Since no constructor is defined, there is an implicit default constructor, therefore satisfying both requirements of a Trivial Type

Standard Layout requirements:

  • All non-static data members have the same access control
  • Has no virtual functions or virtual base classes
  • Has no non-static data members of reference type
  • All non-static data members and base classes are themselves standard layout types
  • Has no two (possibly indirect) base class subobjects of the same type
  • Has all non-static data members and bit-fields declared in the same class (either all in the derived or all in some base)
  • None of the base class subobjects has the same type as: for non-union types, as the first non-static data member (see empty base optimization), and, recursively, the first non-static data member of that data member if it has non-union class type, or all non-static data members of that data member if it has union type, or an element of that data member if it has array type, etc.

Therefore it has a standard layout as well.

Therefore, being of standard layout and trivial, the struct should be considered POD.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM