Title
Definition of POD is too strict
Status
cd1
Section
Clause [11] [class]
Submitter
Matt Austern

Created on 2006-03-20.00:00:00 last changed 188 months ago

Messages

Date: 2007-07-15.00:00:00

[Voted into the WP at the July, 2007 meeting as part of paper J16/07-0202 = WG21 N2342.]

Date: 2007-04-15.00:00:00

Proposed resolution (April, 2007):

Adoption of the POD proposal (currently J16/07-0090 = WG21 N2230) will resolve this issue.

Date: 2020-12-15.00:00:00

A POD struct (Clause 11 [class] paragraph 4) 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 that has no user-defined copy assignment operator and no user-defined destructor.” Meanwhile, an aggregate class (9.4.2 [dcl.init.aggr] paragraph 1) must have “no user-declared constructors, no private or protecte non-static data members, no base classes, and no virtual functions.”

This is too strict. The whole reason we define the notion of POD is for the layout compatibility guarantees in 11.4 [class.mem] paragraphs 14-17 and the byte-for-byte copying guarantees of 6.8 [basic.types] paragraph 2. None of those guarantees should be affected by the presence of ordinary constructors, any more than they're affected by the presence of any other member function. It’s silly for the standard to make layout and memcpy guarantees for this class:

 struct A {
    int n;
 };

but not for this one:

  struct B {
    int n;
    B(n_) : n(n_) { }
  };

With either A or B, it ought to be possible to save an array of those objects to disk with a single call to Unix’s write(2) system call or the equivalent. At present the standard says that it’s legal for A but not B, and there isn’t any good reason for that distinction.

Suggested resolution:

The following doesn’t fix all problems (in particular it still doesn’t let us treat pair<int, int> as a POD), but at least it goes a long way toward fixing the problem: in 9.4.2 [dcl.init.aggr] paragraph 1, change “no user-declared constructors” to “no nontrivial default constructor and no user-declared copy constructor.”

(Yes, I’m aware that this proposed change would also allow brace initialization for some types that don't currently allow it. I consider this to be a feature, not a bug.)

Mike Miller: I agree that something needs to be done about “POD,” but I’m not sure that this is it. My own take is that “POD” is used for too many different things — things that are related but not identical — and the concept should be split. The current definition is useful, as is, for issues regarding initialization and lifetime. For example, I wouldn’t want to relax the prohibition of jumping over a constructor call in 8.8 [stmt.dcl] (which is currently phrased in terms of POD types). On the other hand, I agree that the presence of a user-declared constructor says nothing about layout and bitwise copying. This needs (IMHO) a non-trivial amount of further study to determine how many categories we need (instead of just POD versus non-POD), which guarantees and prohibitions go with which category, the interaction of “memcpy initialization” (for want of a better term) with object lifetime, etc.

(See paper J16/06-0172 = WG21 N2102.)

History
Date User Action Args
2008-10-05 00:00:00adminsetstatus: wp -> cd1
2008-06-29 00:00:00adminsetmessages: + msg1725
2007-12-10 00:00:00adminsetstatus: review -> wp
2007-05-06 00:00:00adminsetmessages: + msg1481
2007-05-06 00:00:00adminsetstatus: open -> review
2006-03-20 00:00:00admincreate