<html>
<head>
<title>Consolidated Quasi-Editorial Changes for National Body Comments
Concerning the Core Language</title>
</head>

<body>
N2841 = 09-0031<br/>
Jens Maurer &lt;Jens.Maurer@gmx.net><br/>
2009-03-05

<h1>Consolidated Quasi-Editorial Changes for National Body Comments
Concerning the Core Language</h1>

<p>This paper presents changes to the core-language sections of the
C++ Working Paper N2800 in response to those National Body comments
(re C++0x CD1) that the Core Working Group agreed to handle
as essentially editorial changes, but felt that additional wording
guidance would be beneficial for the Project Editor.</p>


<h2>US 12: memory location vs. object</h2>

Change section 1.7 intro.memory paragraph 3 as indicated:

<blockquote>
A <del>memory location</del> <ins><em>memory location</em></ins> is
either an object of scalar type or a maximal sequence of adjacent
bit-fields all having non-zero width. ...
</blockquote>


<h2>US 14: memory locations and bit-fields</h2>

Change section 1.7 intro.memory paragraph 4 as indicated:

<blockquote>
[ Note: ... It is not safe to concurrently update two bit-fields in
the same struct if all fields between them are also bit-fields <ins>of
non-zero width</ins><del>, no matter what the sizes of those
intervening bit-fields happen to be</del>. -- end note ]
</blockquote>


<h2>UK 10: implementation-defined whitespace conflation</h2>

Change section 2.1 lex.phases paragraph 1 number 3 as indicated:

<blockquote>
... Whether each nonempty sequence of white-space characters other than
new-line is retained or replaced by one space character is
<del>implementation-defined</del> <ins>unspecified</ins>. ...
</blockquote>


<h2>UK 25: bad example for implicitly-defined default constructor</h2>

Change section 3.1 basic.def paragraph 3 as indicated:

<blockquote>
... [ Example: ...
the implementation will implicitly define functions to make the
definition of C equivalent to
<pre>
  struct C {
     std::string s;
     C()<del>: s()</del> { }
     C(const C& x): s(x.s) { }
     C& operator=(const C& x) { s = x.s; return *this; }
     ~C() { }
  };
</pre>
-- end example ] ...
</blockquote>


<h2>UK 27: complete class type required when catching exceptions</h2>

In section 3.2 basic.def.odr paragraph 4, add a bullet to the list in
the note:

<blockquote>
...
<ul>
<li>the type <code>T</code> is the subject of an <code>alignof</code>
expression (5.3.6 expr.alignof)<del>.</del><ins>, or</ins></li>
<li><ins>an <em>exception-declaration</em> has type <code>T</code>,
reference to <code>T</code>, or pointer to <code>T</code> (15.3
except.handle)</ins></li>
</ul>
</blockquote>

<h2>UK 28: point of declaration of class templates</h2>

Change section 3.3.1 basic.scope.pdecl paragraph 3 as indicated:

<blockquote>
The point of declaration for a class <ins>or class template</ins>
first declared by a <em>class-specifier</em> is immediately after the
<del>identifier</del><ins><em>identifier</em></ins> or
<em>simple-template-id</em> (if any) in its <em>class-head</em>
(Clause 9 class). ...
</blockquote>

<em>Note to the editor: We suggest to italicize "identifier" here
because it refers to a specific part of the grammar, not the general
concept.</em>


<h2>UK 31: linkage of names inside anonymous namespaces</h2>

Change section 3.5 paragraph 4 last bullet as indicated:
<blockquote>
<ul>
<li>a namespace (7.3 basic.namespace)<del>, unless it is declared
within an unnamed namespace</del>.</li>
</ul>
</blockquote>


<h2>UK 32: using <code>constexpr</code> with the <code>main</code>
function</h2>

Change in section 3.6.1 basic.start.main paragraph 3 as indicated:
<blockquote>
A program that declares <code>main</code> to be <code>inline</code>
<del>or</del> <ins>,</ins> <code>static</code> <ins>, or
<code>constexpr</code></ins> is ill-formed.
</blockquote>


<h2>UK 33: integer conversion rank of <code>signed char</code>
 vs. <code>char</code></h2>

Change in 4.13 conv.rank paragraph 1 bullet 1 and bullet 6 as indicated:
<blockquote>
<ul>
<li>No two signed integer types <ins>other than <code>char</code> and
<code>signed char</code> (if <code>char</code> is signed)</ins> shall
have the same rank, even if they have the same represesentation.</li>
</ul>
...
<ul>
<li>The rank of any unsigned integer type shall equal the rank of the
corresponding signed integer type.</li>
</ul>
...
<ul>
<li>the rank of <code>char</code> shall equal the rank of
<code>signed char</code> and <code>unsigned char</code>.</li>
</ul>
</blockquote>


<h2>UK 36: introductory sentence for primary expressions</h2>

Change in 5.1 expr.prim paragraph 1 as indicated (keep the grammar):
<blockquote>
<del>Primary expressions are literals, names, names qualified by the
scope resolution operator <code>::</code>, and lambda
expressions.</del> ...
</blockquote>


<h2>DE 8: ref-qualifier and attribute-specifier for lambda's function
call operator</h2>

Add a bullet in 5.1.1 expr.prim.lambda paragraph 10 as indicated:
<blockquote>
...
<ul>
<li>The <em>cv-qualifier-seq</em> is absent if the lambda expression
is <code>mutable</code>, and it is <code>const</code> otherwise.</li>
<li><ins>The <em>attribute-specifier</em> and <em>ref-qualifier</em>
are both absent.</ins></li>
</ul>
...
</blockquote>


<h2>UK 59: va_arg vs. function parameter packs</h2>

Change section 5.2.2 expr.call paragraph 7 as indicated:
<blockquote>
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 <code>va_arg</code> (18.9
support.runtime).
<ins>[ Note: This paragraph does not apply to arguments passed to a
function parameter pack.  Function parameter packs are expanded during
template instantiation (14.5.3 temp.variadic), thus each such argument
has a corresponding parameter when a function template specialization
is actually called. --end note ] </ins> ...
</blockquote>


<h2>UK 62: "not an lvalue" vs. "rvalue"</h2>

<p>
<em>Editing note: No change to 4.1p2 conv.lval (ISO C does not have
rvalues), 8.5.3p5b2 dcl.init.ref and 8.5.4p3b4 dcl.init.list (example
is highlighting the non-lvalueness).</em>
</p>

Change section 2.13.5 lex.bool paragraph 1 as indicated:

<blockquote>
The Boolean literals are the keywords false and true. Such literals
<del>have type bool. They are not lvalues</del><ins> are rvalues and
have type <code>bool</code></ins>.
</blockquote>

Change in section 5.2.5 expr.ref paragraph 4 bullet 3 sub-bullet 2 and
bullet 5 as indicated:

<blockquote>
<ul>
<li>...
<ul>
<li>Otherwise, if <code>E1.E2</code> refers to a non-static member
function, and the type of <code>E2</code> is "function of
parameter-type-list <em>cv</em> returning <code>T</code>", then
<code>E1.E2</code> is <del><em>not</em> an lvalue</del> <ins>an
rvalue</ins>. ... </li>
</ul>
...
<li>If <code>E2</code> is a member enumerator, and the type of
<code>E2</code> is <code>T</code>, the expression <code>E1.E2</code>
is <del>not an lvalue</del> <ins>an rvalue</ins>. ...
</ul>
</blockquote>

Change in 14.1 temp.param paragraph 6 as indicated:
<blockquote>
A non-type non-reference template-parameter is <del>not an
lvalue</del> <ins>an rvalue</ins>. ...
</blockquote>


<h2>UK 65: dynamic_cast and lvalues/rvalues</h2>

Change section 5.2.7 expr.dynamic.cast paragraph 8 bullets 1 and 2 as
indicated:

<blockquote>
<ul>
<li>If, in the most derived object pointed (referred) to by
<code>v</code>, <code>v</code> points (refers) to a public base class
subobject of a <code>T</code> object, and  only one object of type
<code>T</code> is derived from the subobject pointed (referred) to by
<code>v</code> the result <del>is a pointer (an lvalue
referring)</del> <ins>points (refers)</ins> to that
<code>T</code> object.</li>
<li>Otherwise, if v points (refers) to a public base class subobject
of the most derived object, and the type of the most derived object
has a base class, of type <code>T</code>, that is unambiguous and public, the
result <del>is a pointer (an lvalue referring)</del> <ins>points
(refers)</ins> to the <code>T</code> subobject of the most derived
object.
</li>
...
</ul>

</blockquote>


<h2>UK 66: derivation from std::type_info</h2>

Change section 5.2.8 expr.typeid paragraph 1 as indicated:
<blockquote>
The result of a <code>typeid</code> expression is an lvalue of static
type <code>const std::type_info</code> (18.6.1 type.info) and dynamic
type <code>const std::type_info</code> or <code>const
<em>name</em></code> where <em>name</em> is an implementation-defined
class <ins>publicly</ins> derived from
<code>std::type_info</code> which preserves the behavior described in
18.6.1 type.info [ Footnote: ... ] ...
</blockquote>


<h2>UK 67: static_cast and lvalueness</h2>

Change section 5.2.9 expr.static.cast paragraph 2 as indicated:

<blockquote>
... <del>It is an lvalue if the type cast
to is an lvalue reference; otherwise, it is an rvalue.</del> ...
<del>The result is an rvalue.</del> ...
</blockquote>

Change section 5.2.9 expr.static.cast paragraph 3 as indicated:

<blockquote>
... <del>The result is an lvalue if T is an lvalue reference type
(8.3.2 dcl.ref), and an rvalue otherwise.</del> ...
</blockquote>


<h2>UK 54: reinterpret_cast and implementation-defined behavior</h2>

Change section 5.2.10 expr.reinterpret.cast paragraph 3 as indicated:
<blockquote>
<del>The mapping performed by <code>reinterpret_cast</code> is
implementation-defined.</del> [ Note: <del>it</del> <ins>The mapping
performed by <code>reinterpret_cast</code></ins> might, or might not,
produce a representation different from the original value.
-- end note ]
</blockquote>


<h2>UK 55: reinterpret_cast and constness</h2>

Change section 5.2.10 expr.reinterpret.cast paragraph 2 as indicated:
<blockquote>
The <code>reinterpret_cast</code> operator shall not cast away
constness <ins>(5.2.11 expr.const.cast)</ins>. [ Note: <del>see 5.2.11 for
the definition of "casting away constness".</del> Subject to the
restrictions in this section, an expression may be cast to its own
type using a reinterpret_cast operator. -- end note ]
</blockquote>


<h2>UK 56: reinterpret_cast and safely-derived pointers</h2>

Add to section 5.2.10 expr.reinterpret.cast paragraph 5:
<blockquote>
... <ins>[ Note: Except as described in 3.7.4.3 basic.stc.dynamic.safety,
the result of such a conversion will not be a safely-derived pointer
value. ]</ins>
</blockquote>


<h2>UK 68: most unary operators return rvalues</h2>

In section 5.3.1 expr.unary.op, add a new paragraph between paragraphs
1 and 2:
<blockquote>
<ins>The result of each of the following unary operators is an rvalue.</ins>
</blockquote>


<h2>UK 47: description of sequencing for logical-and and
logical-or</h2>

Change 5.15 expr.log.or paragraph 2 as indicated:
<blockquote>
The result is a <code>bool</code>.  <del>All side effects of the first
expression except for destruction of temporaries (12.2 class.temporary)
happen before the second expression is evaluated.</del>
<ins>If the second expression is evaluated, every value computation
and side effect associated with the first expression is sequenced
before every value computation and side effect associated with the
second expression.</ins>
</blockquote>


<h2>DE 11: late-checked block has no effect</h2>

Change 6.9 stmt.late paragraph 1 as indicated:

<blockquote>
... Outside of a constrained context, the late-checked block has <del>no
effect</del> <ins>the same meaning as if the <code>late_check</code>
keyword were absent.</ins> ...
</blockquote>


<h2>UK 84: stray "alignment-specifier" in the grammar</h2>

In 7.1 dcl.spec paragraph 1, remove the <em>alignment-specifier</em>
from the grammar:
<blockquote>
<pre>
decl-specifier:
       storage-class-specifier
       type-specifier
       function-specifier
       friend
       typedef
       constexpr
<del>       alignment-specifier</del>
</pre>
</blockquote>


<h2>UK 91: Parenthesis handling for decltype</h2>

Change section 7.1.6.2 dcl.type.simple paragraph 4 bullet 1 as
indicated:

<blockquote>
<ul>
<li>if <code>e</code> is an <ins>unparenthesized</ins>
<em>id-expression</em> or class member access (5.2.5 expr.ref),
<code>decltype(e)</code> is the type of the entity named by
<code>e</code>.  If there is no such entity, or if <code>e</code>
names a set of overloaded functions, the program is ill-formed;</li>
</ul>
</blockquote>


<h2>UK 110: example for atomics</h2>

Change section 7.6.5 dcl.attr.depend paragraphs 4, 5, 6 as indicated:
<blockquote>
<pre>
    /* <del>Compilation</del><ins>Translation</ins> unit A. */
    struct foo { int* a; int* b; };
    <del>struct foo* foo_head[10];</del>
    <ins>std::atomic&lt;struct foo *&gt; foo_head[10];</ins>
    <ins>int foo_array[10][10];</ins>

    struct foo* f [[carries_dependency]] (int i) {
      return foo_head[i].load(memory_order_consume);
    }

    int g(int* x, int* y [[carries_dependency]]) {
      return kill_dependency(foo_array[*x][*y]);
    }

    /* <del>Compilation</del><ins>Translation</ins> unit B. */
    struct foo* f [[carries_dependency]] (int i);
    int* g(int* x, int* y [[carries_dependency]]);

    int c = 3;

    void h(int i) {
      struct foo* p;

      p = f(i);
      do_something_with(g(&c, p->a));
      do_something_with(g(p->a, &c));
    }
</pre>
</blockquote>

<blockquote>
The annotation on function <code>f</code> means that the return value
carries a dependency out of <code>f</code>, so that the
<del>implementation need  constrain ordering upon return from
<code>f</code></del> <ins>implementations of <code>f</code> and its
caller may choose to preserve dependencies instead of emitting
hardware memory ordering instructions (a.k.a. fences)</ins>.
</blockquote>

<blockquote>
Function <code>g</code>'s second argument is annotated, but its first
argument is not. Therefore, function <code>h</code>'s first call to
<code>g</code> carries a dependency into <code>g</code>, but its
second call does not. The implementation might need to <del>constrain
ordering</del><ins>insert a fence</ins> prior to the second call to
<code>g</code>.
</blockquote>


<h2>FR 28: example for class object initialization</h2>

Change section 12.6.1 class.expl.init paragraph 1 as indicated:
<blockquote>
...
<pre>
complex g = { 1, 2 }; // <del>error: constructor is required</del>
                         <ins><em>construct</em> complex(1,2)
                         <em>using</em> complex(double,double)
                         <em>copy it into</em> g</ins>
</pre>
</blockquote>


<h2>UK 132: copy construction for handler object</h2>

Change section 15.3 except.handle paragraph 16 as indicated and remove
paragraph 17:

<blockquote>
<del>When the <em>exception-declaration</em> specifies a class type, a copy
constructor is used to initialize either the object declared in the
<em>exception-declaration</em> or, if the
<em>exception-declaration</em> does not specify a name, a temporary
object of that type.</del> <ins>The object declared
in an <em>exception-declaration</em> or, if the
<em>exception-declaration</em> does not specify a name, a temporary
(12.2 class.temporary) is copy-initialized (8.5 dcl.init) from the
exception object.</ins>
The object shall not have an abstract class
type. The object is destroyed when the handler exits, after the
destruction of any automatic objects initialized within the
handler. <del>The copy constructor and destructor shall be accessible in
the context of the handler. If the copy constructor and destructor are
implicitly declared (12.8 class.copy), such a use in the handler
causes these functions to be implicitly defined; otherwise, the
program shall provide a definition for these functions.</del>
</blockquote>

<blockquote>
<del>The copy constructor and destructor associated with the object
shall be accessible even if the copy operation is elided (12.8
class.copy).</del>
</blockquote>


<h2>UK 133: prohibit exception-specifications in alias-declarations</h2>

Change in section 15.4 except.spec paragraph 2 as indicated:
<blockquote>
.... An <em>exception-specification</em> shall not appear in a typedef
declaration <ins>or <em>alias-declaration</em></ins>. ...
</blockquote>


<h2>UK 139: library function exiting with an exception</h2>

Change section 15.5.1 except.terminate paragraph 1 first bullet as
indicated:
<blockquote>
<ul>
<li>when the exception handling mechanism, after completing evaluation
of the expression to be thrown but before the exception is caught
(15.1 except.throw), calls a <del>user</del> function that exits via
an uncaught exception, [ Footnote: ... ]
</blockquote>


</body>
</html>
