1209

I've come across this term POD-type a few times.
What does it mean?

Arsen Khachaturyan
  • 7,904
  • 4
  • 42
  • 42
oz10
  • 153,307
  • 27
  • 93
  • 128
  • 1
    Also see [http://stackoverflow.com/questions/2293796](http://stackoverflow.com/questions/2293796) – Lazer Jun 13 '10 at 07:16
  • 5
    please see http://chat.stackoverflow.com/transcript/message/213026#213026 and the following day's messages for discussion about the accepted answer – Johannes Schaub - litb Dec 22 '10 at 10:51
  • 2
    Also http://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special – Mihran Hovsepyan Jun 23 '11 at 08:45
  • @paxos1977: Please change your selection of "solution" (currently Hewgill's answer) so that a fundamentally wrong answer doesn't mislead googlers who end up here. – Cheers and hth. - Alf Aug 16 '16 at 00:15
  • We've concluded that a c-style string is NOT a POD type because 1.) the pointer is not contiguous with the string data, and 2.) in order to make a string a POD type, you would need to ensure the type had a nil-term char in it within the predefined size of the POD type, leading to undefined behavior. –  May 25 '18 at 03:53
  • 1
    @user2356685 what do you mean, and who are we? There is pointer to string and storage where array of chars is located, both are treated as trivial data. Structure which contains pointer to char is still a POD, the fact that it doesn't own string's storage is a different, unrelated fact. – Swift - Friday Pie Apr 25 '19 at 17:22

9 Answers9

843

POD stands for Plain Old Data - that is, a class (whether defined with the keyword struct or the keyword class) without constructors, destructors and virtual members functions. Wikipedia's article on POD goes into a bit more detail and defines it as:

A Plain Old Data Structure in C++ is an aggregate class that contains only PODS as members, has no user-defined destructor, no user-defined copy assignment operator, and no nonstatic members of pointer-to-member type.

Greater detail can be found in this answer for C++98/03. C++11 changed the rules surrounding POD, relaxing them greatly, thus necessitating a follow-up answer here.

Community
  • 1
  • 1
Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • Hmmm... I guess I prefer more correct technical term of "intrinsic type" to this kind of slang. ;) – oz10 Sep 28 '08 at 18:41
  • 38
    There's a difference. Intrinsic types are the "builtin" language primitives. POD types are these, plus aggregations of these (and other PODs). – Adam Wright Sep 28 '08 at 18:44
  • POD: int,char,float etc. The built in types. – Martin York Sep 28 '08 at 19:52
  • 2
    @Greg Hewgill: Why do we need to differentiate between POD's and non-POD's at all? – Lazer Jun 13 '10 at 07:53
  • 70
    POD types have characteristics that non-POD types do not. For example, if you have a global, const, POD-type struct, you can initialize its contents with brace notation, it is put into read-only memory, and no code needs to be generated to initialize it (constructor or otherwise), because it's part of the program image. This is important for embedded folks who often have tight constraints on RAM, ROM, or Flash. – Mike DeSimone Nov 14 '10 at 18:11
  • 49
    In C++11, you can do std::is_pod() to tell whether MyType is POD. – allyourcode Mar 31 '14 at 21:24
  • 11
    Bjarne Stroustrup's [Technical Report on C++ Performance](http://www.stroustrup.com/performanceTR.pdf) states that the C++ standard describes a POD as being "_a data type which is compatible with the equivalent data type in C in layout, initialization, and its ability to be copied with memcpy_". Perhaps a distinction should be made between a POD type and a POD structure. – Sam Hobbs Jan 13 '15 at 19:59
  • 11
    **−1** This answer is still fundamentally wrong & misleading as of 16th Aug 2016: POD types are not restricted to be class types. – Cheers and hth. - Alf Aug 16 '16 at 00:13
  • What about a string? Strings are in C, but you can't just copy them with memcpy. –  May 16 '18 at 01:50
  • A string by default is a ASCII string, and UTF-8 is a not built-in. A string could use a UTF-8 base class with a UTF-16 and UTF-32 subclass. By this definition, not all strings are POD types. If not all strings are POD types, then strings by definition would not be a POD type. No one mentions strings in the POD argument probably for this very reason. Where are the doctors? –  May 16 '18 at 02:18
  • So then by that definition then a String is not a POD because you cannot copy it directly with memcpy. –  May 25 '18 at 03:50
  • 3
    @Cale There's no such thing as a "string" type in C. There's a `char *`, but the vital distinction there is that while _the type itself_ is in fact a POD type, its _conceptual value_ -- i.e. what you think of it representing, that array of characters -- isn't POD, for the reasons you give. The actual pointer itself, the `char *` you pass around, is basically an integer in fancy dress, and works give-or-take the same as an `int` for the purposes if figuring if something is a POD type. However, to copy the _conceptual string_ that it represents, yes, you need to do more. – Nic Jun 26 '18 at 20:54
  • @NicHartley: That's a critical point. An array of characters is a POD, and in C, that's all you've got. The concept of a "string" is an artifact of a library of functions that process zero-terminated arrays of characters. – David C. Feb 27 '19 at 18:59
  • POD sounds quite similar to [blittable types of C#](https://learn.microsoft.com/en-us/dotnet/framework/interop/blittable-and-non-blittable-types) – zwcloud Apr 13 '20 at 09:40
  • This answer is very incomplete and can be misleading. A POD is not necessarily a POD Class. It could be an array, it could be a scalar, etc. It's much more nuanced. See [this](https://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special/7189821#7189821) for a detailed breakdown. – Michele Piccolini Feb 08 '22 at 13:54
  • Isn't your text contradicting with the quote you have put after it? I mean in the "no constructors" part? – Student4K Mar 04 '23 at 13:05
420

Very informally:

A POD is a type (including classes) where the C++ compiler guarantees that there will be no "magic" going on in the structure: for example hidden pointers to vtables, offsets that get applied to the address when it is cast to other types (at least if the target's POD too), constructors, or destructors. Roughly speaking, a type is a POD when the only things in it are built-in types and combinations of them. The result is something that "acts like" a C type.

Less informally:

  • int, char, wchar_t, bool, float, double are PODs, as are long/short and signed/unsigned versions of them.
  • pointers (including pointer-to-function and pointer-to-member) are PODs,
  • enums are PODs
  • a const or volatile POD is a POD.
  • a class, struct or union of PODs is a POD provided that all non-static data members are public, and it has no base class and no constructors, destructors, or virtual methods. Static members don't stop something being a POD under this rule. This rule has changed in C++11 and certain private members are allowed: Can a class with all private members be a POD class?
  • Wikipedia is wrong to say that a POD cannot have members of type pointer-to-member. Or rather, it's correct for the C++98 wording, but TC1 made explicit that pointers-to-member are POD.

Formally (C++03 Standard):

3.9(10): "Arithmetic types (3.9.1), enumeration types, pointer types, and pointer to member types (3.9.2) and cv-qualified versions of these types (3.9.3) are collectively caller scalar types. Scalar types, POD-struct types, POD-union types (clause 9), arrays of such types and cv-qualified versions of these types (3.9.3) are collectively called POD types"

9(4): "A POD-struct is an aggregate class that has no non-static data members of type non-POD-struct, non-POD-union (or array of such types) or reference, and has no user-define copy operator and no user-defined destructor. Similarly a POD-union is an aggregate union that has no non-static data members of type non-POD-struct, non-POD-union (or array of such types) or reference, and has no user-define copy operator and no user-defined destructor.

8.5.1(1): "An aggregate is an array or class (clause 9) with no user-declared constructors (12.1), no private or protected non-static data members (clause 11), no base classes (clause 10) and no virtual functions (10.3)."

Community
  • 1
  • 1
Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
  • 3
    You have formal/less formal. You could add rule of thumb. Built in types and aggregations of Built in types (or something like that). In addition to get the exact definition we need to make the knowledge easy to use. – Martin York Sep 28 '08 at 19:58
  • I've added a "roughly speaking" clause. I don't want to say "aggregate" because it's a jargon term, and a casual reader wouldn't know that it means no virtual functions, no private members, etc. – Steve Jessop Sep 28 '08 at 20:08
  • 1
    You're a bit wrong on the "offsets when _cast_to_ another type" bit. Those offsets are applied when casting to a base or derived class. So, if you cast from a POD base class pointer to a non-POD derived class, you may still encounter an adjustement. – MSalters Sep 29 '08 at 12:05
  • 1
    @Steve Jessop: Why do we need to differentiate between POD's and non-POD's at all? – Lazer Jun 13 '10 at 08:03
  • 9
    @Lazer: that's a whole other question, "how do PODs behave?" as opposed to "what does POD mean?". In summary the difference relates to initialisation (hence also use of memcpy to duplicate objects), compatibility with C struct layout for that compiler, and pointer up- and down-casting. PODs "act like C types", non-PODs aren't guaranteed to do so. So if you want your type to portably act like a C struct, you must ensure that it is POD, so you need to know the difference. – Steve Jessop Jun 13 '10 at 18:13
  • @Lazer: A (belated, but) very comprehensive reply can be found here: http://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-how-are-they-special/4178176#4178176 – sbi Nov 14 '10 at 18:46
  • 1
    I like this one. I wish this one would have been accepted. Very nice! I like how the first paragraph fits the description of "POF" too ("plain old function", a term also defined by the Standard). – Johannes Schaub - litb Dec 22 '10 at 10:22
  • 4
    @muntoo: it has been, really I was commenting on the answer that quotes outdated info from Wikipedia. I could edit that answer, I suppose, but I smell trouble if I go around editing other people's answer to agree with mine, no matter how right I think I am. – Steve Jessop Jun 17 '12 at 01:45
  • So then is a string a POD type or what? All of the posts don't touch the subjects with a 10 foot pole. It's the question EVERYONE wants to know... Yes a ASCII string IS a built-in type, but what about a UTF-16 or UTF-32 string? Those aren't built-in, but are still strings,and there COULD be magic going on behind the scenes with OO programming techniques (i.e. abstract string stored as UTF-8 then sub-classed to UTF-16 or UTF-32). If one type of string is not a POD type, then all of them aren't POD types by induction. –  May 16 '18 at 02:08
  • 1
    @Cale: the C++ string types all have constructors, so in the C++03 definition they are not aggregates and hence not POD. Likewise, my "very informally" and "less informally" definitions both state that classes cannot be POD if they have a constructor. For a given standard class, you can check whether or not it has constructors, destructors, virtual member functions, base classes, or copy operators, by reading the spec for that class (or class template). – Steve Jessop May 22 '18 at 13:31
  • The conclusion me and a doctor of CS friend came to was that you could "pretend" a string is a POD type, but in order to ensure the nil-term char is there, it would require a constructor. You would just get undefined behavior. –  May 25 '18 at 03:49
  • 2
    @Cale: pretend what you like :-) There are several things you're allowed to do with POD that won't work with strings. Using them without construction is one, but freeing the memory without first destructing the object is another, and copying the object to a new location and using it there is a third. – Steve Jessop May 26 '18 at 11:21
  • You mention "vtables" but don't explain them. Here's some great info. on `vptr`s and `vtbl`s: https://www.drdobbs.com/cpp/storage-layout-of-polymorphic-objects/240012098. – Gabriel Staples Aug 29 '20 at 03:00
30

Plain Old Data

In short, it is all built-in data types (e.g. int, char, float, long, unsigned char, double, etc.) and all aggregation of POD data. Yes, it's a recursive definition. ;)

To be more clear, a POD is what we call "a struct": a unit or a group of units that just store data.

Kotauskas
  • 1,239
  • 11
  • 31
ugasoft
  • 3,778
  • 7
  • 27
  • 23
  • 13
    It's true that we sometimes call them 'a struct'. However we're always wrong to do so, since a struct is not necessarily a POD-type. – Steve Jessop Sep 28 '08 at 19:21
  • 7
    obviously... struct and class are almost equivalent, but in "the business" we call 'a struct' a simple data collector, usually without ctors and dtor, usually with value semantics... – ugasoft Sep 28 '08 at 21:52
  • 2
    For me it was C++ wrong to make struct identical to the class keyword or close to: struct only adds public default access to class. I was simpler to make C-like structs and we would have had PODs on day 0 of c++. – user1708042 Sep 16 '15 at 12:14
  • ugasoft: your answer may be misleading - your comment explained the missing detail that it is used like that in practice, rather than standard. Whoa, 8 years, are you even here? ;-) – hauron Mar 10 '16 at 08:14
  • With the exception of a string because you can't copy it with memcpy without first determining the string length. –  May 25 '18 at 03:51
  • @ugasoft actually struct and class are not equivalent, because all variables declared in a struct is public, whereas in a class you can have private variables as well, so using struct can led to security problems in the long run, that is why they are not used very often in OOP. – Yunfei Chen Jul 01 '20 at 21:05
  • Can anyone clarify for me what ctors and dtor are because I have never seen them in structs or seen a struct referred to as a simple data collector??? – Yunfei Chen Jul 01 '20 at 21:06
  • @user1708042 Well, the reason why struct and class are identical, save for default access qualifier, is that, under the C++ compiler hood, the implementation of a class really is just a struct. Methods really are just functions that take "a pointer to a struct" (a.k.a. "this") to access that instance of the struct as the first parameter, and "virtual tables" are just function pointers inside that struct (so they can be changed). The only reason to add the "class" keyword was because C "structs" are public by default, which violates the OOP "black box" principle. – Bob Jun 28 '22 at 08:49
25

Why do we need to differentiate between POD's and non-POD's at all?

C++ started its life as an extension of C. While modern C++ is no longer a strict superset of C, people still expect a high level of compatibility between the two. The "C ABI" of a platform also frequently acts as a de-facto standard inter-language ABI for other languages on the platform.

Roughly speaking, a POD type is a type that is compatible with C and perhaps equally importantly is compatible with certain ABI optimisations.

To be compatible with C, we need to satisfy two constraints.

  1. The layout must be the same as the corresponding C type.
  2. The type must be passed to and returned from functions in the same way as the corresponding C type.

Certain C++ features are incompatible with this.

Virtual methods require the compiler to insert one or more pointers to virtual method tables, something that doesn't exist in C.

User-defined copy constructors, move constructors, copy assignments and destructors have implications for parameter passing and returning. Many C ABIs pass and return small parameters in registers, but the references passed to the user defined constructor/assigment/destructor can only work with memory locations.

So there is a need to define what types can be expected to be "C compatible" and what types cannot. C++03 was somewhat over-strict in this regard, any user-defined constructor would disable the built-in constructors and any attempt to add them back in would result in them being user-defined and hence the type being non-pod. C++11 opened things up quite a bit, by allowing the user to re-introduce the built-in constructors.

plugwash
  • 9,724
  • 2
  • 38
  • 51
16

Examples of all non-POD cases with static_assert from C++11 to C++17 and POD effects

std::is_pod was added in C++11, so let's consider that standard onwards for now.

std::is_pod will be removed from C++20 as mentioned at https://stackoverflow.com/a/48435532/895245 , let's update this as support arrives for the replacements.

POD restrictions have become more and more relaxed as the standard evolved, I aim to cover all relaxations in the example through ifdefs.

libstdc++ has at tiny bit of testing at: https://github.com/gcc-mirror/gcc/blob/gcc-8_2_0-release/libstdc%2B%2B-v3/testsuite/20_util/is_pod/value.cc but it just too little. Maintainers: please merge this if you read this post. I'm lazy to check out all the C++ testsuite projects mentioned at: https://softwareengineering.stackexchange.com/questions/199708/is-there-a-compliance-test-for-c-compilers

#include <type_traits>
#include <array>
#include <vector>

int main() {
#if __cplusplus >= 201103L
    // # Not POD
    //
    // Non-POD examples. Let's just walk all non-recursive non-POD branches of cppreference.
    {
        // Non-trivial implies non-POD.
        // https://en.cppreference.com/w/cpp/named_req/TrivialType
        {
            // Has one or more default constructors, all of which are either
            // trivial or deleted, and at least one of which is not deleted.
            {
                // Not trivial because we removed the default constructor
                // by using our own custom non-default constructor.
                {
                    struct C {
                        C(int) {}
                    };
                    static_assert(std::is_trivially_copyable<C>(), "");
                    static_assert(!std::is_trivial<C>(), "");
                    static_assert(!std::is_pod<C>(), "");
                }

                // No, this is not a default trivial constructor either:
                // https://en.cppreference.com/w/cpp/language/default_constructor
                //
                // The constructor is not user-provided (i.e., is implicitly-defined or
                // defaulted on its first declaration)
                {
                    struct C {
                        C() {}
                    };
                    static_assert(std::is_trivially_copyable<C>(), "");
                    static_assert(!std::is_trivial<C>(), "");
                    static_assert(!std::is_pod<C>(), "");
                }
            }

            // Not trivial because not trivially copyable.
            {
                struct C {
                    C(C&) {}
                };
                static_assert(!std::is_trivially_copyable<C>(), "");
                static_assert(!std::is_trivial<C>(), "");
                static_assert(!std::is_pod<C>(), "");
            }
        }

        // Non-standard layout implies non-POD.
        // https://en.cppreference.com/w/cpp/named_req/StandardLayoutType
        {
            // Non static members with different access control.
            {
                // i is public and j is private.
                {
                    struct C {
                        public:
                            int i;
                        private:
                            int j;
                    };
                    static_assert(!std::is_standard_layout<C>(), "");
                    static_assert(!std::is_pod<C>(), "");
                }

                // These have the same access control.
                {
                    struct C {
                        private:
                            int i;
                            int j;
                    };
                    static_assert(std::is_standard_layout<C>(), "");
                    static_assert(std::is_pod<C>(), "");

                    struct D {
                        public:
                            int i;
                            int j;
                    };
                    static_assert(std::is_standard_layout<D>(), "");
                    static_assert(std::is_pod<D>(), "");
                }
            }

            // Virtual function.
            {
                struct C {
                    virtual void f() = 0;
                };
                static_assert(!std::is_standard_layout<C>(), "");
                static_assert(!std::is_pod<C>(), "");
            }

            // Non-static member that is reference.
            {
                struct C {
                    int &i;
                };
                static_assert(!std::is_standard_layout<C>(), "");
                static_assert(!std::is_pod<C>(), "");
            }

            // Neither:
            //
            // - has no base classes with non-static data members, or
            // - has no non-static data members in the most derived class
            //   and at most one base class with non-static data members
            {
                // Non POD because has two base classes with non-static data members.
                {
                    struct Base1 {
                        int i;
                    };
                    struct Base2 {
                        int j;
                    };
                    struct C : Base1, Base2 {};
                    static_assert(!std::is_standard_layout<C>(), "");
                    static_assert(!std::is_pod<C>(), "");
                }

                // POD: has just one base class with non-static member.
                {
                    struct Base1 {
                        int i;
                    };
                    struct C : Base1 {};
                    static_assert(std::is_standard_layout<C>(), "");
                    static_assert(std::is_pod<C>(), "");
                }

                // Just one base class with non-static member: Base1, Base2 has none.
                {
                    struct Base1 {
                        int i;
                    };
                    struct Base2 {};
                    struct C : Base1, Base2 {};
                    static_assert(std::is_standard_layout<C>(), "");
                    static_assert(std::is_pod<C>(), "");
                }
            }

            // Base classes of the same type as the first non-static data member.
            // TODO failing on GCC 8.1 -std=c++11, 14 and 17.
            {
                struct C {};
                struct D : C {
                    C c;
                };
                //static_assert(!std::is_standard_layout<C>(), "");
                //static_assert(!std::is_pod<C>(), "");
            };

            // C++14 standard layout new rules, yay!
            {
                // Has two (possibly indirect) base class subobjects of the same type.
                // Here C has two base classes which are indirectly "Base".
                //
                // TODO failing on GCC 8.1 -std=c++11, 14 and 17.
                // even though the example was copy pasted from cppreference.
                {
                    struct Q {};
                    struct S : Q { };
                    struct T : Q { };
                    struct U : S, T { };  // not a standard-layout class: two base class subobjects of type Q
                    //static_assert(!std::is_standard_layout<U>(), "");
                    //static_assert(!std::is_pod<U>(), "");
                }

                // Has all non-static data members and bit-fields declared in the same class
                // (either all in the derived or all in some base).
                {
                    struct Base { int i; };
                    struct Middle : Base {};
                    struct C : Middle { int j; };
                    static_assert(!std::is_standard_layout<C>(), "");
                    static_assert(!std::is_pod<C>(), "");
                }

                // None of the base class subobjects has the same type as
                // for non-union types, as the first non-static data member
                //
                // TODO: similar to the C++11 for which we could not make a proper example,
                // but with recursivity added.

                // TODO come up with an example that is POD in C++14 but not in C++11.
            }
        }
    }

    // # POD
    //
    // POD examples. Everything that does not fall neatly in the non-POD examples.
    {
        // Can't get more POD than this.
        {
            struct C {};
            static_assert(std::is_pod<C>(), "");
            static_assert(std::is_pod<int>(), "");
        }

        // Array of POD is POD.
        {
            struct C {};
            static_assert(std::is_pod<C>(), "");
            static_assert(std::is_pod<C[]>(), "");
        }

        // Private member: became POD in C++11
        // https://stackoverflow.com/questions/4762788/can-a-class-with-all-private-members-be-a-pod-class/4762944#4762944
        {
            struct C {
                private:
                    int i;
            };
#if __cplusplus >= 201103L
            static_assert(std::is_pod<C>(), "");
#else
            static_assert(!std::is_pod<C>(), "");
#endif
        }

        // Most standard library containers are not POD because they are not trivial,
        // which can be seen directly from their interface definition in the standard.
        // https://stackoverflow.com/questions/27165436/pod-implications-for-a-struct-which-holds-an-standard-library-container
        {
            static_assert(!std::is_pod<std::vector<int>>(), "");
            static_assert(!std::is_trivially_copyable<std::vector<int>>(), "");
            // Some might be though:
            // https://stackoverflow.com/questions/3674247/is-stdarrayt-s-guaranteed-to-be-pod-if-t-is-pod
            static_assert(std::is_pod<std::array<int, 1>>(), "");
        }
    }

    // # POD effects
    //
    // Now let's verify what effects does PODness have.
    //
    // Note that this is not easy to do automatically, since many of the
    // failures are undefined behaviour.
    //
    // A good initial list can be found at:
    // https://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special/4178176#4178176
    {
        struct Pod {
            uint32_t i;
            uint64_t j;
        };
        static_assert(std::is_pod<Pod>(), "");

        struct NotPod {
            NotPod(uint32_t i, uint64_t j) : i(i), j(j) {}
            uint32_t i;
            uint64_t j;
        };
        static_assert(!std::is_pod<NotPod>(), "");

        // __attribute__((packed)) only works for POD, and is ignored for non-POD, and emits a warning
        // https://stackoverflow.com/questions/35152877/ignoring-packed-attribute-because-of-unpacked-non-pod-field/52986680#52986680
        {
            struct C {
                int i;
            };

            struct D : C {
                int j;
            };

            struct E {
                D d;
            } /*__attribute__((packed))*/;

            static_assert(std::is_pod<C>(), "");
            static_assert(!std::is_pod<D>(), "");
            static_assert(!std::is_pod<E>(), "");
        }
    }
#endif
}

GitHub upstream.

Tested with:

for std in 11 14 17; do echo $std; g++-8 -Wall -Werror -Wextra -pedantic -std=c++$std pod.cpp; done

on Ubuntu 18.04, GCC 8.2.0.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
12

As I understand POD (PlainOldData) is just a raw data - it does not need:

  • to be constructed,
  • to be destroyed,
  • to have custom operators.
  • Must not have virtual functions,
  • and must not override operators.

How to check if something is a POD? Well, there is a struct for that called std::is_pod:

namespace std {
// Could use is_standard_layout && is_trivial instead of the builtin.
template<typename _Tp>
  struct is_pod
  : public integral_constant<bool, __is_pod(_Tp)>
  { };
}

(From header type_traits)


Reference:

набиячлэвэли
  • 4,099
  • 4
  • 29
  • 40
10

A POD (plain old data) object has one of these data types--a fundamental type, pointer, union, struct, array, or class--with no constructor. Conversely, a non-POD object is one for which a constructor exists. A POD object begins its lifetime when it obtains storage with the proper size for its type and its lifetime ends when the storage for the object is either reused or deallocated.

PlainOldData types also must not have any of:

  • Virtual functions (either their own, or inherited)
  • Virtual base classes (direct or indirect).

A looser definition of PlainOldData includes objects with constructors; but excludes those with virtual anything. The important issue with PlainOldData types is that they are non-polymorphic. Inheritance can be done with POD types, however it should only be done for ImplementationInheritance (code reuse) and not polymorphism/subtyping.

A common (though not strictly correct) definition is that a PlainOldData type is anything that doesn't have a VeeTable.

amitabes
  • 117
  • 1
  • 3
  • Yuor answer is very good, but this question has accepted answer 8 years ago, plus several other good answers. You can contribute more to SO if you use you knowledge to answer questions that are not yet answered ))) – mvidelgauz Aug 16 '16 at 12:03
5

The concept of POD and the type trait std::is_pod will be deprecated in C++20. See this question for further information.

ThomasMcLeod
  • 7,603
  • 4
  • 42
  • 80
-7

With C++, Plain Old Data doesn't just mean that things like int, char, etc are the only types used. Plain Old Data really means in practice that you can take a struct memcpy it from one location in memory to another and things will work exactly like you would expect (i.e. not blow up). This breaks if your class, or any class your class contains, has as a member that is a pointer or a reference or a class that has a virtual function. Essentially, if pointers have to be involved somewhere, its not Plain Old Data.

Mark Kegel
  • 4,476
  • 3
  • 21
  • 21