<html>

<head>
<meta http-equiv="Content-Language" content="en-us">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>POD's Revisited</title>
</head>

<body>

<p>Doc. no.&nbsp;&nbsp; WG21/N2062=06-0132<br>
Date:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%Y-%m-%d" startspan -->2006-09-06<!--webbot bot="Timestamp" endspan i-checksum="12590" --><br>
Project:&nbsp;&nbsp;&nbsp;&nbsp; Programming Language C++<br>
Reply to:&nbsp;&nbsp; Beman Dawes &lt;<a href="mailto:bdawes@acm.org">bdawes@acm.org</a>&gt;</p>

<h1>POD's Revisited</h1>

<p><a href="#Introduction">Introduction</a><br>
<a href="#Features">Features and benefits of POD types</a><br>
<a href="#Motivating-examples">Motivating examples</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#std::pair-example">std::pair example</a><br>
&nbsp;&nbsp;&nbsp; <a href="#Endian-example">Endian example</a><br>
&nbsp;&nbsp;&nbsp; <a href="#Two-structs-example">Two structs example</a><br>
&nbsp;&nbsp;&nbsp; <a href="#Atomic">Atomic example</a><br>
<a href="#Coupling">Coupling between POD's and aggregates</a><br>
<a href="#Rationale">Rationale for changes</a><br>
<a href="#Proposed">Proposed changes to the Working Paper</a><br>
&nbsp;&nbsp;&nbsp; <a href="#POD-in-Standard">POD in the Standard, with changes</a><br>
<a href="#Impact">Impact on existing code</a><br>
<a href="#Interaction">Interactions with other proposals</a><br>
<a href="#Acknowledgements">Acknowledgements</a><br>
<a href="#References">References</a></p>

<h2><a name="Introduction">Introduction</a></h2>

<p>This paper proposes resolutions for
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2029.html#568">Core 
Issue 568</a>, <b>Definition of POD is 
too strict,</b> submitted by Matt Austern.</p>

<p>The current working paper has several problems with POD's:</p>

<ul>
  <li><i><b>Overly strict requirements.</b></i> This forces users to make unwise 
  design choices, such as reliance on undefined behavior. 
  See <a href="#Motivating-examples">Motivating examples</a>.<br>
&nbsp;</li>
  <li><i><b>Coupling between POD's and aggregates.</b></i> The current 
  definition of POD depends by reference on the definition of aggregate, causing 
  several difficulties. See <a href="#Coupling">Coupling between POD's and 
  aggregates</a>.<br>
&nbsp;</li>
  <li><b><i>Coupling between byte copyability needs and other needs.</i></b> 
  The Standard describes requirements as POD or non-POD in some places where 
  byte-for-byte copyability is the only actual concern. Separating these 
  two needs would result in a cleaner specification.</li>
</ul>

<h2><a name="Features">Features</a> and benefits of POD types</h2>

<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
  <tr>
    <td width="50%" align="center"><b><i>Features</i></b></td>
    <td width="50%" align="center"><i><b>Benefits</b></i></td>
  </tr>
  <tr>
    <td width="50%" valign="top">Byte copyable guarantees [<a href="#3.9/2">3.9<b><i> <font face="Times New Roman"></font></i></b>2-3, basic.types</a>]</td>
    <td width="50%">
    <ul>
      <li>Programs tcan safely apply coding optimizations, particularly <code>
  std::memcpy</code>.</li>
    </ul>
    </td>
  </tr>
  <tr>
    <td width="50%" valign="top">C layout-compatible guarantees, including 
    including byte copyable, and [<a href="#class.mem">9.2<b><i> <font face="Times New Roman"></font></i></b>14-17, class.mem</a>]</td>
    <td width="50%"><ul>
  <li>C++ programs can interoperate with 
  functions written in C and other languages.</li>
  <li>C++ programs can, after considering compiler, alignment, and data type 
  constraints, perform binary I/O such that files to interoperate with other 
  languages and platforms.</li>
  </ul>

    </td>
  </tr>
  <tr>
    <td width="50%" valign="top">C code compatibility guarantees, including byte 
    copyable, C layout compatible, and numerous 
  initialization rules</td>
    <td width="50%">
    <ul>
      <li>C language compatibility.</li>
    </ul>
    </td>
  </tr>
  <tr>
    <td width="50%" valign="top">Static initialization guarantees [<a href="#3.6.2">3.6.2, 
    basic.start.init</a>]</td>
    <td width="50%">
    <ul>
      <li>Programs can avoid order-of-initialization issues.</li>
      <li>Multi-threaded programs can avoid data races during initialization.</li>
    </ul>
    </td>
  </tr>
  <tr>
    <td width="50%" valign="top">Various rules for non-POD's</td>
    <td width="50%">
    <ul>
      <li>Compilers  apply data layout optimizations.</li>
      <li>Compilers  assume non-aliasing, allowing code generation 
      optimizations. </li>
    </ul>
    </td>
  </tr>
</table>

<h2><a name="Motivating-examples">Motivating examples</a></h2>

<h3><a name="std::pair-example"><code>std::pair</code> example</a></h3>

<p>Matt Austern provided this example:</p>

<p>If a program has two arrays of type <code>std::pair&lt;int,int&gt;</code>, then it 
is natural to expect that <code>memcpy(A2,A1,sizeof(A2))</code> would be safe. 
Programmers have trouble imagining any implementation in which a byte-for-byte 
copy of <code>std::pair&lt;int,int&gt;</code> wouldn't do the right thing. 
Unfortunately, that's not what the language standard says. It says that 
byte-for-byte copies are guaranteed to work only for PODs. <code>std::pair&lt;T,U&gt;</code> 
isn't a class aggregate, since it has a user-defined constructor, and that means 
it also isn't a <span id="st" name="st" class="st">POD</span>.<br>
<br>
<code>std::pair </code>has a user-defined constructor essentially for syntactic 
reasons: because in some cases it looks nicer to write &quot;<code>std::pair&lt;int,int&gt; 
p(1,2);</code>&quot; than to write &quot;<code>std::pair&lt;int,int&gt; p = {1,2};</code>&quot;. It 
seems a shame that this syntactic change caused the loss of the important 
semantic property of PODness. It's especially a shame because it means something 
formally doesn't work when on all real-world implementations it actually does 
work. It also encourages programmers to rely on undefined behavior, which is 
something the standard should not encourage.</p>

<p>With the proposed wording, the example pair becomes a POD, solving the issue.</p>

<h3><a name="Endian-example">Endian example</a></h3>

<p>Beman Dawes provided this eample:</p>

<p>Here is an example of something in development for Boost, based on classes 
used in industrial applications for many years. The fact that it is 
a template partial specialization isn't material to this discussion and 
can be ignored.</p>
<blockquote>
  <pre>template &lt;typename T, std::size_t n_bits&gt;
class endian&lt; big, T, n_bits, unaligned &gt; : cover_operators&lt; endian&lt; big, T, n_bits &gt;, T &gt;
{
  BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
public:
  typedef T value_type;
  endian() {}
  endian(T i) { detail::store_big_endian&lt;T, n_bits/8&gt;(bytes, i); }
  operator T() const { return detail::load_big_endian&lt;T, n_bits/8&gt;(bytes); }
private:
  char bytes[n_bits/8];
};</pre>
</blockquote>
<p>But it isn't a POD, so it won't work at all in unions. Some  uses such as 
binary I/O 
rely on undefined behavior. Since the rationale for having endian is to do 
binary I/O, forcing the user to rely on undefined behavior is unfortunate to say the least.</p>

<p>Here is what would have to be done to make it a POD:</p>

<blockquote>

<p><i><b>Remove the constructors.</b></i> But that makes initialization painful, 
so boosters are proposing to add an ugly and unintuitive static init function, and an <code>operator=</code> 
from the <code>value_type</code>. Those are partial workarounds, but not really what the 
designers, Beman Dawes and Darin Adler,&nbsp;want.</p>

<p><b><i>Make the data member public.</i></b> But this encourages a poor design 
practice.</p>

<p><b><i>Eliminate the base class.</i></b> But the only way to do that without 
the highly error-prone duplication of the functions provided by the base class 
is to introduce a lengthy macro. Enough said.</p>

</blockquote>

<p>In other words, making this class a POD under current language rules would do serious 
damage to interface ease-of-use and to code quality, and would encourage poor 
design practices. Yet the only data member of the class is an array of char, so 
programmers intuitively expect the class to be memcpyable and binary I/O-able.</p>

<p>With the proposed wording, the class becomes a POD, solving all the issues.</p>

<h3><a name="Two-structs-example">Two structs example</a></h3>

<p>Matt Austern provided this example in Core DR 568:</p>

<p>Its silly for the standard to make layout and memcpy guarantees for this 
class:</p>

<blockquote>
  <pre>struct A {
  int n;
};</pre>
</blockquote>
<p>but not for this one:</p>
<blockquote>
  <pre>struct B {
  int n;
  B(n_) : n(n_) { }
};</pre>
</blockquote>
<p>With either A or B, it ought to be possible to save an array of those objects 
to disk with a single call to Unixs write(2) system call or the equivalent. At 
present the standard says that its legal for A but not B, and there isnt any 
good reason for that distinction.</p>

<p>With the proposed wording, the class becomes a POD, solving all the issues.</p>

<h3><a name="Atomic">Atomic</a> example</h3>

<p>Lawrence Crowl provided this example.</p>

<p>Consider a class providing atomic operations. Among other requirements, it 
should:</p>

<ul>
  <li>Be C-layout compatible.</li>
  <li>Be non-copyable.</li>
</ul>

<p>For best C++ coding practice, the data should be private. But that would make 
the class a non-POD under current rules. Under the proposed rules, it is 
allowable for the data members to be private, as long as all are private.</p>

<p>Under both the current and proposed rules, there doesn't seem to be any way 
to make a POD non-copyable.</p>
<h2><a name="Coupling">Coupling</a> between POD's and aggregates</h2>

<p>POD's provide object representation guarantees, 
layout-compatibility guarantees, memory contiguity guarantees, and memory 
copy-ability guarantees for fairly simple types, yet leave compilers much 
latitude in such matters for more complicated types.</p>

<p>Aggregates provide well-defined initialization from <i>initializer-clauses</i>.</p>

<p>The two concepts are at most tangential, if not completely orthogonal. Thus 
to define POD in terms of aggregates creates an unnecessary and confusing 
dependency. It makes otherwise straightforward changes to the Standard POD and 
aggregate sections much more difficult because of the need to analyze a potential 
change for impact on both POD's and aggregates. The coupling is confusing to users, 
causing them to make mistaken assumptions about POD's. The coupling may be part 
of the reason even committee members cannot accurately remember the full rules 
for POD-ness.</p>

<h2><a name="Rationale">Rationale</a> for changes</h2>

<p>The proposed changes decompose the byte-copyability requirement from the 
larger POD requirements. The dependency on the 
definition of aggregates by the definition of POD is removed. Instead, additional POD requirements 
are tailored 
to the needs of POD's. Because these requirements are somewhat less restrictive 
than the requirements for aggregates, the effect is to make POD's more broadly 
useful and solve the problems identified in the <a href="#Introduction">
Introduction</a> and <a href="#Motivating-examples">
Motivating examples</a>.</p>

<p>Changes are not proposed that would allow POD's to be non-copyable. There was 
no apparent way to provide syntax for this without more complexity than is 
justified by a need judged to be fairly minor.</p>

<p>Changes are not proposed that would allow POD's to have base classes with 
non-static data members. There was no apparent way to allow these cases without 
putting undue restrictions on how compilers layout base class data in relation 
to derived class data.</p>

<h2><a name="Proposed">Proposed</a> changes to the Working Paper</h2>

<p>Added text is shown in <u>
<font color="#228822">green and underlined</font></u>. Deleted text is show 
in <strike><font color="#FF0000">red with strikethrough</font></strike>. </p>

<h4>Proposed text:</h4>

<p><a name="Change-POD-definition">Change</a> 9 [class] paragraph 4 as 
indicated:</p>

<blockquote>

<p>A <i>structure</i> is a class defined with the <i>class-key</i> <code>struct</code>; its members and 
base classes (clause 10) are public by default (clause 11). A <i>union</i> is a class 
defined with the <i>class-key</i> <code>union</code>; its members are public by default and it holds 
only one data member at a time (9.5). <strike><font color="#FF0000">[ <i>Note</i>: aggregates of class type are 
described in 8.5.1. <i>end note</i> ]</font></strike><i>&nbsp; </i><u>
<font color="#228822">A 
byte-copyable-class is a class that has a trivial copy constructor (12.8),  a trivial copy assignment operator (13.5.3, 12.8), 
and a trivial destructor (12.4). [<i>Note: </i>Among other requirements,<i> </i>
that precludes 
virtual functions, virtual bases, and members or bases with non-trivial copy 
constructors, copy assignments, or destructors. <i>
--end note</i>] </font></u></p>

<p><i>A POD-struct</i> is <strike>
<font color="#FF0000">an aggregate</font></strike> <font color="#228822"> <u>a 
byte-copyable class</u></font> that:</p>

<blockquote>

<p> has no non-static data members of type non-POD-struct, non-POD-union (or 
array of such types) or reference, and<br>
 <u><font color="#228822">all non-static data members have the same 
access control (clause 11), and<br>
</font></u> <u><font color="#228822">has no non-POD base classes, and no base classes with data members.</font></u></p>

</blockquote>

<p>Similarly, a <i>POD-union</i> is <strike><font color="#FF0000">an aggregate</font></strike>
<u><font color="#228822">a</font></u> 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-declared copy assignment operator 
and no user-declared destructor. A <i>POD class</i> is a class that is 
either a POD-struct or a POD-union.<font color="#228822"><u><i> [Note:</i> virtual functions and base classes are 
prohibited in unions (9.5). <i>-- end note.]</i></u></font></p>

</blockquote>

<p>Change other WP text as indicated in the <a href="#POD-in-Standard">POD in 
the Standard</a> table below.</p>

<h3><a name="POD-in-Standard">POD in the Standard</a>, with changes</h3>
<p>The following table lists uses of POD in the current working paper, with 
proposed changes.</p>

<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
  <tr>
    <td width="76%" align="center"><b><i>Working Paper Text</i></b></td>
    <td width="14%" align="center"><b><i>Proposal</i></b></td>
  </tr>
  <tr>
    <td width="76%"><b><i>1.8 <font face="Times New Roman"></font>5 [intro.object]</i></b><p>An object of POD5) type (3.9) shall occupy contiguous bytes 
    of
    storage.</td>
    <td width="14%"><b><i>No change</i></b></td>
  </tr>
  <tr>
    <td width="76%"><b><i><a name="3.6.2">3.6.2</a> 1 Initialization of non-local objects</i></b><p>Objects with static storage duration (3.7.1) shall be 
    zero-initialized (8.5) before any other initialization takes place. A 
    reference with static storage duration and an object of POD type with static 
    storage duration can be initialized with a constant expression (5.19); this 
    is called constant initialization. Together, zero-initialization and 
    constant initialization are called static initialization; all other 
    initialization is dynamic initialization.</td>
    <td width="14%"><b><i>No change </i></b></td>
  </tr>
  <tr>
    <td width="76%"><b><i>3.8 2 Object Lifetime</i></b><p>&nbsp;[ Note: the lifetime of an array object or of an object of 
    POD type (3.9) starts as soon as storage with proper size and alignment is 
    obtained, and its lifetime ends when the storage which the array or object 
    occupies is reused or released. 12.6.2 describes the lifetime of base and 
    member subobjects. end note ]</td>
    <td width="14%"><i><b>No change</b></i></td>
  </tr>
  <tr>
    <td width="76%"><b><i>3.8 5 Object Lifetime</i></b><p><i>Restrictions on pointers to partially constructed non-POD 
    types.</i></td>
    <td width="14%"><b><i>No change</i></b></td>
  </tr>
  <tr>
    <td width="76%"><b><i>3.8 6 Object Lifetime</i></b><p><i>Restrictions on l-values of partially constructed non-POD 
    types.</i></td>
    <td width="14%"><b><i>No change</i></b></td>
  </tr>
  <tr>
    <td width="76%"><b><i><a name="3.9/2">3.9 2</a> Types</i></b><p>For any object (other than a base-class subobject) of 
    <strike><font color="#FF0000">POD</font></strike> <font color="#228822"><u>
    byte-copyable</u></font> 
    type T, whether or not the object holds a valid value of type T, the 
    underlying bytes (1.7) making up the object can be copied into an array of 
    char or unsigned char.41) If the content of the array of char or unsigned 
    char is copied back into the object, the object shall subsequently hold its 
    original value.</td>
    <td width="14%"><font color="#228822"><b><i>Change as indicated</i></b></font></td>
  </tr>
  <tr>
    <td width="76%"><b><i>3.9 3 Types</i></b><p>For any <strike>
    <font color="#FF0000">POD</font></strike> <font color="#228822"><u>
    byte-copyable</u></font> type T, if two pointers to T point to distinct T 
    objects obj1 and obj2, where neither 
    obj1 nor obj2 is a base-class subobject,
    if the value of obj1 is copied into obj2, using the std::memcpy library 
    function, obj2 shall subsequently hold the same value as obj1.</td>
    <td width="14%"><font color="#228822"><b><i>Change as indicated</i></b></font></td>
  </tr>
  <tr>
    <td width="76%"><b><i>3.9 4 Types</i></b><p>The object representation of an object of type T is the 
    sequence of N unsigned char objects taken up by the object of type T, where 
    N equals sizeof(T). The value representation of an object is the set of bits 
    that hold the value of type T. For <strike><font color="#FF0000">POD</font></strike>
    <font color="#228822"><u>byte-copyable</u></font> types, the value representation is a 
    set of bits in the object representation that determines a value, which is 
    one
    discrete element of an implementation-defined set of values.42)</td>
    <td width="14%"><font color="#228822"><b><i>Change as indicated</i></b></font></td>
  </tr>
  <tr>
    <td width="76%"><b><i>3.9 10 Types</i></b><p>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 called 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.</td>
    <td width="14%"><b><i>No change</i></b></td>
  </tr>
  <tr>
    <td width="76%"><i><b>3.9 11 Types</b></i><p>If two types T1 and T2 are the 
    same type, then T1 and T2 are layout-compatible types. [ Note: 
    Layout-compatible enumerations are described in 7.2. Layout-compatible POD-structs 
    and POD-unions are described in 9.2. end note ]</td>
    <td width="14%"><b><i>No change</i></b></td>
  </tr>
  <tr>
    <td width="76%"><i><b>5.2 7 Postfix expressions</b></i><p>When there is no 
    parameter for a given argument, the argument is passed in such a way that 
    the receiving function can obtain the value of the argument by invoking 
    va_arg (18.8). The lvalue-to-rvalue (4.1), array-to-pointer (4.2), and 
    function-to-pointer (4.3) standard conversions are performed on the argument 
    expression. After these conversions, if the argument does not have 
    arithmetic, enumeration, pointer, pointer to member, or class type, the 
    program is ill-formed. If the argument has a non-POD class type (clause 9), 
    the behavior is undefined. If the argument has integral or enumeration type 
    that is subject to the integral promotions (4.5), or a floating point type 
    that is subject to the floating point promotion (4.6), the value of the 
    argument is converted to the promoted type before the call. These promotions 
    are referred to as the default argument promotions.</td>
    <td width="14%"><b><i>No change </i></b></td>
  </tr>
  <tr>
    <td width="76%"><b><i><a name="5.3/16">5.3.4 16</a> New</i></b><p>A new-expression 
    that creates an object of type T initializes that object as follows:<br>
     If the new-initializer is omitted:<br>
    &nbsp;&nbsp;&nbsp;
     If T is a (possibly cv-qualified) non-POD class type (or array thereof), the object is default-initialized (8.5).
    If T is a const-qualified type, the underlying class type shall have a 
    user-declared default constructor.<br>
    &nbsp;&nbsp;&nbsp;
     Otherwise, the object created has indeterminate value. If T is a 
    const-qualified type, or a (possibly cv-qualified) POD class type (or array 
    thereof) containing (directly or indirectly) a member of const-qualified 
    type, the program is ill-formed;<br>
     If the new-initializer is of the form (), the item is value-initialized 
    (8.5);<br>
     If the new-initializer is of the form (expression-list) and T is a class 
    type, the appropriate constructor is called, using expression-list as the 
    arguments (8.5);<br>
     If the new-initializer is of the form (expression-list) and T is an 
    arithmetic, enumeration, pointer, or pointer-to-member type and 
    expression-list comprises exactly one expression, then the object is 
    initialized to the (possibly converted) value of the expression (8.5);<br>
     Otherwise the new-expression is ill-formed.</td>
    <td width="14%"><b><i>No change</i></b></td>
  </tr>
  <tr>
    <td width="76%"><i><b>5.19 4 Constant expressions</b></i><p>An address 
    constant expression is a pointer to an lvalue designating an object of 
    static storage duration, a string literal (2.13.4), or a function. The 
    pointer shall be created explicitly, using the unary &amp; operator, or 
    implicitly using a non-type template parameter of pointer type, or using an 
    expression of array (4.2) or function (4.3) type. The subscripting operator 
    [] and the class member access . and -&gt; operators, the &amp; and * unary 
    operators, and pointer casts (except dynamic_casts, 5.2.7) can be used in 
    the creation of an address constant expression, but the value of an object 
    shall not be accessed by the use of these operators. If the subscripting 
    operator is used, one of its operands shall be an integral constant 
    expression. An expression that designates the address of a subobject of a 
    non-POD class object (clause 9) is not an address constant expression 
    (12.7). Function calls shall not be used in an address constant expression, 
    even if the function is inline and has a reference return type.</td>
    <td width="14%"><b><i>No change</i></b></td>
  </tr>
  <tr>
    <td width="76%"><i><b>5.19 5 Constant expressions</b></i><p>A reference 
    constant expression is an lvalue designating an object of static storage 
    duration, a non-type template parameter of reference type, or a function. 
    The subscripting operator [], the class member access . and -&gt; operators, 
    the &amp; and * unary operators, and reference casts (except those invoking 
    user-defined conversion functions (12.3.2) and except dynamic_casts (5.2.7)) 
    can be used in the creation of a reference constant expression, but the 
    value of an object shall not be accessed by the use of these operators. If 
    the subscripting operator is used, one of its operands shall be an integral 
    constant expression. An lvalue expression that designates a member or base 
    class of a non-POD class object (clause 9) is not a reference constant 
    expression (12.7). Function calls shall not be used in a reference constant 
    expression, even if the function is inline and has a reference return type.</td>
    <td width="14%"><b><i>No change</i></b></td>
  </tr>
  <tr>
    <td width="76%"><b><i>6.7 3 Declaration statement</i></b><p>It is possible 
    to transfer into a block, but not in a way that bypasses declarations with 
    initialization. A program that jumps82) from a point where a local variable 
    with automatic storage duration is not in scope to a point where it is in 
    scope is ill-formed unless the variable has POD type (3.9) and is declared 
    without an initializer (8.5).</td>
    <td width="14%"><b><i>No change</i></b></td>
  </tr>
  <tr>
    <td width="76%"><b><i>6.8 4 Ambiguity resolution</i></b><p>The 
    zero-initialization (8.5) of all local objects with static storage duration 
    (3.7.1) is performed before any other initialization takes place. A local 
    object of POD type (3.9) with static storage duration initialized with 
    constant-expressions is initialized before its block is first entered. An 
    implementation is permitted to perform early initialization of other local 
    objects with static storage duration under the same conditions that an 
    implementation is permitted to statically initialize an object with static 
    storage duration in namespace scope (3.6.2). Otherwise such an object is 
    initialized the first time control passes through its declaration; such an 
    object is considered initialized upon the completion of its initialization. 
    If the initialization exits by throwing an exception, the initialization is 
    not complete, so it will be tried again the next time control enters the 
    declaration. If control re-enters the declaration (recursively) while the 
    object is being initialized, the behavior is undefined.</td>
    <td width="14%"><b><i>No change</i></b></td>
  </tr>
  <tr>
    <td width="76%"><b><i><a name="8.5/5">8.5 5</a> Initializers</i></b><blockquote>
      <p>To <i>default-initialize</i> an 
    object of type T means:<br>
     if T is a non-POD class type (clause 9), the default constructor for T is 
    called (and the initialization is ill-formed if T has no accessible default 
    constructor);<br>
     if T is an array type, each element is default-initialized;<br>
     otherwise, the object is zero-initialized.</blockquote>
    </td>
    <td width="14%"><b><i>No change</i></b></td>
  </tr>
  <tr>
    <td width="76%"><b><i><a name="8.5/9">8.5 9</a> Initializers</i></b><p>If no initializer is 
    specified for an object, and the object is of (possibly cv-qualified) 
    non-POD class type (or array thereof), the object shall be 
    default-initialized; if the object is of const-qualified type, the 
    underlying class type shall have a user-declared default constructor. 
    Otherwise, if no initializer is specified for a non-static object, the 
    object and its subobjects, if any, have an indeterminate initial value97); 
    if the object or any of its subobjects are of const-qualified type, the 
    program is ill-formed.</td>
    <td width="14%"><b><i>No change</i></b></td>
  </tr>
  <tr>
    <td width="76%"><b><i>8.5 14 Initializers</i></b><p>When an aggregate with 
    static storage duration is initialized with a brace-enclosed 
    initializer-list, if all the member initializer expressions are constant 
    expressions, <span style="background-color: #FFFFFF">and the aggregate is a POD type</span>, the initialization shall be 
    done during the static phase of initialization (3.6.2); otherwise, it is 
    unspecified whether the initialization of members with constant expressions 
    takes place during the static phase or during the dynamic phase of 
    initialization.</td>
    <td width="14%"><b><i>No Change&nbsp; </i></b></td>
  </tr>
  <tr>
    <td width="76%"><b><i>9 4 Classes [class]</i></b><p>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. 
    end note ] 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-declared copy 
    assignment operator and no user-declared 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-declared copy 
    assignment operator and no user-declared destructor. A POD class is a 
    class that is either a POD-struct or a POD-union.</td>
    <td width="14%">See <a href="#Change-POD-definition">proposed change</a> 
    above.</td>
  </tr>
  <tr>
    <td width="76%"><b><i>9.2 15-18 Class members [<a name="class.mem">class.mem</a>]</i></b><p>15 Two POD-struct (clause 9) types 
    are layout-compatible if they have the same number of non-static data 
    members, and corresponding non-static data members (in order) have 
    layout-compatible types (3.9).</p>
    <p>16 Two POD-union (clause 9) types are layout-compatible if they have the 
    same number of non-static data members, and corresponding non-static data 
    members (in any order) have layout-compatible types (3.9).</p>
    <p>17 If a POD-union contains two or more POD-structs that share a common 
    initial sequence, and if the POD-union object currently contains one of 
    these POD-structs, it is permitted to inspect the common initial part of any 
    of them. Two POD-structs share a common initial sequence if corresponding 
    members have layout-compatible types (and, for bit-fields, the same widths) 
    for a sequence of one or more initial members.</p>
    <p>18 A pointer to a POD-struct object, suitably converted using a 
    reinterpret_cast, points to its initial member (or if that member is a 
    bit-field, then to the unit in which it resides) and vice versa. [ Note: 
    There might therefore be unnamed padding within a POD-struct object, but not 
    at its beginning, as necessary to achieve appropriate alignment. end note ]</td>
    <td width="14%"><i><b>No Change</b></i></td>
  </tr>
  <tr>
    <td width="76%"><b><i>9.5 1 Unions</i></b><p>In a union, at most one of the 
    data members can be active at any time, that is, the value of at most one of 
    the data members can be stored in a union at any time. [ Note: one special 
    guarantee is made in order to simplify the use of unions: If a POD-union 
    contains several POD-structs that share a common initial sequence (9.2), and 
    if an object of this POD-union type contains one of the POD-structs, it is 
    permitted to inspect the common initial sequence of any of POD-struct 
    members; see 9.2. end note ] The size of a union is sufficient to contain 
    the largest of its data members. Each data member is allocated as if it were 
    the sole member of a struct. A union can have member functions (including 
    constructors and destructors), but not virtual (10.3) functions. A union 
    shall not have base classes. A union shall not be used as a base class. An object of a class with a 
    non-trivial default constructor (12.1), a non-trivial copy constructor 
    (12.8), a non-trivial destructor (12.4), or a non-trivial copy assignment 
    operator (13.5.3, 12.8) cannot be a member of a union, nor can an 
    array of such objects. If a union contains a static data member, or a member 
    of reference type, the program is ill-formed.</td>
    <td width="14%"><b><i>No change</i></b></td>
  </tr>
  <tr>
    <td width="76%"><b><i><a name="12.6.2/4">12.6.2 4</a> Initializing bases and members</i></b><p>If a 
    given non-static data member or base class is not named by a mem-initializer-id 
    (including the case where there is no mem-initializer-list because the 
    constructor has no ctor-initializer), then<br>
    <br>
     If the entity is a non-static data member of (possibly cv-qualified) class 
    type (or array thereof) or a base class, and the entity class is a non-POD 
    class the entity is default-initialized (8.5). If the entity is a 
    non-static data member of a const-qualified type, the entity class shall 
    have a user-declared default constructor.<br>
    <br>
     Otherwise, the entity is not initialized. If the entity is of 
    const-qualified type or reference type, or of a (possibly cv-qualified) POD 
    class type (or array thereof) containing (directly or indirectly) a member 
    of a const-qualified type, the program is ill-formed.<br>
    <br>
    After the call to a constructor for class X has completed, if a member of X 
    is neither specified in the constructors mem-initializers, nor 
    default-initialized, nor value-initialized, nor given a value during 
    execution of the body of the constructor, the member has indeterminate 
    value.</td>
    <td width="14%"><b><i>No change</i></b></td>
  </tr>
  <tr>
    <td width="76%"><b><i><a name="12.7/1">12.7 1</a> Construction and destruction</i></b><p>
    For an object of non-POD class type (clause 9) before the constructor begins 
    execution and after the destructor&nbsp;finishes execution, referring to 
    any non-static member or base class of the object results in undefined 
    behavior. [ <i>Example:</i></p>
    <blockquote>
      <pre>struct X { int i; };                  <u><font color="#228822">// POD</font></u>
struct Y : X { };                     <u><font color="#228822">// non-POD</font></u>
struct A { int a; };                  <u><font color="#228822">// POD</font></u>
struct B : public A { int j; Y y; };  <u><font color="#228822">// non-POD</font></u><span style="background-color: #FFFF00">
</span>
extern B bobj;
B* pb = &amp;bobj;         // OK
int* p1 = &amp;bobj.a;     // undefined, refers to base class member
int* p2 = &amp;bobj.y.i;   // undefined, refers to members member

A* pa = &amp;bobj;         // undefined, upcast to a base class type
B bobj;                // definition of bobj

extern X xobj;
int* p3 = &amp;xobj.i;     //OK, X is a POD class
X xobj;</pre>
    </blockquote>
    </td>
    <td width="14%"><font color="#228822"><b><i>Change&nbsp; as indicated</i></b></font></td>
  </tr>
  <tr>
    <td width="76%"><b><i>17.1.3 character container type</i></b><p>a class or a 
    type used to represent a character (17.1.2). It is used for one of the 
    template parameters of the string and iostream class templates. A character 
    container class shall be a POD (3.9) type.</td>
    <td width="14%"><b><i>No change. </i></b>Users expect characters involved in 
    I/O to be C-layout-compatible, and thus POD types.</td>
  </tr>
  <tr>
    <td width="76%"><b><i>18.1 4 Types</i></b><p>The macro offsetof(type, 
    member-designator) accepts a restricted set of type arguments in this 
    International Standard. If type is not a POD structure or a POD union 
    (clause 9), the results are undefined.189) The expression offsetof(type, 
    member-designator) is never type-dependent (14.6.2.2) and it is 
    value-dependent (14.6.2.3) if and only if type is dependent. The result of 
    applying the offsetof macro to a field that is a static data member or a 
    function member is undefined.</td>
    <td width="14%"><i><b>No change</b></i></td>
  </tr>
  <tr>
    <td width="76%"><i><b>20.4 type traits </b>has many uses of POD in the 
    specification of is_pod. Most of those uses clearly will remain unchanged. 
    Uses in other type traits need to be reviewed</i></td>
    <td width="14%"><span style="background-color: #FFFF00">TODO</span></td>
  </tr>
  <tr>
    <td width="76%"><i><b>21 1 Strings library</b></i><p>This clause describes 
    components for manipulating sequences of characters, where characters may 
    be of any POD (3.9) type. In this clause such types are called char-like 
    types, and objects of char-like types are called char-like objects or simply 
    characters.</td>
    <td width="14%"><i><b>No change</b></i><b><i>. </i></b>Users expect <code>
    c_str()</code> and <code>data()</code> to return pointers to 
    C-layout-compatible, and thus POD types.</td>
  </tr>
  <tr>
    <td width="76%"><b><i>25.4 4 C library algorithms</i></b><p>The function 
    signature:<br>
    <br>
    <code>qsort(void *, size_t, size_t, int (*)(const void *, const void *));</code><br>
    <br>
    is replaced by the two declarations:<br>
    <br>
    <code>extern &quot;C&quot; void qsort(void* base , size_t nmemb , size_t size, int (*compar 
    )(const void*, const void*));</code><br>
    <br>
    <code>extern &quot;C++&quot; void qsort(void* base , size_t nmemb , size_t size, int (*compar 
    )(const void*, const void*)); </code> <br>
    <br>
    both of which have the same behavior as the original declaration. The 
    behavior is undefined unless the objects in the array pointed to by base are 
    of <strike><font color="#FF0000">POD</font></strike> <font color="#228822">
    <u>byte-copyable</u></font> type.</td>
    <td width="14%"><font color="#228822"><i><b>Change as indicated</b></i></font></td>
  </tr>
</table>

<h2><a name="Impact">Impact</a> on existing code</h2>

<p>The proposed changes will cause some existing non-POD's to become 
POD's. This may result in less optimization being performed. The problem can be 
eliminated by adding a user-defined do-nothing destructor.</p>

<table border="2" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
  <tr>
    <td width="100%">Adding a user-defined do-nothing destructor to existing code 
    to leave POD-ness unchanged is simple enough that it could be done 
    programmatically. If a compiler vendor felt this was a serious concern for 
    their user-base, they might wish to provide such a program. Alternately, compilers may wish to issue warnings 
    during a transition period if the new 
rules change a non-POD into a  POD.</td>
  </tr>
</table>

<h2><a name="Interaction">Interaction</a> with other proposals</h2>

<p>See
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1824.htm">
N1824</a>, Extending Aggregate Initialization. Whichever proposal is accepted 
first, the other will have to be reviewed, and possibly revised, accordingly.</p>

<h2><a name="Acknowledgements">Acknowledgements</a></h2>

<p>Matt Austern, Greg Colvin,  Alisdair Meredith, and Clark Nelson provided 
helpful comments during preparation of this proposal. Our cat Jane woke me up in 
the middle of the night, provoking this proposal as an alternative to counting 
sheep (or cats).</p>

<h2><a name="References">References</a></h2>

<p>N1824 Extending Aggregate Initialization, Alisdair Meredith,&nbsp;
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1824.htm">
www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1824.htm</a></p>

<p>Core issue 568.
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#568">
www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#568</a></p>

<hr>

<p>&nbsp;</p>

</body>

</html>
