<html>
<head>
<title>P0767R1: Deprecate POD</title>

<style type="text/css">
  ins { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  .new { text-decoration:none; font-weight:bold; background-color:#D0FFD0 }
  del { text-decoration:line-through; background-color:#FFA0A0 }  
  strong { font-weight: inherit; color: #2020ff }
  table, td, th { border: 1px solid black; border-collapse:collapse; padding: 5px }
</style>
</head>

<body>
ISO/IEC JTC1 SC22 WG21 P0767R1<br/>
Jens Maurer &lt;Jens.Maurer@gmx.net><br/>
Target audience: LEWG, LWG and CWG<br/>
2017-11-10<br/>

<h1>P0767R1: Deprecate POD</h1>

<h2>Introduction</h2>

This paper addresses NB commment US 101 on the CD for C++17.  It is
tracked as core issue 2323, but has substantial impact on the library
section, too.  In order to better handle the necessary coordination
between LWG and CWG, the changes are presented in this paper.
<p>
Preliminary discussion on the reflector has demonstrated some concerns
about the direction proposed in this paper.  Notwithstanding, I
believe the remaining use (but not the definition, if required for the
library section) of POD in the core language section is misleading at
best and should be fixed.

<h2>Wording changes</h2>


Change footnote in 6.8 [basic.life] paragraph 6:

<blockquote>
Before the lifetime of an object has started but after the storage
which the object will occupy has been allocated [ Footnote: For
example, before the construction of a global object
<del>of non-POD class type</del> <ins>that is initialized via a user-provided
constructor</ins> (15.7 [class.cdtor]). ] or, after the lifetime of an
object has ended and before the storage which the object occupied is
reused or released, any pointer that represents the address of the
storage location where the object will be or was located may be used
but only in limited ways. [...]
</blockquote>

Remove in 6.9 [basic.types] paragraph 9:

<blockquote>
[...] <del>Scalar types, POD classes (Clause 12), arrays of such types
and cv-qualified versions of these types are collectively called POD
types.</del> [...]
</blockquote>

Change in 8.1.5.1 [expr.prim.lambda.closure] paragraph 2:

<blockquote>
An implementation may define the closure type differently from what is
described below provided this does not alter the observable behavior
of the program other than by changing:
<ul>
  <li>the size and/or alignment of the closure type,</li>
  <li>whether the closure type is trivially copyable (Clause 12), <ins>or</ins></li>
  <li>whether the closure type is a standard-layout class (Clause 12)<del>, or</del><ins>.</ins></li>
  <li><del>whether the closure type is a POD class (Clause 12).</del></li>
</ul>

</blockquote>

Remove the normative text in 12 [class] paragraph 10, but keep the
example:

<blockquote>
<del>A POD struct [ Footnote: ...] is a non-union class that is both a
trivial class and a standard-layout class, and has no non-static data
members of type non-POD struct, non-POD union (or array of such
types). Similarly, a POD union is a union that is both a trivial class
and a standard-layout class, and has no non-static data members of
type non-POD struct, non-POD union (or array of such types). A POD
class is a class that is either a POD struct or a POD union.</del>
[ Example:
<pre>
   struct N {            // neither trivial nor standard-layout
     int i;
     int j;
     virtual ~N();
   };
   struct T {            // trivial but not standard-layout
     int i;
   private:
     int j;
   };
   struct SL {           // standard-layout but not trivial
     int i;
     int j;
     ~SL();
   };
   struct POD {          // both trivial and standard-layout
     int i;
     int j;
   };
   </pre>
 -- end example ]

</blockquote>




Change in 20.3.3 [defns.character.container]:

<blockquote>
<b>character container type</b><br/> a class or a type used to
represent a character [ Note: It is used for one of the template
parameters of the string, iostream, and regular expression class
templates. <del>A character container type is a POD (6.9) type.</del>
-- end note ]

</blockquote> 

Change in 21.2.4 [support.types.layout] paragraph 5:

<blockquote>
The type <code>max_align_t</code> is
a <del>POD</del> <ins>trivial</ins> type whose alignment requirement
is at least as great as that of every scalartype, and whose alignment
requirement is supported in every context (6.11 [basic.align]).
</blockquote>

Change in 23.15.2 [meta.type.synop]

<blockquote>
  <pre>
    <del>template &lt;class T> struct is_pod;</del>
    [...]
    <del>template &lt;class T> inline constexpr bool is_pod_v
      = is_pod&lt;T>::value;</del>
  </pre>
</blockquote>

In the table in 23.15.4.3 [meta.unary.prop], strike the row
for <code>is_pod</code>:

<blockquote>
  <del>template &lt;class T>
  struct is_pod;<br/>
  T is a POD type (6.9 [basic.types])<br/>
  <code>remove_all_extents_t&lt;T></code> shall be a complete type or cv void.</del>
</blockquote>

Change in the table in 23.15.7.6 [meta.trans.other]:

<blockquote>
<code>aligned_storage</code><br/>
The member typedef type shall be a <del>POD</del> <ins>trivial</ins>
type suitable for use as uninitialized storage for any object whose
size is at most <code>Len</code> and whose alignment is a divisor
of <code>Align</code>.
<p>
<code>aligned_union</code><br/> The member typedef type shall be
a <del>POD</del> <ins>trivial</ins> type suitable for use as
uninitialized storage for any object whose type is listed
in <code>Types</code>; its size shall be at least <code>Len</code>.
</blockquote>

Change in 24.1 [strings.general] paragraph 1:

<blockquote>
This Clause describes components for manipulating sequences of any
non-array <del>POD</del> <ins>trivial</ins> (6.9 [basic.types])
type. Such types are called char-like types, and objects of char-like
types are called char-like objects or simply characters.
</blockquote>

Add a new subsection to Annex D or merge into D.12 [depr.meta.types]:

<blockquote class="new">
D.17 Identification of POD types [depr.is_pod]
<p>
  The following type property is defined in
  header <code>&lt;type_traits></code> in addition to those defined in
  23.15.4.3 [meta.unary.prop]:
  <pre>
    template &lt;class T> struct is_pod;
    template &lt;class T> inline constexpr bool is_pod_v
    = is_pod&lt;T>::value;
  </pre>

<em>Requires:</em> <code>remove_all_extents_t&lt;T></code> shall be a complete type or <em>cv</em> <code>void</code>.
<p>

<code>is_pod&lt;T></code> is a UnaryTypeTrait (23.15.1 [meta.rqmts])
with a base characteristic of <code>true_type</code> if T is a POD
type, and
<code>false_type</code> otherwise.
      
A POD class is a class that is both a trivial class and a
standard-layout class, and has no non-static data members of type
non-POD class (or array thereof). A POD type is a scalar type, a POD
class, an array of such a type, or a cv-qualified version of one of
these types. [ Note: It is unspecified whether a closure type (8.1.5.1
[expr.prim.lambda.closure]) is a POD type. -- end note ]
</blockquote>

</body>
</html>
