N2841 = 09-0031
Jens Maurer <Jens.Maurer@gmx.net>
2009-03-05

Consolidated Quasi-Editorial Changes for National Body Comments Concerning the Core Language

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.

US 12: memory location vs. object

Change section 1.7 intro.memory paragraph 3 as indicated:
A memory location memory location is either an object of scalar type or a maximal sequence of adjacent bit-fields all having non-zero width. ...

US 14: memory locations and bit-fields

Change section 1.7 intro.memory paragraph 4 as indicated:
[ Note: ... It is not safe to concurrently update two bit-fields in the same struct if all fields between them are also bit-fields of non-zero width, no matter what the sizes of those intervening bit-fields happen to be. -- end note ]

UK 10: implementation-defined whitespace conflation

Change section 2.1 lex.phases paragraph 1 number 3 as indicated:
... Whether each nonempty sequence of white-space characters other than new-line is retained or replaced by one space character is implementation-defined unspecified. ...

UK 25: bad example for implicitly-defined default constructor

Change section 3.1 basic.def paragraph 3 as indicated:
... [ Example: ... the implementation will implicitly define functions to make the definition of C equivalent to
  struct C {
     std::string s;
     C(): s() { }
     C(const C& x): s(x.s) { }
     C& operator=(const C& x) { s = x.s; return *this; }
     ~C() { }
  };
-- end example ] ...

UK 27: complete class type required when catching exceptions

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

UK 28: point of declaration of class templates

Change section 3.3.1 basic.scope.pdecl paragraph 3 as indicated:
The point of declaration for a class or class template first declared by a class-specifier is immediately after the identifieridentifier or simple-template-id (if any) in its class-head (Clause 9 class). ...
Note to the editor: We suggest to italicize "identifier" here because it refers to a specific part of the grammar, not the general concept.

UK 31: linkage of names inside anonymous namespaces

Change section 3.5 paragraph 4 last bullet as indicated:

UK 32: using constexpr with the main function

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

UK 33: integer conversion rank of signed char vs. char

Change in 4.13 conv.rank paragraph 1 bullet 1 and bullet 6 as indicated:
... ...

UK 36: introductory sentence for primary expressions

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

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

Add a bullet in 5.1.1 expr.prim.lambda paragraph 10 as indicated:
... ...

UK 59: va_arg vs. function parameter packs

Change section 5.2.2 expr.call paragraph 7 as indicated:
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.9 support.runtime). [ 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 ] ...

UK 62: "not an lvalue" vs. "rvalue"

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).

Change section 2.13.5 lex.bool paragraph 1 as indicated:
The Boolean literals are the keywords false and true. Such literals have type bool. They are not lvalues are rvalues and have type bool.
Change in section 5.2.5 expr.ref paragraph 4 bullet 3 sub-bullet 2 and bullet 5 as indicated:
Change in 14.1 temp.param paragraph 6 as indicated:
A non-type non-reference template-parameter is not an lvalue an rvalue. ...

UK 65: dynamic_cast and lvalues/rvalues

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

UK 66: derivation from std::type_info

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

UK 67: static_cast and lvalueness

Change section 5.2.9 expr.static.cast paragraph 2 as indicated:
... It is an lvalue if the type cast to is an lvalue reference; otherwise, it is an rvalue. ... The result is an rvalue. ...
Change section 5.2.9 expr.static.cast paragraph 3 as indicated:
... The result is an lvalue if T is an lvalue reference type (8.3.2 dcl.ref), and an rvalue otherwise. ...

UK 54: reinterpret_cast and implementation-defined behavior

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

UK 55: reinterpret_cast and constness

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

UK 56: reinterpret_cast and safely-derived pointers

Add to section 5.2.10 expr.reinterpret.cast paragraph 5:
... [ 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. ]

UK 68: most unary operators return rvalues

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

UK 47: description of sequencing for logical-and and logical-or

Change 5.15 expr.log.or paragraph 2 as indicated:
The result is a bool. All side effects of the first expression except for destruction of temporaries (12.2 class.temporary) happen before the second expression is evaluated. 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.

DE 11: late-checked block has no effect

Change 6.9 stmt.late paragraph 1 as indicated:
... Outside of a constrained context, the late-checked block has no effect the same meaning as if the late_check keyword were absent. ...

UK 84: stray "alignment-specifier" in the grammar

In 7.1 dcl.spec paragraph 1, remove the alignment-specifier from the grammar:
decl-specifier:
       storage-class-specifier
       type-specifier
       function-specifier
       friend
       typedef
       constexpr
       alignment-specifier

UK 91: Parenthesis handling for decltype

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

UK 110: example for atomics

Change section 7.6.5 dcl.attr.depend paragraphs 4, 5, 6 as indicated:
    /* CompilationTranslation unit A. */
    struct foo { int* a; int* b; };
    struct foo* foo_head[10];
    std::atomic<struct foo *> foo_head[10];
    int foo_array[10][10];

    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]);
    }

    /* CompilationTranslation 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));
    }
The annotation on function f means that the return value carries a dependency out of f, so that the implementation need constrain ordering upon return from f implementations of f and its caller may choose to preserve dependencies instead of emitting hardware memory ordering instructions (a.k.a. fences).
Function g's second argument is annotated, but its first argument is not. Therefore, function h's first call to g carries a dependency into g, but its second call does not. The implementation might need to constrain orderinginsert a fence prior to the second call to g.

FR 28: example for class object initialization

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

UK 132: copy construction for handler object

Change section 15.3 except.handle paragraph 16 as indicated and remove paragraph 17:
When the exception-declaration specifies a class type, a copy constructor is used to initialize either the object declared in the exception-declaration or, if the exception-declaration does not specify a name, a temporary object of that type. The object declared in an exception-declaration or, if the exception-declaration does not specify a name, a temporary (12.2 class.temporary) is copy-initialized (8.5 dcl.init) from the exception object. 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. 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.
The copy constructor and destructor associated with the object shall be accessible even if the copy operation is elided (12.8 class.copy).

UK 133: prohibit exception-specifications in alias-declarations

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

UK 139: library function exiting with an exception

Change section 15.5.1 except.terminate paragraph 1 first bullet as indicated: