C++ Language Note:
Walter E. Brown
September 29, 1999; last updated November 29, 1999
This note documents the definition of a POD type according
to the International Standard for the C++ Programming Language [ISO/IEC
14882, first edition, 1998-09-01]. Related definitions are also provided,
as is interpretive commentary on the significance of a POD-type.
All references herein are to the Standard.
The term POD is an acronym.
It stands for "plain old data" [p. 5, footnote 4], and is intended to suggest
areas of substantive compatibility between comparable data types in C and
C++. The terms POD and
object are often used interchangeably to refer to an object
of POD type.
The term POD types collectively
refers to the following categories of C++ types, and encompasses both cv-qualified
versions of these as well as arrays of these [§3.9, ¶10; §9,
The term scalar types collectively
refers to the following categories of C++ types, and encompasses cv-qualified
versions of these [§3.9, ¶10]:
scalar types, and
POD class types.
The term arithmetic types collectively
refers to the following categories of C++ types [§3.9.1, ¶8]:
pointer types, and
The term integral types collectively
refers to the following C++ types [§3.9.1, ¶7]:
integral (also known as integer) types, and
floating (also known as floating point) types.
The term floating types collectively
refers to the C++ types
and long double [§3.9.1, ¶8].
signed integer types (signed char, short,
unsigned integer types (unsigned char, unsigned
short, unsigned int, unsigned
char and wchar_t, and
The term enumeration types
collectively refers to distinct types, known as enumerations,
that comprise sets of named constant values [§3.9.1, ¶1; §7.2,
The term pointer types collectively
refers to the following categories of C++ types [§3.9.2, ¶1]:
The term pointer-to-member types
collectively refers to the following C++ types [§3.9.2, ¶1]:
pointer-to-void (void *),
pointer-to-object and pointer-to-static-member-data (both of the form T*
when pointing to an object of type T), and
pointer-to-function and pointer-to-static-member-function (both of the
form T (*)(...) when pointing
to a function that returns an object of type T).
The term POD class types collectively
refers to aggregate classes (POD-struct
types) and aggregate
types) that have none of the following as members
pointer-to-nonstatic-member-data (of the form T C::*
when pointing to one of class C's data members that has
type T), and
pointer-to-nonstatic-member-functions (of the form T (C::*)(...)
when pointing to one of class C's member functions
that returns an object of type T).
The term aggregate refers to
an array or class that has none of the following characteristics
non-static data (including arrays) of any pointer-to-member type,
non-static data (including arrays) of any non-POD class type,
non-static data of any reference type,
user-defined copy assignment operator, nor
private or protected non-static data members,
base classes, nor
POD types have primary significance as an important source of compatibility
with ANSI C code. As such, objects of these types share several characteristics
with their C equivalents. These characteristics include initialization,
copying, layout, and addressing.
As an example of the sometimes-subtle distinction between POD and non-POD
types, consider the initializations implied by each of the following new-expressions
||POD type T
||non-POD type T
| new T
| new T()
| new T(x)
||always initialized via a constructor
Thus, an object (or an array) of non-POD type is always guaranteed initialization,
while an instance (or an array) of a POD type may be left uninitialized.
Other POD-related C++ characteristics include the following:
The bytes constituting a POD object are contiguous [§1.8, ¶5].
"POD-struct ... types are layout-compatible if they have the same number
of members, and corresponding members (in order) have layout-compatible
types" [§9.2, ¶14].
POD-union ... types are layout-compatible if they have the same number
of members, and corresponding members (in any order) have layout-compatible
types" [§9.2, ¶15].
A non-const POD object declared with no initializer has an "indeterminate
initial value" [§8.5, ¶9].
Default initialization of a POD object is zero initialization [§8.5,
A static POD object declared with an initializer is given
its initial value:
if local, "before its block is first entered" [§6.7, ¶4]; else
if non-local, "before any dynamic initialization takes place" [§3.6.2,
The bytes constituting a POD object can be copied (e.g., via memcpy())
to a sufficiently large array of char or unsigned
char and back again without changing the object's value [§3.9,
to another object of the same POD-type, in which case the second object's
value will be the same as that of the first [§3.9, ¶3].
Any POD type may be used as the "character" type in the standard's templated
string classes [§21, ¶1].
The address of a POD object can be an address constant expression (or part
of one) [§5.19, ¶4], while a reference to a POD member can be
a reference constant expression [§5.19, ¶5].
"A pointer to a POD-struct object, suitably converted using a reinterpret_cast,
points to its initial member ... and vice versa" [§9.2, ¶17].