Plain Old Data

It seems perverse that the C++ gods had to go back and make up a special term for unadorned data, but that's what happened.

Bjarne Stroustrup's C with Classes and later C++ provided programmers with all sorts of powerful capabilities. However, some features, most importantly virtual methods and multiple inheritance, affected the internal structure of classes that used them. Not only that, different implementers of C++ were free to implement the structure changes in whatever way they desired, as long as it worked. The same source code compiled on different compilers on the same platform might result in radically different object structures.

At first glance, this appeared to go against a fundamental goal that Bjarne Stroustrup had set for C++, the notion that you don't pay for what you don't use. Looking further, however, it was clear that any implementation of these features carried some overhead, and leaving it up to the implementer was the best decision.

Another important design goal of C++ was for its code to be linkable to libraries written in other languages, especially C. This goal would have been defeated if the C++ implementation could interfere with all classes. To the rescue came "you don't pay for what you don't use": After identifying all of the features that had to interfere with an object structure, the classes that didn't use these features had to be left unmolested.

And so the notion of a "plain old data" type developed.




The 1998 C++ Standard1 defines (9.0.4):
A POD-struct is an aggregate class2 that has no non-static data members of type pointer-to-member, non-POD-struct, non-POD-union (or array of such types) and has no user-defined copy assignment operator and no user defined destructor. Similarly a POD-union is an aggregate union...

In other words, a POD-struct (union) is a struct (union) that would compile in C, with the additional possibility of (non-virtual) function members that aren't in the Big Three.

Earlier3 in the standard, (3.9.0.10), basic.types,
Scalar types, POD-struct types, POD-union types, arrays of such types, and cv-qualified versions of such types are collectively called POD types.
A C++ programmer is permitted to do all sorts of tricks with POD types, things familiar to C hackers. Consider the following declarations, all of POD types:

struct pt2 { int x, y };
struct pt3 { int x, y, z };
union u23 {
           pt2 p2;
           pt3 p3;
          }
struct m { int x; const int y; };

  • A POD occupies contiguous bytes of storage.
  • You can use a POD as an argument to a function declared with an ellipsis and retrieve it with va_arg.
  • A POD created as an automatic variable or with a new-expression without an initializer has an indeterminate value (saving the time it takes to zero-initialize the variable).  You can jump into a block past such a declaration!

    foo()
    {
     int y;       // y is garbage, but ok
     pt2 *p;      // p is garbage, but ok
     p = new pt2; // *p is garbage, but ok
     y = 5;       // now y == 5
     goto bar;    // evil, but well-formed
     {
      pt2 q;      // q is garbage, but ok
      bar: y = 6; // now y == 6
     }
    }


     
  • You can use an initializer-list in curly braces to initialize a POD-struct, since it is an aggregate:

    pt2 p = { 3, 5 };

     
  • (9.2.17) You can reinterpret_cast a pointer to a POD struct to a pointer to its first member.

    pt2 p = { 3, 5 };
    int *q;
    q = reinterpret_cast<int *>(&p); // *q == 3


     
  • You can memcpy the object to an array of char and back and it will retain the same value:

    unsigned char ac sizeof(pt3);
    pt3 p = {34, 65, 78};
    pt3 q;
    memcpy (ac, &p, sizeof (pt3));
    memcpy (&q, ac, sizeof (pt3);  // now p == q


     
  • Common initial sections of unions are layout-compatible, and so the following is not undefined behavior:

    u23 u;
    int y;
    u.p2.y = 5;
    y = u.p3.y; // now y == 5


     
  • a std::basic_string or std::basic_xstream template can be specialized with any POD type (so long as you fulfill the other requirements).

1International Standard ISO-IEC 14882, Programming Languages -- C++, published by the American National Standards Institute, © 1998 Information Technology Industry Council.
2a class which can be initialized with a list of constants enclosed in curly braces, leaving out anything with protected or private data members, base classes, user-declared-constructors, or virtual function members.
3One of the things that makes the Standard so diffcult to interpret its the fact that things are not defined sequentially. Concepts are frequently referenced before they are defined.