grahamp
grahamp

Reputation: 125

Is there a valid use case where a non-POD struct is preferred to a class?

According to the (2003) standard's definition of a struct, it is a specialized case of a class, with different default access modifiers for members, functions, and base classes. It also goes on to define the requirements of a struct to be a POD-struct.

C++ 2003 Standard, ISO 14882 Section 9.0.4:

A structure is a class defined with the class-key struct; its members and base classes (clause 10) are public by default (clause 11). A union is a class defined with the class-key union; its members are public by default and it holds only one data member at a time (9.5). [Note: aggregates of class type are described in 8.5.1. ] 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-defined copy assignment 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 userdefined copy assignment operator and no user-defined destructor. A POD class is a class that is either a POD-struct or a POD-union.

Given this definition, the only differentiating factor between a non-POD struct and a class is the default access modifier.

Here's what I could imagine as the purpose of having non-POD structs:

Having non-POD structs can lead to pain when they're assumed to be POD by other systems, for example when passed around to C and back. To illustrate, this person ran into problems when a struct that was assumed to be POD was updated by another developer such that it was no longer POD. Because POD-ness isn't statically asserted by the compiler by default, the application would crash at run-time when that struct was used in contexts where only POD structs could be used. Even worse, I could imagine (though I don't know for certain if this is possible) a non-POD struct working in certain circumstances that require POD, and failing in others, leading to errors and crashes that are nothing short of arduous to track down.

Seeing as there are situations where having non-POD structs can lead to the realm of bizarre and broken behavior, what is the use of non-POD structs? Why aren't structs statically checked for POD-ness at compile-time (via std::is_pod in C++11 or the Boost equivalent)?

Upvotes: 0

Views: 1173

Answers (2)

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145379

“POD-ness isn't statically asserted by the compiler by default”

Oh?

#include <iostream>         // std::cout, std::endl
#include <type_traits>      // std::is_pod
#include <string>           // std::string, std::to_string
using namespace std;

struct A
{
    int x;
};

struct B
{
    string s;
};

int main()
{
    static bool const a = is_pod<A>::value;
    static_assert( a, "Ah..." );
    static_assert( !is_pod<B>::value, "Bah!" );
}

The reason that struct is allowed to be non-POD, as e.g. B above, i.e. why the language is designed this way, is probably to be found in Bjarne Stroustrup’s book “The Design and Evolution of C++”. And if not, then probably only Bjarne himself knows. Because this C++ generality of struct has been there since the very beginning.

Upvotes: 0

John Zwinck
John Zwinck

Reputation: 249424

I think it's a pointless historical accident, and frankly the class keyword never should have been added in C++ at all. Oh well!

It would often be annoying if a struct was required to be POD--you'd often start out with something POD, call it a "struct" just because you could, and then wind up having to change it in many places later on when you decide to make it non-POD.

Note that GCC (at least until recently) did not care if you (forward) declared something as a class in one place and as a struct elsewhere, or vice versa. Clang complains about this sort of thing (as it has every right to, though this does "break" some existing code).

Upvotes: 4

Related Questions