<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>

    C++ Standard Core Language
    
      Defect Reports and Accepted Issues
     </TITLE>
</HEAD>
<BODY>
<TABLE ALIGN="RIGHT" CELLSPACING="0" CELLPADDING="0">
<TR>
<TD ALIGN="RIGHT">
      Document number:
     </TD>
<TD>
        &#160;WG21 N3714</TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Date:
     </TD>
<TD>
      &#160;2013-09-03</TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Project:
     </TD>
<TD>
      &#160;Programming Language C++
     </TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Reference:
     </TD>
<TD>
      &#160;ISO/IEC IS 14882:2003
     </TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Reply to:
     </TD>
<TD>
      &#160;William M. Miller
     </TD>
</TR>
<TR>
<TD></TD>
<TD>
      &#160;Edison Design Group, Inc.
     </TD>
</TR>
<TR>
<TD></TD>
<TD>
      &#160;<A HREF="mailto://wmm@edg.com">wmm@edg.com</A></TD>
</TR>
</TABLE><BR CLEAR="ALL"><BR><CENTER>
<H2>

     C++ Standard Core Language
     
       Defect Reports and Accepted Issues,
      

     Revision
     85</H2>
</CENTER><BR><P>
      This document contains the C++ core language issues that have been
      categorized as Defect Reports by the Committee (PL22.16 +
      WG21) and other accepted issues, that is, issues with status
      "<A HREF="#DR Status">DR</A>,"
      "<A HREF="#Accepted Status">accepted</A>,"
      "<A HREF="#DRWP Status">DRWP</A>,"
      "<A HREF="#WP Status">WP</A>,"
      "<A HREF="#CD1 Status">CD1</A>,"
      "<A HREF="#CD2 Status">CD2</A>,"
      "<A HREF="#TC1 Status">TC1</A>," and
      "<A HREF="#FDIS Status">FDIS</A>,"
      along with their proposed resolutions.  <B>Issues with DR,
      accepted, DRWP, and WP status are NOT part of the International
      Standard for C++.</B> They are provided for informational
      purposes only, as an indication of the intent of the Committee.
      They should not be considered definitive until or unless they
      appear in an approved Technical Corrigendum or revised
      International Standard for C++.
     </P>
<P>
    This document is part of a group of related documents that
    together describe the issues that have been raised regarding the
    C++ Standard.  The other documents in the group are:
   </P>
<UL>
<LI><A HREF="cwg_active.html">Active Issues List</A>, which contains
      explanatory material for the entire document group and a list of
      the issues that have not yet been acted upon by the Committee.
     </LI>
<LI><A HREF="cwg_closed.html">Closed Issues List</A>, which contains
      the issues which the Committee has decided are not defects
      in the International Standard, including a brief rationale
      explaining the reason for the decision.
     </LI>
<LI><A HREF="cwg_toc.html">Table of Contents</A>, which contains a
     summary listing of all issues in numerical order.
    </LI>
<LI><A HREF="cwg_index.html">Index by Section</A>, which contains a
     summary listing of all issues arranged in the order of the
     sections of the Standard with which they deal most directly.
    </LI>
<LI><A HREF="cwg_status.html">Index by Status</A>, which contains a
     summary listing of all issues grouped by status.
    </LI>
</UL>
<P>
     For more information, including a description of the meaning of
     the issue status codes and instructions on reporting new issues,
     please see <A HREF="cwg_active.html">the Active Issues List</A>.
    </P>
<P>
    Section references in this document reflect the section numbering
    of document
    <A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf">WG21 N3690</A>.
   </P>
<HR><A NAME="DR Status"></A><H3>Issues with "DR" Status</H3>
<HR><A NAME="616"></A><H4>616.
  
Definition of &#8220;indeterminate value&#8221;
</H4><B>Section: </B>1.3&#160; [intro.defs]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Bjarne Stroustrup
 &#160;&#160;&#160;

 <B>Date: </B>2 February 2007<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>The C++ Standard uses the phrase &#8220;indeterminate value&#8221;
without defining it.  C99 defines it as &#8220;either an unspecified
value or a trap representation.&#8221;  Should C++ follow suit?</P>

<P>In addition, 4.1 [conv.lval] paragraph 1 says that
applying the lvalue-to-rvalue conversion to an &#8220;object
[that] is uninitialized&#8221; results in undefined behavior;
this should be rephrased in terms of an object with an
indeterminate value.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<OL><LI><P>Change 4.1 [conv.lval] paragraphs 1 and 2 as
follows (including changing the running text of paragraph 2 into
bullets):</P></LI>

<BLOCKQUOTE>

<P>A glvalue (3.10 [basic.lval]) of a non-function, non-array
type <TT>T</TT> can be converted to a prvalue.<SUP>53</SUP> If
<TT>T</TT> is an incomplete type, a program that necessitates this
conversion is ill-formed. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">If the object to which the glvalue
refers is not an object of type <TT>T</TT> and is not an object of a
type derived from <TT>T</TT>, or if the object is uninitialized, a
program that necessitates this conversion has undefined
behavior.</SPAN> If <TT>T</TT> is a non-class type, the type of the
prvalue is the cv-unqualified version of <TT>T</TT>. Otherwise, the
type of the prvalue is <TT>T</TT>.<SUP>54</SUP></P>

<P>When an lvalue-to-rvalue conversion occurs in an unevaluated
operand or a subexpression thereof (Clause 5 [expr]) the
value contained in the referenced object is not accessed. <SPAN style="font-weight:bold;background-color:#A0FFA0">In all
other cases, the result of the conversion is determined according
to the following rules:</SPAN></P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">If <TT>T</TT> is (possibly cv-qualified)
<TT>std::nullptr_t</TT>, the result is a null pointer constant
(4.10 [conv.ptr]).</SPAN></P></LI>

<LI><P>Otherwise, if <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the glvalue</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>T</TT></SPAN> has
a class type, the conversion copy-initializes a temporary of type
<TT>T</TT> from the glvalue and the result of the conversion is a
prvalue for the temporary.</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">Otherwise, if the object to which the glvalue refers contains
an invalid pointer value (3.7.4.2 [basic.stc.dynamic.deallocation],
3.7.4.3 [basic.stc.dynamic.safety]), the behavior is 
implementation-defined.</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">Otherwise, if <TT>T</TT> is a (possibly cv-qualified)
unsigned character type (3.9.1 [basic.fundamental]), and the object
to which the glvalue refers contains an indeterminate value
(5.3.4 [expr.new], 8.5 [dcl.init], 12.6.2 [class.base.init]), and that object does not have automatic storage
duration or the glvalue was the operand of a unary <TT>&amp;</TT>
operator or it was bound to a reference, the result is an unspecified
value.  [<I>Footnote:</I> The value may be different each time the
lvalue-to-rvalue conversion is applied to the object.  An <TT>unsigned
char</TT> object with indeterminate value allocated to a register
might trap. &#8212;<I>end footnote</I>]</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">Otherwise, if the object to which the glvalue refers contains
an indeterminate value, the behavior is undefined.</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">Otherwise, if the glvalue
has (possibly cv-qualified) type <TT>std::nullptr_t</TT>, the prvalue
result is a null pointer constant (4.10 [conv.ptr]).</SPAN>
Otherwise, the value contained in the object indicated by the glvalue
is the prvalue result.</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 5.2.5 [expr.ref] paragraph 4 second bullet as
follows:</P></LI>

<UL><LI><P>If <TT>E2</TT> is a static data member...</P></LI>

<LI><P>...If <TT>E1</TT> is an lvalue, then <TT>E1.E2</TT> is an
lvalue; <SPAN style="text-decoration:line-through;background-color:#FFA0A0">if <TT>E1</TT> is an xvalue, then</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">otherwise</SPAN> <TT>E1.E2</TT> is an xvalue<SPAN style="text-decoration:line-through;background-color:#FFA0A0">; otherwise, it is a
prvalue</SPAN>.  Let the notation...</P></LI>

<LI><P>If <TT>E2</TT> is a (possibly overloaded) member
function...</P></LI>

</UL>

<LI><P>Change 5.5 [expr.mptr.oper] paragraph 6 as follows:</P></LI>

<BLOCKQUOTE>

...The result of a <TT>.*</TT> expression whose second operand is a
pointer to a data member is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">of the same value category
(3.10 [basic.lval]) as its first operand</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an lvalue
if the first operand is an lvalue and an xvalue otherwise</SPAN>.  The
result of a <TT>.*</TT> expression whose second operand is a pointer
to a member function...

</BLOCKQUOTE>

</OL>

<P>This resolution also resolves issues <A HREF="
     cwg_defects.html#129">129</A>,
<A HREF="
     cwg_defects.html#240">240</A>, <A HREF="
     cwg_defects.html#312">312</A>, and
<A HREF="
     cwg_defects.html#1013">1013</A>.</P>

<P>(See also <A HREF="
     cwg_defects.html#1213">issue 1213</A>.)</P>

<P><B>Additional note (August, 2012):</B></P>

<P>It was observed  that the phrase in the
fourth bullet of the change to 4.1 [conv.lval] paragraph 2
that reads &#8220;is not a local variable&#8221; should probably
be changed to &#8220;does not have automatic storage
duration,&#8221; because objects with static storage duration are
zero-initialized and thus cannot have an indeterminate value. The
issue was returned to "review" status for discussion of this point.</P>

<BR><BR><HR><A NAME="1476"></A><H4>1476.
  
Definition of user-defined type
</H4><B>Section: </B>1.3&#160; [intro.defs]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Lo&#239;c Joly
 &#160;&#160;&#160;

 <B>Date: </B>2012-03-08<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>

<P>The Standard uses the phrase, &#8220;user-defined type,&#8221; but it
is not clear what it is intended to mean.  For example,
17.6.4.2.1 [namespace.std] paragraph 1 says,</P>

<BLOCKQUOTE>

A program may add a template specialization for any standard library
template to namespace <TT>std</TT> only if the declaration depends on a
user-defined type...

</BLOCKQUOTE>

<P>Are types defined in the Standard library &#8220;user-defined?&#8221;</P>

<P>7.1.6.2 [dcl.type.simple] paragraph 2 says,</P>

<BLOCKQUOTE>

The <TT>auto</TT> specifier is a placeholder for a type to be deduced
(7.1.6.4 [dcl.spec.auto]). The other
<I>simple-type-specifier</I>s specify either a previously-declared
user-defined type or one of the fundamental types (3.9.1 [basic.fundamental]).

</BLOCKQUOTE>

<P>implying that all non-fundamental types are &#8220;user-defined.&#8221;</P>

<P>A definition is needed, as well as a survey of uses of the term to
ensure consistency with the definition.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<OL><LI><P>Change 7.1.6.2 [dcl.type.simple] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

The <TT>auto</TT> specifier is a placeholder for a type to be deduced
(7.1.6.4 [dcl.spec.auto]). The other
<I>simple-type-specifier</I>s specify either a previously-declared
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">user-defined</SPAN> type<SPAN style="font-weight:bold;background-color:#A0FFA0">, a type determined from an
expression,</SPAN> or one of the fundamental types (3.9.1 [basic.fundamental]). Table 10 summarizes the valid combinations of
<I>simple-type-specifier</I>s and the types they specify.

</BLOCKQUOTE>

<LI><P>Change 4 [conv] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

<P>[<I>Note:</I> For <SPAN style="text-decoration:line-through;background-color:#FFA0A0">user-defined</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">class</SPAN> types,
user-defined conversions are considered as well; see 12.3 [class.conv].  In general, an implicit conversion sequence
(13.3.3.1 [over.best.ics]) consists of a standard conversion
sequence followed by a user-defined conversion followed by another
standard conversion sequence.  &#8212;<I>end note</I>]
</P>

</BLOCKQUOTE>

<LI><P>Change the example in 13.3.1.2 [over.match.oper] paragraph 1
as follows:</P></LI>

<PRE>
  ...
  void f(void) {
    const char* p= "one" + "two";  //<SPAN style="font-family:Times;font-style:italic"> ill-formed because neither</SPAN>
                                   //<SPAN style="font-family:Times;font-style:italic"> operand has <SPAN style="text-decoration:line-through;background-color:#FFA0A0">user-defined</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">class or enumeration</SPAN> type</SPAN>
    int I = 1 + 1;                 //<SPAN style="font-family:Times;font-style:italic"> Always evaluates to </SPAN>2<SPAN style="font-family:Times;font-style:italic"> even if</SPAN>
                                   //<SPAN style="font-family:Times;font-style:italic"> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">user-defined</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">class or enumeration</SPAN> types exist which</SPAN>
                                   //<SPAN style="font-family:Times;font-style:italic"> would perform the operation.</SPAN>
  }
</PRE>

</OL>

<BR><BR><HR><A NAME="1531"></A><H4>1531.
  
Definition of &#8220;access&#8221; (verb)
</H4><B>Section: </B>1.3&#160; [intro.defs]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>2012-07-27<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>The verb &#8220;access&#8221; is used in various places in the
Standard (see 3.8 [basic.life] paragraphs 5 and 6 and
3.10 [basic.lval] paragraph 10) but is not defined.  C99
defines it as</P>

<BLOCKQUOTE>

&lt;execution-time action&gt; to read or modify the value of an object

</BLOCKQUOTE>

<P>(See also <A HREF="
     cwg_active.html#1530">issue 1530</A>.)</P>

<P><B>Proposed resolution (March, 2013):</B></P>

<OL><LI><P>Add the following to 1.3 [intro.defs]:</P></LI>

<BLOCKQUOTE>

<SPAN style="font-weight:bold;background-color:#A0FFA0"><B>access</B></SPAN><BR>
<SPAN style="font-weight:bold;background-color:#A0FFA0">&lt;execution-time action&gt; to read or modify the value of
an object</SPAN>

</BLOCKQUOTE>

<LI><P>Change 1.9 [intro.execution] paragraph 12 as follows:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Accessing</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Reading</SPAN> an object designated
by a volatile glvalue (3.10 [basic.lval]), modifying
an object, calling...

</BLOCKQUOTE>

<LI><P>Change 1.10 [intro.multithread] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

Two expression evaluations <I>conflict</I> if one of them
modifies a memory location (1.7 [intro.memory]) and
the other one <SPAN style="text-decoration:line-through;background-color:#FFA0A0">accesses</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">reads</SPAN> or
modifies the same memory location.

</BLOCKQUOTE>

<LI><P>Change 1.10 [intro.multithread] paragraph 24 as follows:</P></LI>

<BLOCKQUOTE>

<P>The implementation may assume that any thread will
eventually do one of the following:</P>

<UL><LI><P>...</P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">access</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">read</SPAN> or modify a
volatile object, or</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 5.17 [expr.ass] paragraph 8 as follows:</P></LI>

<BLOCKQUOTE>

If the value being stored in an object is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">accessed
from</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">read via</SPAN> another object that overlaps
in any way the storage of the first object, then the overlap
shall be exact and the two objects shall have the same type,
otherwise the behavior is undefined. [<I>Note:</I>...

</BLOCKQUOTE>

</OL>

<I>[Note: this wording was reviewed during the 2013-03-25
teleconference.]</I>

<BR><BR><HR><A NAME="129"></A><H4>129.
  
Stability of uninitialized auto variables
</H4><B>Section: </B>1.9&#160; [intro.execution]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Nathan Myers
 &#160;&#160;&#160;

 <B>Date: </B>26 June 1999<BR>



<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>Does the Standard require that an uninitialized auto variable have
a stable (albeit indeterminate) value?  That is, does the Standard
require that the following function return <TT>true</TT>?</P>

<PRE>
    bool f() {
        unsigned char i;  // not initialized
        unsigned char j = i;
        unsigned char k = i;
        return j == k;    // true iff "i" is stable
    }
</PRE>

3.9.1 [basic.fundamental]
 paragraph 1
requires that uninitialized <TT>unsigned char</TT> variables have a
valid value, so the initializations of <TT>j</TT> and <TT>k</TT> are
well-formed and required not to trap.  The question here is whether
the value of <TT>i</TT> is allowed to change between those
initializations.

<P><U>Mike Miller</U>:
1.9 [intro.execution]
 paragraph 10 says,</P>

<BLOCKQUOTE>
An instance of each object with automatic storage
duration (3.7.3 [basic.stc.auto]
) is
associated with each entry into
its block.  Such an object exists and retains its
last-stored value during the execution of the block
and while the block is suspended...
</BLOCKQUOTE>

I think that the most reasonable way to read this is that the
only thing that is allowed to change the value of an automatic
(non-volatile?) value is a "store" operation in the abstract
machine.  There are no "store" operations to <TT>i</TT> between the
initializations of <TT>j</TT> and <TT>k</TT>, so it must retain its
original (indeterminate but valid) value, and the result of
the program is well-defined.

<P>The quibble, of course, is whether the wording "last-stored
value" should be applied to a "never-stored" value.  I
think so, but others might differ.</P>

<P><U>Tom Plum</U>:
7.1.6.1 [dcl.type.cv]
 paragraph 8 says,</P>

<BLOCKQUOTE>
[<I>Note:</I> <TT>volatile</TT> is a hint to the implementation
to avoid aggressive
optimization involving
the object because the value of the object might be changed by means
undetectable 
by an implementation. See
1.9 [intro.execution]
 for detailed
semantics. In general, the semantics
of <TT>volatile</TT>
are intended to be the same in C++ as they are in C. ]
</BLOCKQUOTE>

&gt;From this I would infer that non-volatile means "shall not be
changed
by means undetectable by an implementation"; that the compiler is entitled to
safely cache accesses to non-volatile objects if it can prove that no
"detectable"
means can modify them; and that therefore  i  <I>shall</I>
maintain the same value
during the example above.

<P><U>Nathan Myers</U>:
This also has practical code-generation consequences.  If the
uninitialized auto variable lives in a register, and its value is 
<I>really</I> unspecified, then until it is initialized that register 
can be used as a temporary.  Each time it's "looked at" the variable
has the value that last washed up in that register.  After it's 
initialized it's "live" and cannot be used as a temporary any more, 
and your register pressure goes up a notch.  Fixing the uninit'd 
value would make it "live" the first time it is (or might be) looked 
at, instead.</P>

<P><U>Mike Ball</U>:
I agree with this.  I also believe that it was certainly never
my intent that an uninitialized variable be stable, and I would
have strongly argued against such a provision.  Nathan has well
stated the case.
And I am quite certain that it would be disastrous for optimizers.
To ensure it, the frontend would have to generate an initializer,
because optimizers track not only the lifetimes of variables, but
the lifetimes of values assigned to those variables.  This would
put C++ at a significant performance disadvantage compared to
other languages.  Not even Java went this route.  Guaranteeing 
defined behavior for a very special case of a generally undefined
operation seems unnecessary.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#616">issue 616</A>.</P>

<BR><BR><HR><A NAME="1472"></A><H4>1472.
  
odr-use of reference variables
</H4><B>Section: </B>3.2&#160; [basic.def.odr]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2012-03-01<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>We have a special case in 3.2 [basic.def.odr] paragraph 2 that
variables which satisfy the requirements for appearing in a constant
expression are not odr-used if the lvalue-to-rvalue conversion is
immediately applied. This special case only applies to objects, and
thus does not apply to variables of reference type.  This
inconsistency seems strange, and there is implementation divergence:
</P>

<PRE>
  int n;
  void f() {
   constexpr int &amp;r = n;
   [] { return r; }; //<SPAN style="font-family:Times;font-style:italic"> error: </SPAN>r<SPAN style="font-family:Times;font-style:italic"> is odr-used but not captured</SPAN>
  }
</PRE>

<P>This code is accepted by g++ but rejected by clang. Should <TT>r</TT> be
odr-used here?
</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 3.2 [basic.def.odr] paragraph 3 as follows:</P>

<BLOCKQUOTE>

A variable <TT>x</TT> whose name appears as a potentially-evaluated
expression <TT>ex</TT> is <I>odr-used</I> unless <TT>x</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">is an
object that</SPAN> satisfies the requirements for appearing in a
constant expression (5.19 [expr.const]) and<SPAN style="font-weight:bold;background-color:#A0FFA0">, if
<TT>x</TT> is an object,</SPAN> <TT>ex</TT> is an element of the set of
potential results of an expression <TT>e</TT>, where either the
lvalue-to-rvalue conversion (4.1 [conv.lval]) is applied to
<TT>e</TT>, or <TT>e</TT> is a discarded-value expression (Clause
5 [expr]).  <TT>this</TT> is odr-used...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1511"></A><H4>1511.
  
<TT>const volatile</TT> variables and the one-definition rule
</H4><B>Section: </B>3.2&#160; [basic.def.odr]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2012-06-18<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>One of the criteria in 3.2 [basic.def.odr] paragraph 6 for
when a entity is allowed to have multiple definitions is:</P>

<BLOCKQUOTE>

in each definition of <TT>D</TT>, corresponding names, looked up
according to 3.4 [basic.lookup], shall refer to an entity
defined within the definition of <TT>D</TT>, or shall refer to the
same entity, after overload resolution (13.3 [over.match]) and
after matching of partial template specialization (14.8.3 [temp.over]), except that a name can refer to a <TT>const</TT>
object with internal or no linkage if the object has the same literal
type in all definitions of <TT>D</TT>, and the object is initialized
with a constant expression (5.19 [expr.const]), and the value
(but not the address) of the object is used, and the object has the
same value in all definitions of <TT>D</TT>; and

</BLOCKQUOTE>

<P>This wording is possibly not sufficiently clear for an example like:</P>

<PRE>
  const volatile int n = 0;
  inline int get() { return n; }
</PRE>

<P>Presumably this code could not appear in multiple translation units,
because the requirement that <TT>n</TT> &#8220;has the same value in
all definitions&#8221; cannot be satisfied (the value of a volatile
variable can change &#8220;by means undetectable by the
implementation,&#8221; per 7.1.6.1 [dcl.type.cv] paragraph 7,
so the value of <TT>n</TT> might be different in each translation
unit).  However, it might be good to make it explicit that &#8220;a
<TT>const</TT> object&#8221; is not intended to apply to a
volatile-qualified object.</P>

<P>Other points that were raised during the discussion of this issue
were that it would probably be better to rephrase &#8220;the value
(but not the address) of the object is used&#8221; in terms of the
odr-use of the object, as well as questioning why a <TT>const
volatile</TT> variable implicitly has internal linkage.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<OL><LI><P>Change 3.2 [basic.def.odr] paragraph 6 as follows:</P></LI>

<BLOCKQUOTE>

<P>There can be more than one definition...</P>

<UL><LI><P>...</P></LI>

<LI><P>in each definition of <TT>D</TT>, corresponding names, looked
up according to 3.4 [basic.lookup], shall refer to an entity
defined within the definition of <TT>D</TT>, or shall refer to the
same entity, after overload resolution (13.3 [over.match]) and
after matching of partial template specialization (14.8.3 [temp.over]), except that a name can refer to a
<SPAN style="font-weight:bold;background-color:#A0FFA0">non-volatile</SPAN> <TT>const</TT> object with internal or no
linkage if the object has the same literal type in all definitions of
<TT>D</TT>, and the object is initialized with a constant expression
(5.19 [expr.const]), and <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the value (but not the address)
of</SPAN> the object is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">used</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">not odr-used</SPAN>, and
the object has the same value in all definitions of <TT>D</TT>;
and</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 3.5 [basic.link] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

<P>A name having namespace scope (3.3.6 [basic.scope.namespace]) has
internal linkage if it is the name of</P>

<UL><LI><P>a variable, function or function template that is
explicitly declared <TT>static</TT>; or,</P></LI>

<LI><P>a <SPAN style="font-weight:bold;background-color:#A0FFA0">non-volatile</SPAN> variable that is explicitly declared
<TT>const</TT> or <TT>constexpr</TT> and neither explicitly declared
<TT>extern</TT> nor previously declared to have external linkage;
or</P></LI>

<LI><P>a data member of an anonymous union.</P></LI>

</UL>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1482"></A><H4>1482.
  
Point of declaration of enumeration
</H4><B>Section: </B>3.3.2&#160; [basic.scope.pdecl]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>2012-03-20<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>

<P>According to 3.3.2 [basic.scope.pdecl] paragraph 2,</P>

<BLOCKQUOTE>

The point of declaration for an enumeration is immediately after the
identifier (if any) in either its <I>enum-specifier</I> (7.2 [dcl.enum]) or its first <I>opaque-enum-declaration</I> (7.2 [dcl.enum]), whichever comes first.

</BLOCKQUOTE>

<P>This would make the following example well-formed:</P>

<PRE>
  template&lt;typename T&gt; struct S { typedef char I; };
  enum E: S&lt;E&gt;::I { e }; 
</PRE>

<P>Presumably that would make <TT>E</TT> an incomplete enumeration type
for the instantiation of <TT>S&lt;E&gt;</TT> (a concept not otherwise
found in the Standard).  However, some implementations reject this
example, presumably making the point of declaration after the
<I>enum-base</I>.  We either need to make it ill-formed or describe
incomplete enumeration types.</P>

<P>See also <A HREF="
     cwg_defects.html#977">issue 977</A>.</P>

<P><B>Proposed resolution (December, 2012):</B></P>

<OL><LI><P>Change 3.9 [basic.types] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

A class that has been declared but not defined, <SPAN style="font-weight:bold;background-color:#A0FFA0">an enumeration
type in certain contexts (7.2 [dcl.enum]),</SPAN> or an array
of unknown size or of incomplete element type, is an
incompletely-defined object type.<SUP>43</SUP> Incompletely-defined
object types...

</BLOCKQUOTE>

<LI><P>Add the following as a new paragraph preceding
7.2 [dcl.enum] paragraph 6:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">An enumeration whose underlying type is fixed is an incomplete
type from its point of declaration (3.3.2 [basic.scope.pdecl]) to
immediately after its <I>enum-base</I> (if any), at which point it
becomes a complete type. An enumeration whose underlying type is not
fixed is an incomplete type from its point of declaration to
immediately after the closing <TT>}</TT> of its
<I>enum-specifier</I>, at which point it becomes a complete
type.</SPAN></P>

<P>For an enumeration whose underlying type is not fixed...</P>

</BLOCKQUOTE>

</OL>

<P>This resolution also resolves <A HREF="
     cwg_defects.html#977">issue 977</A>.</P>

<BR><BR><HR><A NAME="1310"></A><H4>1310.
  
What is an &#8220;acceptable lookup result?&#8221;
</H4><B>Section: </B>3.4.3.1&#160; [class.qual]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2011-05-06<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>In 3.4.3.1 [class.qual] paragraph 2,</P>

<BLOCKQUOTE>

<P>In a lookup in which the constructor is an acceptable lookup result
and the <I>nested-name-specifier</I> nominates a class <TT>C</TT>:</P>

<UL>

<LI><P>if the name specified after the <I>nested-name-specifier</I>, when
looked up in <TT>C</TT>, is the injected-class-name of <TT>C</TT>
(Clause 9 [class]), or
</P></LI>

<LI><P>in a <I>using-declaration</I> (7.3.3 [namespace.udecl]) that is a
<I>member-declaration</I>, if the name specified after the
<I>nested-name-specifier</I> is the same as the <I>identifier</I> or
the <I>simple-template-id</I>'s <I>template-name</I> in the last
component of the <I>nested-name-specifier</I>,
</P></LI>

</UL>

<P>the name is instead considered to name the constructor of class
<TT>C</TT>.
</P>

</BLOCKQUOTE>

<P>it is not clear what constitutes &#8220;an acceptable lookup
result.&#8221;  For instance, is</P>

<PRE>
  struct S { } *sp = new S::S;
</PRE>

<P>well-formed?</P>

<P>The intent of the wording was that <TT>S::S</TT> would refer to
the constructor except in lookups that ignore the names of functions,
e.g., in <I>elaborated-type-specifier</I>s and
<I>nested-name-specifier</I>s.  There doesn't seem to be a good reason
to allow a <I>qualified-id</I> naming the injected-class-name.  The
alternative, i.e., only to find the constructor in a declarator,
complicates parsing because the determination of whether the name is
a type or a function would require lookahead.</P>

<P><B>Proposed resolution (August, 2012):</B></P>

<P>Change 3.4.3.1 [class.qual] paragraph 2 as follows:</P>

<BLOCKQUOTE>

<P>In a lookup in which <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the constructor is an acceptable lookup
result</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">function names are not ignored [<I>Footnote:</I>
Lookups in which function names are ignored include names appearing in
a <I>nested-name-specifier</I>, an <I>elaborated-type-specifier</I>,
or a <I>base-specifier</I>. &#8212;<I>end footnote</I>]</SPAN> and the
<I>nested-name-specifier</I> nominates a class <TT>C</TT>:</P>

<UL><LI>

<P>if the name specified after the <I>nested-name-specifier</I>, when
looked up in <TT>C</TT>, is the injected-class-name of C (Clause
9 [class]), or
</P></LI>

<LI>

<P>in a <I>using-declaration</I> (7.3.3 [namespace.udecl]) that is
a <I>member-declaration</I>, if the name specified after the
<I>nested-name-specifier</I> is the same as the identifier or the
<I>simple-template-id</I>'s <I>template-name</I> in the last component
of the <I>nested-name-specifier</I>,
</P></LI>

</UL>

<P>the name is instead considered to name the constructor of class
<TT>C</TT>...
</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1489"></A><H4>1489.
  
Is value-initialization of an array constant initialization?
</H4><B>Section: </B>3.6.2&#160; [basic.start.init]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>2012-03-29<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>

<P>According to 3.6.2 [basic.start.init] paragraph 2,</P>

<BLOCKQUOTE>

<P><I>Constant initialization</I> is performed:</P>

<UL><LI><P>...</P></LI>

<LI>

<P>if an object with static or thread storage duration is not initialized
by a constructor call and if every full-expression that appears in its
initializer is a constant expression.
</P>
</LI>

</UL>

</BLOCKQUOTE>

<P>Presumably this would include a value-initialization (i.e., with no
expressions) such as</P>

<PRE>
  int a[1000]{};
</PRE>

<P>However, we have recently clarified the degenerate cases of other
similar rules referencing &#8220;every,&#8221; so it wouldn't hurt to
be more explicit here.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 3.6.2 [basic.start.init] paragraph 2 as follows:</P>

<BLOCKQUOTE>

<P>Constant initialization is performed:</P>

<UL><LI><P>...</P></LI>

<LI><P>if an object with static or thread storage duration is not
initialized by a constructor call and if <SPAN style="font-weight:bold;background-color:#A0FFA0">either the object is
value-initialized or</SPAN> every full-expression that appears in its
initializer is a constant expression.</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="312"></A><H4>312.
  
&#8220;use&#8221; of invalid pointer value not defined
</H4><B>Section: </B>3.7.4.2&#160; [basic.stc.dynamic.deallocation]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Martin von Loewis
 &#160;&#160;&#160;

 <B>Date: </B>20 Sep 2001<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>

<P>3.7.4.2 [basic.stc.dynamic.deallocation] paragraph 4 mentions that the effect
of using an invalid pointer value is undefined. However, the standard
never says what it means to 'use' a value.</P>

<P>There are a number of possible interpretations, but it appears that
each of them leads to undesired conclusions:</P>
<OL>
<LI>
A value is 'used' in a program if a variable holding this value
appears in an expression that is evaluated.
This interpretation would render the sequence
<PRE>
   int *x = new int(0);
   delete x;
   x = 0;
</PRE>
into undefined behaviour. As this is a common idiom, this is
clearly undesirable.
</LI>
<LI>
A value is 'used' if an expression evaluates to that value.
This would render the sequence
<PRE>
   int *x = new int(0);
   delete x;
   x-&gt;~int();
</PRE>
into undefined behaviour; according to 5.2.4 [expr.pseudo],
the variable x is
'evaluated' as part of evaluating the pseudo destructor call. This,
in turn, would mean that all containers (23 [containers])
of pointers show
undefined behaviour, e.g. 23.3.6.4 [list.modifiers]
requires to invoke the
destructor as part of the <TT>clear()</TT> method of the container.
</LI>
</OL>

<P>If any other meaning was intended for 'using an expression', that
meaning should be stated explicitly.</P>

<P>(See also <A HREF="
     cwg_closed.html#623">issue 623</A>.)</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#616">issue 616</A>.</P>

<BR><BR><HR><A NAME="496"></A><H4>496.
  
Is a volatile-qualified type really a POD?
</H4><B>Section: </B>3.9&#160; [basic.types]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>John Maddock
 &#160;&#160;&#160;

 <B>Date: </B>30 Dec 2004<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>In 3.9 [basic.types] paragraph 10, the standard makes
it quite clear that volatile qualified types are PODs:</P>

<BLOCKQUOTE>

Arithmetic types (3.9.1 [basic.fundamental]), enumeration
types, pointer types, and pointer to member types (3.9.2 [basic.compound]), and <I>cv-qualified</I> versions of these
types (3.9.3 [basic.type.qualifier]) are collectively called
<I>scalar types</I>. Scalar types, POD-struct types, POD-union
types (clause 9 [class]), arrays of such types and
<I>cv-qualified</I> versions of these types (3.9.3 [basic.type.qualifier]) are collectively called <I>POD types</I>.

</BLOCKQUOTE>

<P>However in 3.9 [basic.types] paragraph 3, the
standard makes it clear that PODs can be copied &#8220;as
if&#8221; they were a collection of bytes by <TT>memcpy</TT>:</P>

<BLOCKQUOTE>

For any POD type <TT>T</TT>, if two pointers to <TT>T</TT> point to
distinct <TT>T</TT> objects <TT>obj1</TT> and <TT>obj2</TT>, where
neither <TT>obj1</TT> nor <TT>obj2</TT> is a base-class subobject, if
the value of <TT>obj1</TT> is copied into <TT>obj2</TT>, using
the <TT>std::memcpy</TT> library function, <TT>obj2</TT> shall
subsequently hold the same value as <TT>obj1</TT>.

</BLOCKQUOTE>

<P>The problem with this is that a volatile qualified type may
need to be copied in a specific way (by copying using only atomic
operations on multithreaded platforms, for example) in order to
avoid the &#8220;memory tearing&#8221; that may occur with a
byte-by-byte copy.</P>

<P>I realise that the standard says very little about volatile
qualified types, and nothing at all (yet) about multithreaded
platforms, but nonetheless this is a real issue, for the
following reason:</P>

<P>The forthcoming TR1 will define a series of traits that
provide information about the properties of a type, including
whether a type is a POD and/or has trivial construct/copy/assign
operations.  Libraries can use this information to optimise their
code as appropriate, for example an array of type <TT>T</TT>
might be copied with a <TT>memcpy</TT> rather than an
element-by-element copy if <TT>T</TT> is a POD.  This was one of
the main motivations behind the type traits chapter of the TR1.
However it's not clear how volatile types (or POD's which have a
volatile type as a member) should be handled in these cases.</P>

<P><B>Notes from the April, 2005 meeting:</B></P>

<P>It is not clear whether the volatile qualifier actually guarantees
atomicity in this way.  Also, the work on the memory model for
multithreading being done by the Evolution Working Group seems at this
point likely to specify additional semantics for volatile data, and
that work would need to be considered before resolving this issue.</P>

<P><B>Proposed resolution, October, 2012:</B></P>

<OL><LI><P>Change 3.9 [basic.types] paragraph 9 as follows:</P></LI>

<BLOCKQUOTE>

...Scalar types, trivially copyable class types (Clause 9 [class]), arrays of such types, and <SPAN style="text-decoration:line-through;background-color:#FFA0A0">cv-qualified</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">non-volatile const-qualified</SPAN> versions of these types
(3.9.3 [basic.type.qualifier]) are collectively called <I>trivially
copyable types</I>. Scalar types, trivial class types...

</BLOCKQUOTE>

<LI><P>Change 7.1.6.1 [dcl.type.cv] paragraphs 6-7 as follows:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">What constitutes an access to an object that has
volatile-qualified type is implementation-defined.</SPAN> If an attempt
is made to refer to an object defined with a volatile-qualified type
through the use of a glvalue with a non-volatile-qualified type, the
program behavior is undefined.</P>

<P>[<I>Note:</I> <TT>volatile</TT> is a hint to the implementation to
avoid aggressive optimization involving the object because the value
of the object might be changed by means undetectable by an
implementation. <SPAN style="font-weight:bold;background-color:#A0FFA0">Furthermore, for some implementations,
<TT>volatile</TT> might indicate that special hardware instructions
are required to access the object.</SPAN> See 1.9 [intro.execution]
for detailed semantics.  In general, the semantics of
<TT>volatile</TT> are intended to be the same in C++ as they are in
C. &#8212;<I>end note</I>]</P>

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraph 12 as follows:</P></LI>

<BLOCKQUOTE>

<P>A copy/move constructor for class <TT>X</TT> is trivial if it is not
user-provided, its declared parameter type is the same as if it had
been implicitly declared, and if</P>

<UL><LI><P>class <TT>X</TT> has no virtual functions (10.3 [class.virtual]) and no virtual base classes (10.1 [class.mi]),
and</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">class <TT>X</TT> has no non-static data members of
volatile-qualified type, and</SPAN></P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraph 25 as follows:</P></LI>

<BLOCKQUOTE>

<P>A copy/move assignment operator for class <TT>X</TT> is trivial if
it is not user-provided, its declared parameter type is the same as if
it had been implicitly declared, and if</P>

<UL><LI><P>class <TT>X</TT> has no virtual functions (10.3 [class.virtual]) and no virtual base classes (10.1 [class.mi]),
and</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">class <TT>X</TT> has no non-static data members of
volatile-qualified type, and</SPAN></P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1361"></A><H4>1361.
  
Requirement on <I>brace-or-equal-initializer</I>s of literal types
</H4><B>Section: </B>3.9&#160; [basic.types]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-16<BR>




<P>The requirement in 3.8 [basic.life] paragraph 10 that</P>

<UL><LI>every constructor call and full-expression in the
<I>brace-or-equal-initializer</I>s for non-static data members (if
any) is a constant expression (5.19 [expr.const]),</LI></UL>

<P>is mostly redundant with the <TT>constexpr</TT> constructor
requirements in 7.1.5 [dcl.constexpr] paragraph 4 (although
12.6.2 [class.base.init] does not establish a strict equivalence
between <I>brace-or-equal-initializer</I>s and
<I>mem-initializer</I>s).</P>



<P><B>Proposed resolution (April, 2013):</B></P>

<P>This issue is resolved by the changes in N3652, adopted at the
April, 2013 (Bristol) meeting.</P>

<BR><BR><HR><A NAME="1405"></A><H4>1405.
  
<TT>constexpr</TT> and mutable members of literal types
</H4><B>Section: </B>3.9&#160; [basic.types]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2011-10-21<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>Currently, literal class types can have mutable members.  It is not
clear whether that poses any particular problems with constexpr objects
and constant expressions, and if so, what should be done about it.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 5.19 [expr.const] paragraph 2 as follows:</P>

<UL><LI><P>...</P></LI>

<LI><P>an lvalue-to-rvalue conversion (4.1 [conv.lval])
unless it is applied to</P></LI>

<UL><LI><P>a glvalue of integral or enumeration type that refers to a
non-volatile const object with a preceding initialization, initialized
with a constant expression, or</P></LI>

<LI><P>a glvalue of literal type that refers to a non-volatile object
defined with <TT>constexpr</TT>, or that refers to a
<SPAN style="font-weight:bold;background-color:#A0FFA0">non-mutable</SPAN> sub-object of such an object, or</P></LI>

<LI><P>a glvalue of literal type that refers to a non-volatile
temporary object whose lifetime has not ended, initialized with a
constant expression;</P></LI>

</UL>

<LI><P>...</P></LI>

</UL>

<BR><BR><HR><A NAME="1515"></A><H4>1515.
  
Modulo 2<SUP><I>n</I></SUP> arithmetic for implicitly-unsigned types
</H4><B>Section: </B>3.9.1&#160; [basic.fundamental]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Sean Hunt
 &#160;&#160;&#160;

 <B>Date: </B>2012-07-03<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>

<P>According to 3.9.1 [basic.fundamental] paragraph 4,</P>

<BLOCKQUOTE>

Unsigned integers, declared <TT>unsigned</TT>, shall obey the laws of
arithmetic modulo 2<SUP><I>n</I></SUP> where <I>n</I> is the number of
bits in the value representation of that particular size of integer.

</BLOCKQUOTE>

<P>It is not clear whether this wording intentionally excludes types
like <TT>char16_t</TT> and <TT>char32_t</TT> (and, possibly, types
<TT>char</TT> and <TT>wchar_t</TT>, if those types are unsigned in
a given implementation), since the <TT>unsigned</TT> keyword is not
used in their declaration.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 3.9.1 [basic.fundamental] paragraph 4 as follows:</P>

<BLOCKQUOTE>

Unsigned integers<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, declared <TT>unsigned</TT>,</SPAN> shall obey
the laws of arithmetic modulo 2<SUP><I>n</I></SUP> where <I>n</I> is
the number of bits in the value representation of that particular size
of integer.<SUP>46</SUP>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1539"></A><H4>1539.
  
Definition of &#8220;character type&#8221;
</H4><B>Section: </B>3.9.1&#160; [basic.fundamental]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Beman Dawes
 &#160;&#160;&#160;

 <B>Date: </B>2012-08-15<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>The term <I>character type</I> is used in the Standard without
definition.  It should be defined; however, the use of the term is
divergent between the core and library clauses: in the former, it means
narrow character types, while in the latter it includes <TT>wchar_t</TT>,
<TT>char16_t</TT>, and <TT>char32_t</TT>, so care must be taken in
ensuring that no inadvertent changes are implied.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<OL><LI><P>Change 3.7.4.3 [basic.stc.dynamic.safety] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<P>A <I>traceable pointer object</I> is</P>

<UL><LI><P>...</P></LI>

<LI><P>a sequence of elements in an array of <SPAN style="font-weight:bold;background-color:#A0FFA0">narrow</SPAN>
character type <SPAN style="font-weight:bold;background-color:#A0FFA0">(3.9.1 [basic.fundamental])</SPAN>, where the size
and alignment of the sequence match those of some object pointer
type.</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 3.9.1 [basic.fundamental] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

Objects declared as characters (char) shall be large enough to store
any member of the implementation's basic character set. If a character
from this set is stored in a character object, the integral value of
that character object is equal to the value of the single character
literal form of that character. It is implementation-defined whether a
<TT>char</TT> object can hold negative values. Characters can be
explicitly declared <TT>unsigned</TT> or <TT>signed</TT>.  Plain
<TT>char</TT>, <TT>signed char</TT>, and <TT>unsigned char</TT> are
three distinct types<SPAN style="font-weight:bold;background-color:#A0FFA0">, collectively called <I>narrow character
types</I></SPAN>.  A <TT>char</TT>, a <TT>signed char</TT>, and an
<TT>unsigned char</TT> occupy the same amount of storage and have the
same alignment requirements (3.11 [basic.align]); that is, they
have the same object representation. For <SPAN style="font-weight:bold;background-color:#A0FFA0">narrow</SPAN> character
types, all bits of the object representation participate in the value
representation. For unsigned <SPAN style="font-weight:bold;background-color:#A0FFA0">narrow</SPAN> character types, all
possible bit patterns of the value representation represent numbers.
These requirements do not hold for other types.  In any particular
implementation, a plain <TT>char</TT> object can take on either the
same values as a <TT>signed char</TT> or an <TT>unsigned char</TT>;
which one is implementation-defined.

</BLOCKQUOTE>

<LI><P>Change 3.11 [basic.align] paragraph 6 as follows:</P></LI>

<BLOCKQUOTE>

The alignment requirement of a complete type can be queried using an
<TT>alignof</TT> expression (5.3.6 [expr.alignof]).
Furthermore, the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">types <TT>char</TT>, <TT>signed char</TT>, and
<TT>unsigned char</TT></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">narrow character types (3.9.1 [basic.fundamental])</SPAN> shall have the weakest alignment requirement.
[<I>Note:</I> This enables the <SPAN style="font-weight:bold;background-color:#A0FFA0">narrow</SPAN> character types to be
used as the underlying type for an aligned memory area (7.6.2 [dcl.align]). &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Change 8.5.2 [dcl.init.string] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A <TT>char</TT> array (whether plain <TT>char</TT>, <TT>signed
char</TT>, or <TT>unsigned char</TT>)</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">An array of narrow
character type (3.9.1 [basic.fundamental])</SPAN>, <TT>char16_t
</TT>array, <TT>char32_t</TT> array, or <TT>wchar_t</TT> array can be
initialized by a narrow <SPAN style="text-decoration:line-through;background-color:#FFA0A0">character</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">string</SPAN>
literal, <TT>char16_t</TT> string literal, <TT>char32_t</TT> string
literal, or wide string literal, respectively, or by an
appropriately-typed string literal enclosed in braces
<SPAN style="font-weight:bold;background-color:#A0FFA0">(2.14.5 [lex.string])</SPAN>.  Successive characters of
the value of the string literal initialize the elements of the
array. [<I>Example:</I>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="240"></A><H4>240.
  
Uninitialized values and undefined behavior
</H4><B>Section: </B>4.1&#160; [conv.lval]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>8 Aug 2000<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>4.1 [conv.lval] paragraph 1 says,</P>

<BLOCKQUOTE>

If the object to which the lvalue refers is not an object of type
<TT>T</TT> and is not an object of a type derived from <TT>T</TT>, or
if the object is uninitialized, a program that necessitates this
conversion has undefined behavior.

</BLOCKQUOTE>

<P>I think there are at least three related issues around this
specification:</P>

<OL>

<LI><P>Presumably assigning a valid value to an uninitialized
object allows it to participate in the lvalue-to-rvalue
conversion without undefined behavior (otherwise the number of
programs with defined behavior would be vanishingly small :-).
However, the wording here just says "uninitialized" and doesn't
mention assignment.</P></LI>

<LI><P>There's no exception made for <TT>unsigned char</TT> types.
The wording in 3.9.1 [basic.fundamental] was carefully crafted to
allow use of <TT>unsigned char</TT> to access uninitialized data so
that <TT>memcpy</TT> and such could be written in C++ without
undefined behavior, but this statement undermines that
intent.</P></LI>

<LI><P>It's possible to get an uninitialized rvalue without invoking
the lvalue-to-rvalue conversion.  For instance:</P>

<PRE>
        struct A {
            int i;
            A() { } // no init of A::i
        };
        int j = A().i;  // uninitialized rvalue
</PRE>

<P>There doesn't appear to be anything in the current IS wording
that says that this is undefined behavior.  My guess is that we
thought that in placing the restriction on use of uninitialized
objects in the lvalue-to-rvalue conversion we were catching all
possible cases, but we missed this one.</P></LI>

</OL>

<P>In light of the above, I think the discussion of uninitialized
objects ought to be removed from 4.1 [conv.lval] paragraph
1.  Instead, something like the following ought to be added to
3.9 [basic.types] paragraph 4 (which is where the concept of
"value" is introduced):</P>

<BLOCKQUOTE>
Any use of an indeterminate value (5.3.4 [expr.new],
8.5 [dcl.init], 12.6.2 [class.base.init]) of any type
other than <TT>char</TT> or <TT>unsigned char</TT> results in
undefined behavior.
</BLOCKQUOTE>

<P><U>John Max Skaller</U>:</P>

<P><TT>A().i</TT> had better be an lvalue; the rules are wrong.
Accessing a member of a structure requires it be converted to
an lvalue, the above calculation is 'as if':</P>

<PRE>
    struct A {
        int i;
        A *get() { return this; }
    };
    int j = (*A().get()).i;
</PRE>

<P>and you can see the bracketed expression is an lvalue. </P>

<P>A consequence is:</P>

<PRE>
    int &amp;j= A().i; // OK, even if the temporary evaporates
</PRE>

<P><TT>j</TT> now refers to a 'destroyed' value. Any use of <TT>j</TT>
is an error.  But the binding at the time is valid.</P>

<P><B>Proposed Resolution (November, 2006):</B></P>

<OL><LI><P>Add the indicated words to 3.9 [basic.types] paragraph 4:</P>

<BLOCKQUOTE>

... For trivial 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. <SPAN style="font-weight:bold;background-color:#A0FFA0">Any use of an
indeterminate value (5.3.4 [expr.new], 8.5 [dcl.init],
12.6.2 [class.base.init]) of a type other than <TT>unsigned char</TT>
results in undefined behavior.</SPAN>

</BLOCKQUOTE>
</LI>

<LI><P>Change 4.1 [conv.lval] paragraph 1 as follows:</P>

<BLOCKQUOTE>

If the object to which the lvalue refers is not an object of
type <TT>T</TT> and is not an object of a type derived
from <TT>T</TT>, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or if the object is uninitialized,</SPAN> a program
that necessitates this conversion has undefined behavior.

</BLOCKQUOTE>
</LI>

</OL>

<P><B>Additional note (May, 2008):</B></P>

<P>The C committee is dealing with a similar issue in their <A HREF="http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_338.htm">DR338</A>.
According to <A HREF="http://wiki.dinkumware.com/twiki/pub/WG14/DefectReports/dr338_response.txt">
this analysis</A>, they plan to take almost the opposite approach
to the one described above by augmenting the description of their
version of the lvalue-to-rvalue conversion.  The CWG did not
consider that access to an unsigned char might still trap if it
is allocated in a register and needs to reevaluate the proposed
resolution in that light.  See also <A HREF="
     cwg_defects.html#129">issue 129</A>.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#616">issue 616</A>.</P>

<BR><BR><HR><A NAME="1013"></A><H4>1013.
  
Uninitialized <TT>std::nullptr_t</TT> objects
</H4><B>Section: </B>4.1&#160; [conv.lval]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Miller
 &#160;&#160;&#160;

 <B>Date: </B>2009-12-10<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>

<P>According to 4.1 [conv.lval] paragraph 1, an lvalue-to-rvalue
conversion on an uninitialized object produces undefined behavior.  Since
there is only one &#8220;value&#8221; of type <TT>std::nullptr_t</TT>, an
lvalue-to-rvalue conversion on a <TT>std::nullptr_t</TT> glvalue does not
need to fetch the value from storage.  Is there any need for undefined
behavior in this case?</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#616">issue 616</A>.</P>

<BR><BR><HR><A NAME="974"></A><H4>974.
  
Default arguments for lambdas
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>4 September, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US29">N3092 comment
  US&#160;29<BR></A>

<P>[Moved to DR status at the April, 2013 meeting.]</P>



<P>There does not appear to be any technical difficulty that would
require the restriction in 5.1.2 [expr.prim.lambda] paragraph 5
against default arguments in <I>lambda-expression</I>s.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Delete the following sentence from 5.1.2 [expr.prim.lambda]
paragraph 5:</P>

<BLOCKQUOTE><SPAN style="text-decoration:line-through;background-color:#FFA0A0">Default arguments (8.3.6 [dcl.fct.default]) shall
not be specified in the <I>parameter-declaration-clause</I> of a
<I>lambda-declarator</I>.</SPAN></BLOCKQUOTE>

<P><B>Additional note (February, 2012):</B></P>

<P>EWG requested that the adoption of this proposed resolution be
postponed to allow them to discuss it.  The issue has thus been
returned to "review" status pending EWG action.</P>

<BR><BR><HR><A NAME="975"></A><H4>975.
  
Restrictions on return type deduction for lambdas
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>4 September, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US30">N3092 comment
  US&#160;30<BR></A>

<P>[Moved to DR status at the April, 2013 meeting as part of paper N3638.]</P>



<P>There does not appear to be any technical difficulty that would
require the current restriction that the return type of a lambda can
be deduced only if the body of the lambda consists of a single return
statement.  In particular, multiple return statements could be
permitted if they all return the same type.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 5.1.2 [expr.prim.lambda] paragraph 4 as follows:</P>

<BLOCKQUOTE>

<P>...If a <I>lambda-expression</I> does not include a
<I>trailing-return-type</I>, it is as if the <I>trailing-return-type</I>
denotes the following type:</P>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">if the compound-statement is of the form</SPAN></P>

<UL><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>{</TT> <I>attribute-specifier-seq<SUB>opt</SUB></I> <TT>return</TT> <I>expression</I> <TT>;</TT></SPAN></UL>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">the type of the returned expression after lvalue-to-rvalue
conversion (4.1 [conv.lval]), array-to-pointer conversion
(4.2 [conv.array]), and function-to-pointer conversion
(4.3 [conv.func]);</SPAN></P>

</LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">otherwise, <TT>void</TT>.</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">if there are no <TT>return</TT> statements in the
<I>compound-statement</I>, or all <TT>return</TT> statements return
either an expression of type <TT>void</TT> or no <I>expression</I>
or <I>braced-init-list</I>, the type <TT>void</TT>;</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">otherwise, if all <TT>return</TT> statements return an
expression and the types of the returned expressions after
lvalue-to-rvalue conversion (4.1 [conv.lval]),
array-to-pointer conversion (4.2 [conv.array]), and
function-to-pointer conversion (4.3 [conv.func]) are
the same, that common type;</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">otherwise, the program is ill-formed.</SPAN></P></LI>

</UL>

<P>[<I>Example:</I></P>

<PRE>
  auto x1 = [](int i){ return i; }; //<SPAN style="font-family:Times;font-style:italic"> OK: return type is </SPAN>int
  auto x2 = []{ return { 1, 2 }; }; //<SPAN style="font-family:Times;font-style:italic"> error: the return type is </SPAN>void<SPAN style="font-family:Times;font-style:italic"> (a</SPAN>
                                    //<SPAN style="font-family:Times;font-style:italic"> braced-init-list is not an expression)</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  struct A { int fn1(); const int&amp; fn2(); };
  template &lt;class T&gt; void f () {
    [](T t, bool b){
      if (b)
        return t.fn1();
      else
        return t.fn2();
    };
  }
  template void f&lt;A&gt;();             //<SPAN style="font-family:Times;font-style:italic"> OK: lambda return type is </SPAN>int</SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<P><B>Additional note (February, 2012):</B></P>

<P>EWG requested that the adoption of this proposed resolution be
postponed to allow them to discuss it.  The issue has thus been
returned to "review" status pending EWG action.</P>

<BR><BR><HR><A NAME="1557"></A><H4>1557.
  
Language linkage of converted lambda function pointer
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Scott Meyers
 &#160;&#160;&#160;

 <B>Date: </B>2012-09-19<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>

<P>5.1.2 [expr.prim.lambda] paragraph 6 does not specify the language
linkage of the function type of the closure type's conversion function.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 5.1.2 [expr.prim.lambda] paragraph 6 as follows:</P>

<BLOCKQUOTE>

The closure type for a <I>lambda-expression</I> with no
<I>lambda-capture</I> has a public non-virtual non-explicit const
conversion function to pointer to function <SPAN style="font-weight:bold;background-color:#A0FFA0">with C++ language
linkage (7.5 [dcl.link]).</SPAN> having the same parameter
and return types as the closure type's function call operator.  The
value returned...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1213"></A><H4>1213.
  
Array subscripting and xvalues
</H4><B>Section: </B>5.2.1&#160; [expr.sub]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-10-24<BR>


<P>[Moved to DR status at the April, 2013 meeting.]</P>



<P>Because the subscripting operation is defined as indirection through
a pointer value, the result of a subscript operator applied to an
xvalue array is an lvalue, not an xvalue.  This could be surprising to
some.</P>

<P><B>Proposed resolution (December, 2012):</B></P>

<P>Change 5.2.1 [expr.sub] paragraph 1 as follows:</P>

<BLOCKQUOTE>

A postfix expression followed by an expression in square brackets is a
postfix expression. One of the expressions shall have the type
<SPAN style="font-weight:bold;background-color:#A0FFA0">&#8220;array of <TT>T</TT>&#8221; or</SPAN>
&#8220;pointer to T&#8221; and the other shall have unscoped
enumeration or integral type.  The result is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">an lvalue</SPAN> of type
&#8220;<TT>T</TT>.&#8221; The type &#8220;<TT>T</TT>&#8221; shall be a
completely-defined object type.<SUP>62</SUP> The expression
<TT>E1[E2]</TT> is identical (by definition) to <TT>*((E1)+(E2))</TT>
[<I>Note:</I> see 5.3 [expr.unary] and 5.7 [expr.add] for details of <TT>*</TT> and <TT>+</TT> and 8.3.4 [dcl.array] for details of arrays.  &#8212;<I>end note</I>]<SPAN style="font-weight:bold;background-color:#A0FFA0">,
except that in the case of an array operand, the result is an lvalue if
that operand is an lvalue and an xvalue otherwise.</SPAN>

</BLOCKQUOTE>

<P>(See also <A HREF="
     cwg_defects.html#616">issue 616</A>.)</P>

<P><B>Additional note (January, 2013):</B></P>

<P>The preceding resolution differs from that discussed in the
December, 2012 drafting review teleconference by the deletion of the
words &#8220;an lvalue&#8221; in the second sentence.  The issue has
consequently been moved to "review" status instead of "tentatively
ready."</P>

<BR><BR><HR><A NAME="1516"></A><H4>1516.
  
Definition of &#8220;virtual function call&#8221;
</H4><B>Section: </B>5.2.2&#160; [expr.call]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Nikolay Ivchenkov
 &#160;&#160;&#160;

 <B>Date: </B>2012-07-05<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>The terms &#8220;virtual function call&#8221; and &#8220;virtual
call&#8221; are used in the Standard but are not defined.</P>

<P><B>Proposed resolution (August, 2012):</B></P>

<P>Change 5.2.2 [expr.call] paragraph 1 as follows:</P>

<BLOCKQUOTE>

If the selected function is non-virtual, or if the
<I>id-expression</I> in the class member access expression is a
<I>qualified-id</I>, that function is called. Otherwise, its final
overrider (10.3 [class.virtual]) in the dynamic type of the
object expression is called<SPAN style="font-weight:bold;background-color:#A0FFA0">; such a call is referred to as a
<I>virtual function call</I></SPAN>.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1320"></A><H4>1320.
  
Converting scoped enumerations to <TT>bool</TT>
</H4><B>Section: </B>5.2.9&#160; [expr.static.cast]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Jonathan Wakely
 &#160;&#160;&#160;

 <B>Date: </B>2011-05-18<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>The specification of <TT>static_cast</TT> (5.2.9 [expr.static.cast])
does not describe conversion of a scoped enumeration value to
<TT>bool</TT>.  Presumably it should be handled as for unscoped
enumerations, with a zero value becoming <TT>false</TT> and a non-zero
value becoming <TT>true</TT>.
</P>

<P><B>Proposed resolution (August, 2012):</B></P>

<P>Change 5.2.9 [expr.static.cast] paragraph 9 as follows:</P>

<BLOCKQUOTE>

A value of a scoped enumeration type (7.2 [dcl.enum]) can be
explicitly converted to an integral type.  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">When
that type is <I>cv</I> <TT>bool</TT>, the resulting value is
<TT>false</TT> if the original value is zero and <TT>true</TT> for all
other values.  For the remaining integral types, the</SPAN> value is
unchanged if the original value can be represented by the specified
type.  Otherwise, the resulting value is unspecified.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1412"></A><H4>1412.
  
Problems in specifying pointer conversions
</H4><B>Section: </B>5.2.9&#160; [expr.static.cast]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Nikolay Ivchenkov
 &#160;&#160;&#160;

 <B>Date: </B>2011-11-01<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>The definedness of various pointer conversions (see
5.2.10 [expr.reinterpret.cast] paragraph 7, 9.2 [class.mem]
paragraph 20, 5.2.9 [expr.static.cast] paragraph 13) relies on
the properties of the types involved, such as whether they are
standard-layout types and their intrinsic alignment.  This
creates contradictions and unnecessary unspecified behavior when
the actual values of the pointer involved would actually permit
the operations.  Recasting the specification in terms of the
memory model instead of the types of the objects provides a more
coherent specification.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<OL><LI><P>Change 4.10 [conv.ptr] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

A prvalue of type &#8220;pointer to <I>cv</I> <TT>T</TT>,&#8221;
where <TT>T</TT> is an object type, can be converted to a prvalue
of type &#8220;pointer to <I>cv</I> <TT>void</TT>&#8221;.  The
result of converting a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">&#8220;pointer to <I>cv</I>
<TT>T</TT>&#8221;</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">non-null pointer value of a pointer
to object type</SPAN> to a &#8220;pointer to <I>cv</I> void&#8221;
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">points to the start of the storage location where the object
of type <TT>T</TT> resides, as if the object is a most derived
object (1.8 [intro.object]) of type <TT>T</TT> (that is,
not a base class subobject)</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">represents the address of
the same byte in memory as the original pointer value</SPAN>.
The null pointer value is converted to the null pointer value of
the destination type.

</BLOCKQUOTE>

<LI><P>Change 5.2.9 [expr.static.cast] paragraph 13 as follows:</P></LI>

<BLOCKQUOTE>

A prvalue of type &#8220;pointer to <I>cv1</I>
<TT>void</TT>&#8221; can be converted to a prvalue of type
&#8220;pointer to <I>cv2</I> <TT>T</TT>,&#8221; where <TT>T</TT>
is an object type and <I>cv2</I> is the same cv-qualification as,
or greater cv-qualification than, <I>cv1</I>.  The null pointer
value is converted to the null pointer value of the destination
type. <SPAN style="font-weight:bold;background-color:#A0FFA0">If the original pointer value represents the address
<TT>A</TT> of a byte in memory and <TT>A</TT> satisfies the
alignment requirement of <TT>T</TT>, then the resulting pointer
value represents the same address as the original pointer value,
that is, <TT>A</TT>.  The result of any other such pointer
conversion is unspecified.</SPAN> A value of type pointer to
object converted to &#8220;pointer to <I>cv</I>
<TT>void</TT>&#8221; and back, possibly with different
cv-qualification, shall have its original value...

</BLOCKQUOTE>

<LI><P>Change 5.2.10 [expr.reinterpret.cast] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

An object pointer can be explicitly converted to an object
pointer of a different type.<SUP>70</SUP> When a prvalue
<TT>v</TT> of <SPAN style="font-weight:bold;background-color:#A0FFA0">object pointer</SPAN> type <SPAN style="text-decoration:line-through;background-color:#FFA0A0">&#8220;pointer
to <TT>T1</TT>&#8221;</SPAN> is converted to the <SPAN style="font-weight:bold;background-color:#A0FFA0">object
pointer</SPAN> type &#8220;pointer to <I>cv</I>
<TT>T<SPAN style="text-decoration:line-through;background-color:#FFA0A0">2</SPAN></TT>&#8221;, the result is
<TT>static_cast&lt;<I>cv</I>
T<SPAN style="text-decoration:line-through;background-color:#FFA0A0">2</SPAN>*&gt;(static_cast&lt;<I>cv</I> void*&gt;(v))</TT>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">if both <TT>T1</TT> and <TT>T2</TT> are standard-layout
types (3.9 [basic.types]) and the alignment requirements
of <TT>T2</TT> are no stricter than those of <TT>T1</TT>, or if
either type is <TT>void</TT></SPAN>.  Converting a prvalue of type
&#8220;pointer to <TT>T1</TT>&#8221; to the type &#8220;pointer
to <TT>T2</TT>&#8221; (where <TT>T1</TT> and <TT>T2</TT> are
object types and where the alignment requirements of <TT>T2</TT>
are no stricter than those of <TT>T1</TT>) and back to its
original type yields the original pointer value. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The result
of any other such pointer conversion is unspecified.</SPAN>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1553"></A><H4>1553.
  
<TT>sizeof</TT> and xvalue bit-fields
</H4><B>Section: </B>5.3.3&#160; [expr.sizeof]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2012-09-13<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>According to 5.3.3 [expr.sizeof] paragraph 1,</P>

<BLOCKQUOTE>

The <TT>sizeof</TT> operator shall not be applied...  to an lvalue
that designates a bit-field.

</BLOCKQUOTE>

<P>Xvalues can also designate bit-fields and thus should presumably
be addressed here as well.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 5.3.3 [expr.sizeof] paragraph 1 as follows:</P>

<BLOCKQUOTE>

The <TT>sizeof</TT> operator yields the number of bytes in the object
representation of its operand. The operand is either an expression,
which is an unevaluated operand (Clause 5 [expr]), or a
parenthesized <I>type-id</I>.  The <TT>sizeof</TT> operator shall not
be applied to an expression that has function or incomplete type, to
an enumeration type whose underlying type is not fixed before all its
enumerators have been declared, to the parenthesized name of such
types, or to <SPAN style="text-decoration:line-through;background-color:#FFA0A0">an lvalue</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">a glvalue</SPAN> that designates
a bit-field.  <TT>sizeof(char)</TT>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1559"></A><H4>1559.
  
String too long in initializer list of <I>new-expression</I>
</H4><B>Section: </B>5.3.4&#160; [expr.new]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>2012-09-21<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>

<P>According to 5.3.4 [expr.new] paragraph 7,</P>

<BLOCKQUOTE>

if the <I>new-initializer</I> is a <I>braced-init-list</I> for which
the number of <I>initializer-clause</I>s exceeds the number of
elements to initialize, no storage is obtained and the
<I>new-expression</I> terminates by throwing an exception of a type
that would match a handler (15.3 [except.handle]) of type
<TT>std::bad_array_new_length</TT> (18.6.2.3 [new.badlength]).

</BLOCKQUOTE>

<P>This wording does not, but presumably should, require an exception
to be thrown in a case like</P>

<PRE>
  void f() {
    int x = 3;
    new char[x]{"abc"};
  }
</PRE>

<P>(See also <A HREF="
     cwg_defects.html#1464">issue 1464</A>.)</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#1464">issue 1464</A>.</P>

<BR><BR><HR><A NAME="1504"></A><H4>1504.
  
Pointer arithmetic after derived-base conversion
</H4><B>Section: </B>5.7&#160; [expr.add]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Lo&#239;c Joly
 &#160;&#160;&#160;

 <B>Date: </B>2012-05-20<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>The current wording is not sufficiently clear that a pointer to a
base class subobject of an array element cannot be used in pointer
arithmetic.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Add the following as a new paragraph before 5.7 [expr.add]
paragraph 7:</P>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">For addition or subtraction, if the expressions <TT>P</TT> or
<TT>Q</TT> have type &#8220;pointer to <I>cv</I> <TT>T</TT>", where
<TT>T</TT> is different from the cv-unqualified array element type,
the behavior is undefined. [<I>Note:</I> In particular, a pointer to a
base class cannot be used for pointer arithmetic when the array
contains objects of a derived class type. &#8212;<I>end
note</I>]</SPAN></P>

<P>If the value <TT>0</TT> is added to or subtracted...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="583"></A><H4>583.
  
Relational pointer comparisons against the null pointer constant
</H4><B>Section: </B>5.9&#160; [expr.rel]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>James Widman
 &#160;&#160;&#160;

 <B>Date: </B>24 May 2006<BR>


<P>[Moved to DR status at the April, 2013 meeting as paper N3624.]</P>



<P>In C, this is ill-formed (cf C99 6.5.8):</P>

<PRE>
    void f(char* s) {
        if (s &lt; 0) { }
    }
</PRE>

<P>...but in C++, it's not.  Why?  Who would ever need to write
<TT>(s &gt; 0)</TT>
when they could just as well write <TT>(s != 0)</TT>?</P>

<P>This has been in the language since the ARM (and possibly earlier);
apparently it's because the pointer conversions (4.10 [conv.ptr]) need to be performed on both operands whenever one of
the operands is of pointer type.  So it looks like the
"null-ptr-to-real-pointer-type" conversion is hitching a ride with the
other pointer conversions.</P>

<P><B>Proposed resolution (April, 2013):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#1512">issue 1512</A>.</P>

<BR><BR><HR><A NAME="1512"></A><H4>1512.
  
Pointer comparison vs qualification conversions
</H4><B>Section: </B>5.9&#160; [expr.rel]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Clamage
 &#160;&#160;&#160;

 <B>Date: </B>2012-06-22<BR>


<P>[Moved to DR status at the April, 2013 meeting as paper N3624.]</P>



<P>According to 5.9 [expr.rel] paragraph 2, describing
pointer comparisons,</P>

<BLOCKQUOTE>

Pointer conversions (4.10 [conv.ptr]) and qualification
conversions (4.4 [conv.qual]) are performed on pointer
operands (or on a pointer operand and a null pointer constant, or on
two null pointer constants, at least one of which is non-integral) to
bring them to their <I>composite pointer type</I>.

</BLOCKQUOTE>

<P>This would appear to make the following example ill-formed,</P>

<PRE>
  bool foo(int** x, const int** y) {
     return x &lt; y;  //<SPAN style="font-family:Times;font-style:italic"> valid ?</SPAN>
  }
</PRE>

<P>because <TT>int**</TT> cannot be converted to <TT>const int**</TT>,
according to the rules of 4.4 [conv.qual] paragraph 4.  This
seems too strict for pointer comparison, and current implementations
accept the example.</P>

<P><B>Proposed resolution (November, 2012):</B></P>

<P>The proposed wording is found in document N3478.</P>

<P>(This resolution also resolves <A HREF="
     cwg_defects.html#583">issue 583</A>.)</P>

<BR><BR><HR><A NAME="1550"></A><H4>1550.
  
Parenthesized <I>throw-expression</I> operand of <I>conditional-expression</I>
</H4><B>Section: </B>5.16&#160; [expr.cond]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Nikolay Ivchenkov
 &#160;&#160;&#160;

 <B>Date: </B>2012-09-04<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>The current wording of 5.16 [expr.cond] paragraph 2 says,</P>

<BLOCKQUOTE>

<P>If either the second or the third operand has type <TT>void</TT>,
then the lvalue-to-rvalue (4.1 [conv.lval]), array-to-pointer
(4.2 [conv.array]), and function-to-pointer (4.3 [conv.func]) standard conversions are performed on the second and
third operands, and one of the following shall hold:</P>

<UL><LI><P>The second or the third operand (but not both) is a
<I>throw-expression</I> (15.1 [except.throw]); the result is of
the type of the other and is a prvalue.</P></LI>

<LI>

<P>Both the second and the third operands have type <TT>void</TT>; the
result is of type <TT>void</TT> and is a prvalue.  [<I>Note:</I> This
includes the case where both operands are <I>throw-expression</I>s.
&#8212;<I>end note</I>]</P></LI>

</UL>

</BLOCKQUOTE>

<P>A parenthesized <I>throw-expression</I> is a
<I>primary-expression</I>, not a <I>throw-expression</I>.  Should a
parenthesized <I>throw-expression</I> be considered a
<I>throw-expression</I> for this purpose?</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 5.16 [expr.cond] paragraph 2 as follows:</P>

<BLOCKQUOTE>

<P>If either the second or the third operand has type <TT>void</TT>,
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">then the lvalue-to-rvalue (4.1 [conv.lval]), array-to-pointer
(4.2 [conv.array]), and function-to-pointer (4.3 [conv.func]) standard conversions are performed on the second and
third operands, and</SPAN> one of the following shall hold:</P>

<UL><LI><P>The second or the third operand (but not both) is a
<SPAN style="font-weight:bold;background-color:#A0FFA0">(possibly parenthesized)</SPAN> <I>throw-expression</I>
(15.1 [except.throw]); the result is of the type <SPAN style="font-weight:bold;background-color:#A0FFA0">and value
category</SPAN> of the other <SPAN style="text-decoration:line-through;background-color:#FFA0A0">and is a prvalue</SPAN>.</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<P>(This resolution also resolves <A HREF="
     cwg_defects.html#1560">issue 1560</A>.)</P>

<BR><BR><HR><A NAME="1560"></A><H4>1560.
  
Gratuitous lvalue-to-rvalue conversion in <I>conditional-expression</I> with <I>throw-expression</I> operand
</H4><B>Section: </B>5.16&#160; [expr.cond]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Nikolay Ivchenkov
 &#160;&#160;&#160;

 <B>Date: </B>2012-09-04<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>A glvalue appearing as one operand of a <I>conditional-expression</I>
in which the other operand is a <I>throw-expression</I> is converted to a
prvalue, regardless of how the <I>conditional-expression</I> is used:</P>

<BLOCKQUOTE>

<P>If either the second or the third operand has type <TT>void</TT>, then the
lvalue-to-rvalue (4.1 [conv.lval]), array-to-pointer
(4.2 [conv.array]), and function-to-pointer (4.3 [conv.func]) standard conversions are performed on the second and
third operands, and one of the following shall hold:</P>

<UL><LI><P>The second or the third operand (but not both) is a
<I>throw-expression</I> (15.1 [except.throw]); the result is of
the type of the other and is a prvalue.
</P></LI>

</UL>

</BLOCKQUOTE>

<P>This seems to be gratuitous and surprising.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#1550">issue 1550</A>.</P>

<BR><BR><HR><A NAME="1527"></A><H4>1527.
  
Assignment from <I>braced-init-list</I>
</H4><B>Section: </B>5.17&#160; [expr.ass]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>2012-07-23<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>According to 5.17 [expr.ass] paragraph 9,</P>

<BLOCKQUOTE>

<P>A <I>braced-init-list</I> may appear on the right-hand side of</P>

<UL><LI><P>an assignment to a scalar...
</P></LI>

<LI><P>an assignment defined by a user-defined assignment operator, in which
case the initializer list is passed as the argument to the operator
function.
</P></LI>

</UL>

</BLOCKQUOTE>

<P>Presumably the phrase &#8220;user-defined&#8221; is not intended to
forbid an example like</P>

<PRE>
  struct A {
    A();
    A ( std::initializer_list&lt;int&gt; ) ;
  };
  void f() {
    A a;
    a = {37};
  }
</PRE>

<P>which relies on an implicitly-declared assignment operator.</P>

<P><B>Proposed resolution (August, 2012):</B></P>

<P>Change 5.17 [expr.ass] paragraph 9 as follows:</P>

<BLOCKQUOTE>

<P>A <I>braced-init-list</I> may appear on the right-hand side of</P>

<UL><LI><P>an assignment to a scalar, in which case the initializer
list shall have at most a single element.  The meaning of
<TT>x={v}</TT>, where <TT>T</TT> is the scalar type of the expression
<TT>x</TT>, is that of <TT>x=T(v)</TT> except that no narrowing
conversion (8.5.4) is allowed. The meaning of <TT>x={}</TT> is
<TT>x=T()</TT>.
</P></LI>

<LI><P>an assignment <SPAN style="text-decoration:line-through;background-color:#FFA0A0">defined by a user-defined assignment
operator</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">to an object of class type</SPAN>, in which case
the initializer list is passed as the argument to the
<SPAN style="font-weight:bold;background-color:#A0FFA0">assignment</SPAN> operator function <SPAN style="font-weight:bold;background-color:#A0FFA0">selected by overload
resolution (13.5.3 [over.ass], 13.3 [over.match])</SPAN>.
</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1538"></A><H4>1538.
  
C-style cast in <I>braced-init-list</I> assignment
</H4><B>Section: </B>5.17&#160; [expr.ass]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2012-08-14<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>According to 5.17 [expr.ass] paragraph 9,</P>

<BLOCKQUOTE>

The meaning of <TT>x={v}</TT>, where <TT>T</TT> is the scalar type of
the expression <TT>x</TT>, is that of <TT>x=T(v)</TT> except that no
narrowing conversion (8.5.4 [dcl.init.list]) is allowed. The
meaning of <TT>x={}</TT> is <TT>x=T()</TT>.

</BLOCKQUOTE>

<P>This definition adds a gratuitous C-style cast to the right-hand
operand, inadvertently allowing such things as base-to-derived
conversions and circumvention of access checking.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 5.17 [expr.ass] paragraph 9 as follows:</P>

<BLOCKQUOTE>

The meaning of <TT>x={v}</TT>, where <TT>T</TT> is the scalar type of
the expression <TT>x</TT>, is that of <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>x=T(v)</TT> except that
no narrowing conversion (8.5.4 [dcl.init.list]) is allowed</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>x=T{v}</TT></SPAN>. The meaning of <TT>x={}</TT> is
<TT><SPAN style="text-decoration:line-through;background-color:#FFA0A0">x=T()</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>x=T{}</TT></SPAN></TT>.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1456"></A><H4>1456.
  
Address constant expression designating the one-past-the-end address
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2012-01-14<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>Currently an address constant expression cannot designate the address
one past the end of an array.  This seems unfortunate.</P>

<P><B>Proposed resolution (August, 2012):</B></P>

<P>Change 5.19 [expr.const] paragraph 3 as follows:</P>

<BLOCKQUOTE>

...An <I>address constant expression</I> is a prvalue core constant
expression of pointer type that evaluates to the address of an object
with static storage duration, <SPAN style="font-weight:bold;background-color:#A0FFA0">to the address one past the last
element of an array with static storage duration,</SPAN> to the address
of a function, or to a null pointer value, or a prvalue core constant
expression of type <TT>std::nullptr_t</TT>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1535"></A><H4>1535.
  
<TT>typeid</TT> in core constant expressions
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2012-08-10<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>One of the criteria in 5.19 [expr.const] paragraph 2 for
disqualifying an expression from being a constant expression is:</P>

<UL><LI><P>

<BLOCKQUOTE>

a typeid expression (5.2.8 [expr.typeid]) whose operand is of a
polymorphic class type;

</BLOCKQUOTE></P></LI>
</UL>

<P>on the basis that a runtime test for the dynamic type is inconsistent
with a constant expression.  However, it is only glvalues of polymorphic
type that require a runtime test; <I>type-id</I>s and prvalues with a
polymorphic type could (and should) be permitted in constant
expressions.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 5.19 [expr.const] paragraph 2 as follows:</P>

<UL><LI><P>...</P></LI>

<LI><P>a typeid expression (5.2.8 [expr.typeid]) whose operand
is <SPAN style="font-weight:bold;background-color:#A0FFA0">a glvalue</SPAN> of a polymorphic class type;</P></LI>

</UL>

<BR><BR><HR><A NAME="1537"></A><H4>1537.
  
Optional compile-time evaluation of constant expressions
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>2012-08-14<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>

<P>According to the note in 5.19 [expr.const] paragraph 4,</P>

<BLOCKQUOTE>

[<I>Note:</I> Although in some contexts constant expressions must be
evaluated during program translation, others may be evaluated during
program execution. Since this International Standard imposes no
restrictions on the accuracy of floating-point operations, it is
unspecified whether the evaluation of a floating-point expression
during translation yields the same result as the evaluation of the
same expression (or the same operations on the same values) during
program execution.

</BLOCKQUOTE>

<P>With the advent of narrowing rules, which require the compiler to
evaluate constant expressions in more contexts than was the case in
C++03 in order to determine whether an expression is well formed or
not, this wording is not sufficiently clear in stating that even in
cases where the computation must be done at compile time, the
implementation is free to use the result of a runtime calculation
rather than preserving the one computed at compile time.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 5.19 [expr.const] paragraph 4 as follows:</P>

<BLOCKQUOTE>

[<I>Note:</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">Although in some contexts constant expressions must
be evaluated during program translation, others may be evaluated
during program execution.</SPAN> Since this International Standard
imposes no restrictions on the accuracy of floating-point operations,
it is unspecified whether the evaluation of a floating-point
expression during translation yields the same result as the evaluation
of the same expression (or the same operations on the same values)
during program execution. [<I>Footnote:</I> Nonetheless,
implementations are encouraged to provide consistent results,
irrespective of whether the evaluation was <SPAN style="text-decoration:line-through;background-color:#FFA0A0">actually</SPAN>
performed during translation <SPAN style="font-weight:bold;background-color:#A0FFA0">and/</SPAN>or during program
execution. &#8212;<I>end footnote</I>] [<I>Example:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1442"></A><H4>1442.
  
Argument-dependent lookup in the range-based <TT>for</TT>
</H4><B>Section: </B>6.5.4&#160; [stmt.ranged]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>2012-01-16<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>

<P>It is not clear whether the reference to argument-dependent lookup
in 6.5.4 [stmt.ranged] paragraph 1 bullet 3 should be
&#8220;pure&#8221; argument-dependent lookup (with no unqualified
name lookup component) or the usual lookup that is invoked when
argument-dependent lookup is done, i.e., unqualified lookup, potentially
augmented by the associated namespaces.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 6.5.4 [stmt.ranged] paragraph 1 bullet 3 as follows:</P>

<UL><LI><P>otherwise, <I>begin-expr</I> and <I>end-expr</I> are
<TT>begin(__range)</TT> and <TT>end(__range)</TT>, respectively, where
<TT>begin</TT> and <TT>end</TT> are looked up <SPAN style="text-decoration:line-through;background-color:#FFA0A0">with
argument-dependent lookup</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">in the associated
namespaces</SPAN> (3.4.2 [basic.lookup.argdep]). <SPAN style="text-decoration:line-through;background-color:#FFA0A0">For the purposes
of this name lookup, namespace <TT>std</TT> is an associated
namespace.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> Ordinary unqualified lookup
(3.4.1 [basic.lookup.unqual]) is not performed. &#8212;<I>end
note</I>]</SPAN></P></LI></UL>

<BR><BR><HR><A NAME="1541"></A><H4>1541.
  
<I>cv</I> <TT>void</TT> return types
</H4><B>Section: </B>6.6.3&#160; [stmt.return]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Sean Hunt
 &#160;&#160;&#160;

 <B>Date: </B>2012-08-21<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>

<P>According to 6.6.3 [stmt.return] paragraph 3,</P>

<BLOCKQUOTE>

A return statement with neither an expression nor a
<I>braced-init-list</I> can be used only in functions that do not
return a value, that is, a function with the return type
<TT>void</TT>, a constructor (12.1 [class.ctor]), or a
destructor (12.4 [class.dtor]).

</BLOCKQUOTE>

<P>However, paragraph 3 allows a return type of <I>cv</I> <TT>void</TT>
in cases where the expression in the <TT>return</TT> statement has type
<TT>void</TT>.  Should paragraph 2 follow suit?</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 6.6.3 [stmt.return] paragraph 2 as follows:</P>

<BLOCKQUOTE>

A return statement with neither an <I>expression</I> nor a
<I>braced-init-list</I> can be used only in functions that do not
return a value, that is, a function with the return type
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>cv</I></SPAN> <TT>void</TT>, a constructor (12.1 [class.ctor]), or a destructor (12.4 [class.dtor]).  A return
statement with an expression of non-void type...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1544"></A><H4>1544.
  
Linkage of member of unnamed namespace
</H4><B>Section: </B>7.1.1&#160; [dcl.stc]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Nikolay Ivchenkov
 &#160;&#160;&#160;

 <B>Date: </B>2012-08-24<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>There is a contradiction in the specification of the linkage of
members of the unnamed namespace, for example</P>

<PRE>
  namespace {
    int x;
  }
</PRE>

<P>According to 3.5 [basic.link] paragraph 4,</P>

<BLOCKQUOTE>

<P>An unnamed namespace or a namespace declared directly or indirectly
within an unnamed namespace has internal linkage. All other namespaces
have external linkage. A name having namespace scope that has not been
given internal linkage above has the same linkage as the enclosing
namespace if it is the name of</P>

<UL><LI><P>a variable; or</P></LI>

<LI><P>...</P></LI>
</UL>

</BLOCKQUOTE>

<P>which would give <TT>x</TT> internal linkage.  However,
7.1.1 [dcl.stc] paragraph 7 says,</P>

<BLOCKQUOTE>

A name declared in a namespace scope without a
<I>storage-class-specifier</I> has external linkage unless it has
internal linkage because of a previous declaration and provided it is
not declared <TT>const</TT>.

</BLOCKQUOTE>

<P>This would give <TT>x</TT> external linkage.  (This appears to have
been a missed edit from the resolution of <A HREF="
     cwg_defects.html#1113">issue 1113</A>.)</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Delete 7.1.1 [dcl.stc] paragraph 7:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A name declared in a namespace scope without a
<I>storage-class-specifier</I> has external linkage unless it has
internal linkage because of a previous declaration and provided it is
not declared <TT>const</TT>.  Objects declared <TT>const</TT> and not
explicitly declared <TT>extern</TT> have internal linkage.</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1437"></A><H4>1437.
  
<TT>alignas</TT> in <I>alias-declaration</I>
</H4><B>Section: </B>7.1.3&#160; [dcl.typedef]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>2012-01-02<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>

<P>Consider the following:</P>

<PRE>
    struct S { int i; };
    using A alignas(alignof(long long)) = S;
</PRE>

<P>7.6.2 [dcl.align] paragraph 1 allows an <I>alignment-specifier</I>
to be applied to the declaration of a class or enumeration type, which
<TT>A</TT> arguably is.  The specification should be clarified to indicate
that such a usage is not permitted, however.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 7.6.2 [dcl.align] paragraph 1 as follows:</P>

<BLOCKQUOTE>

An <I>alignment-specifier</I> may be applied to a variable or to a
class data member, but it shall not be applied to a bit-field, a
function parameter, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the formal parameter of a catch clause</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">an <I>exception-declaration</I></SPAN> (15.3 [except.handle]), or a variable declared with the <TT>register</TT>
storage class specifier. An <I>alignment-specifier</I> may also be
applied to the declaration <SPAN style="text-decoration:line-through;background-color:#FFA0A0">of a class or enumeration type</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">or definition of a class (in an <I>elaborated-type-specifier</I>
(7.1.6.3 [dcl.type.elab]) or <I>class-head</I> (Clause
9 [class]), respectively) and to the declaration or
definition of an enumeration (in an <I>opaque-enum-declaration</I> or
<I>enum-head</I>, respectively (7.2 [dcl.enum]))</SPAN>. An
<I>alignment-specifier</I> with an ellipsis is a pack expansion
(14.5.3 [temp.variadic]).

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1358"></A><H4>1358.
  
Unintentionally ill-formed <TT>constexpr</TT> function template instances
</H4><B>Section: </B>7.1.5&#160; [dcl.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-16<BR>


<P>[Moved to DR status at the April, 2013 meeting.]</P>



<P>The permission granted implementations in 7.1.5 [dcl.constexpr]
paragraph 5 to diagnose definitions of <TT>constexpr</TT> functions
that can never be used in a constant expression should not apply to
an instantiated <TT>constexpr</TT> function template.</P>

<P><B>Notes from the August, 2011 meeting:</B></P>

<T>The CWG also decided to treat the following example
 under this issue, although it does not
involve a function template:</T>

<PRE>
    int f();   //<SPAN style="font-family:Times;font-style:italic"> not </SPAN>constexpr
    struct A {
      int m;
      constexpr A(int i = f()) : m(i) { }
    };
    struct B {
      A a;
    } b;
</PRE>

<P>This is ill-formed, no diagnostic required, because the defaulted
default constructor of <TT>B</TT> will be declared <TT>constexpr</TT>
but can never be invoked in a constant expression.  See <A HREF="
     cwg_active.html#1360">issue 1360</A>.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<OL><LI><P>Change 7.1.5 [dcl.constexpr] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

<P>... &#8212;<I>end example</I>]</P>

<P>For a <SPAN style="font-weight:bold;background-color:#A0FFA0">non-template, non-defaulted</SPAN> <TT>constexpr</TT>
function, if no function argument values exist such that the function
invocation substitution would produce a constant expression
(5.19 [expr.const]), the program is ill-formed; no diagnostic
required. For a <SPAN style="font-weight:bold;background-color:#A0FFA0">non-template, non-defaulted, non-inheriting</SPAN>
<TT>constexpr</TT> constructor, if no argument values exist such that
after function invocation substitution, every constructor call and
full-expression in the <I>mem-initializer</I>s would be a constant
expression (including conversions), the program is ill-formed; no
diagnostic required. <SPAN style="font-weight:bold;background-color:#A0FFA0">For a <TT>constexpr</TT> function template
or member function of a class template, if no instantiation would be
well-formed when considered as a non-template <TT>constexpr</TT> function,
the program is ill-formed; no diagnostic required.</SPAN>
[<I>Example:</I>...</P>

</BLOCKQUOTE>

<LI><P>Delete 7.1.5 [dcl.constexpr] paragraph 6:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">If the instantiated template specialization of a <TT>constexpr</TT>
function template or member function of a class template would fail to
satisfy the requirements for a <TT>constexpr</TT> function or
<TT>constexpr</TT> constructor, that specialization is not a
<TT>constexpr</TT> function or <TT>constexpr</TT> constructor.
[<I>Note:</I> If the function is a member function it will still be
<TT>const</TT> as described below. &#8212;<I>end note</I>] If no
specialization of the template would yield a <TT>constexpr</TT>
function or <TT>constexpr</TT> constructor, the program is ill-formed;
no diagnostic required.</SPAN>

</BLOCKQUOTE>

<P><B>Additional notes, February, 2012:</B></P>

<P>The proposed resolution inadvertently removes the provision
allowing specializations of <TT>constexpr</TT> templates to violate
the requirements of 7.1.5 [dcl.constexpr].  It is being retained
in "drafting" status pending additional work.  
</P>

</OL>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 7.1.5 [dcl.constexpr] paragraphs 5-6 as follows:</P>

<BLOCKQUOTE>

<P>...For a <SPAN style="font-weight:bold;background-color:#A0FFA0">non-template, non-defaulted</SPAN> <TT>constexpr</TT>
function, if no function argument values exist such that the function
invocation substitution would produce a constant expression
(5.19 [expr.const]), the program is ill-formed; no diagnostic
required. For a <SPAN style="font-weight:bold;background-color:#A0FFA0">non-template, non-defaulted, non-inheriting</SPAN>
<TT>constexpr</TT> constructor, if no argument values exist such that
after function invocation substitution, every constructor call and
full-expression in the <I>mem-initializer</I>s would be a constant
expression (including conversions), the program is ill-formed; no
diagnostic required. [<I>Example:</I> ... &#8212;<I>end
example</I>]</P>

<P>If the instantiated template specialization of a <TT>constexpr</TT>
function template or member function of a class template would fail to
satisfy the requirements for a <TT>constexpr</TT> function or
<TT>constexpr</TT> constructor, that specialization is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">not</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">still</SPAN> a <TT>constexpr</TT> function or <TT>constexpr</TT>
constructor<SPAN style="font-weight:bold;background-color:#A0FFA0">, even though a call to such a function cannot appear
in a constant expression</SPAN>.  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">[<I>Note:</I> If the function is
a member function it will still be <TT>const</TT> as described below.
&#8212;<I>end note</I>]</SPAN> If no specialization of the template
would <SPAN style="text-decoration:line-through;background-color:#FFA0A0">yield</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">satisfy the requirements for</SPAN> a
<TT>constexpr</TT> function or <TT>constexpr</TT> constructor
<SPAN style="font-weight:bold;background-color:#A0FFA0">when considered as a non-template function or constructor</SPAN>,
the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">program</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">template</SPAN> is ill-formed; no
diagnostic required.
</P>

</BLOCKQUOTE>

<P><B>Additional note (January, 2013):</B></P>

<P>Questions arose in the discussion of <A HREF="
     cwg_active.html#1581">issue 1581</A>
as to whether this approach &#8212; making the specialization of a
<TT>constexpr</TT> function template or member function of a class template
still <TT>constexpr</TT> but unable to be invoked in a constant context
&#8212; is correct.  The implication is that class types might be
categorized as literal but not be able to be instantiated at compile time.
This issue is therefore returned to "review" status to allow further
consideration of this question.
</P>

<BR><BR><HR><A NAME="1588"></A><H4>1588.
  
Deducing cv-qualified <TT>auto</TT>
</H4><B>Section: </B>7.1.6.4&#160; [dcl.spec.auto]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Jens Maurer
 &#160;&#160;&#160;

 <B>Date: </B>2012-11-18<BR>




<P>In an example like</P>

<PRE>
  const auto x = 3;
</PRE>

<P>the intent, clearly, is to make <TT>const int</TT> the type of
<TT>x</TT>.  It is not clear, however, that the current wording
accomplishes this.  Because the deduction is based on that of
function calls, and because top-level cv-qualifiers are ignored
in such deduction, it appears that 7.1.6.4 [dcl.spec.auto]
paragraph 6,</P>

<BLOCKQUOTE>

The type deduced for the variable <TT>d</TT> is then the deduced
<TT>A</TT> determined using the rules of template argument deduction
from a function call (14.8.2.1 [temp.deduct.call]), where <TT>P</TT>
is a function template parameter type and the initializer for
<TT>d</TT> is the corresponding argument.

</BLOCKQUOTE>

<P>incorrectly gives <TT>x</TT> the type <TT>int</TT>.</P>

<P><B>Proposed resolution (April, 2013):</B></P>

<P>This issue is resolved by the wording changes in N3638, adopted
at the April, 2013 (Bristol) meeting.</P>

<BR><BR><HR><A NAME="977"></A><H4>977.
  
When is an enumeration type complete?
</H4><B>Section: </B>7.2&#160; [dcl.enum]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>3 October, 2009<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>There is disagreement among implementations as to when an enumeration
type is complete.  For example,</P>

<PRE>
    enum E { e = E() };
</PRE>

<P>is rejected by some and accepted by another.  The Standard does
not appear to resolve this question definitively.</P>

<P>See also <A HREF="
     cwg_defects.html#1482">issue 1482</A>.</P>

<P><B>Proposed resolution (December, 2012):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#1482">issue 1482</A>.</P>

<BR><BR><HR><A NAME="1477"></A><H4>1477.
  
Definition of a <TT>friend</TT> outside its namespace
</H4><B>Section: </B>7.3.1.2&#160; [namespace.memdef]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>2012-03-09<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>

<P>According to 7.3.1.2 [namespace.memdef] paragraph 3,</P>

<BLOCKQUOTE>

Every name first declared in a namespace is a member of that
namespace. If a <TT>friend</TT> declaration in a non-local class first
declares a class or function<SUP>95</SUP> the friend class or function
is a member of the innermost enclosing namespace. The name of the
friend is not found by unqualified lookup (3.4.1 [basic.lookup.unqual])
or by qualified lookup (3.4.3 [basic.lookup.qual]) until a matching
declaration is provided in that namespace scope (either before or
after the class definition granting friendship).

</BLOCKQUOTE>

<P>Taken literally, that would mean the following example is
ill-formed:</P>

<PRE>
  namespace N {
    struct A {
      friend int f();
    };
  }
  int N::f() { return 0; }
  int i = N::f();    //<SPAN style="font-family:Times;font-style:italic"> ill-formed: </SPAN>N::f<SPAN style="font-family:Times;font-style:italic"> not found</SPAN>
</PRE>

<P>because the definition of <TT>N::f</TT> appears in global scope
rather than in namespace scope.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 7.3.1.2 [namespace.memdef] paragraph 3 as follows:</P>

<BLOCKQUOTE>

Every name first declared in a namespace is a member of that
namespace. If a <TT>friend</TT> declaration in a non-local class first
declares a class or function<SUP>95</SUP> the friend class or function
is a member of the innermost enclosing namespace. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The name of the
friend is not found by</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">The <TT>friend</TT> declaration does
not by itself make the name visible to</SPAN> unqualified lookup
(3.4.1 [basic.lookup.unqual]) or <SPAN style="text-decoration:line-through;background-color:#FFA0A0">by</SPAN> qualified lookup
(3.4.3 [basic.lookup.qual])<SPAN style="font-weight:bold;background-color:#A0FFA0">. [<I>Note:</I> The name of the
friend will be visible in its namespace if</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">until</SPAN> a
matching declaration is provided <SPAN style="text-decoration:line-through;background-color:#FFA0A0">in that</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">at</SPAN>
namespace scope (either before or after the class definition granting
friendship). <SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end note</I>]</SPAN> If a friend function
is called...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1475"></A><H4>1475.
  
Errors in <TT>[[carries_dependency]]</TT> example
</H4><B>Section: </B>7.6.4&#160; [dcl.attr.depend]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Stephan Lavavej
 &#160;&#160;&#160;

 <B>Date: </B>2012-03-06<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>The example in 7.6.4 [dcl.attr.depend] paragraph 4 reads,</P>

<PRE>
  /*<SPAN style="font-family:Times;font-style:italic"> Translation unit A. </SPAN>*/

  struct foo { int* a; int* b; };
  std::atomic&lt;struct foo *&gt; foo_head[10];
  int foo_array[10][10];

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

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

  /*<SPAN style="font-family:Times;font-style:italic"> Translation unit B. </SPAN>*/

  [[carries_dependency]] struct foo* f(int i);
  [[carries_dependency]] int* g(int* x, int* y);

  int c = 3;

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

    p = f(i);
    do_something_with(g(&amp;c, p-&gt;a));
    do_something_with(g(p-&gt;a, &amp;c));
  }
</PRE>

<P>There appear to be two errors in this example.  First, <TT>g</TT>
is declared as returning <TT>int</TT> in TU A but <TT>int*</TT> in
TU B.  Second, paragraph 6 says,</P>

<BLOCKQUOTE>

Function <TT>g</TT>'s second argument has a
<TT>carries_dependency</TT> attribute

</BLOCKQUOTE>

<P>but that is not reflected in the example.</P>

<P><B>Proposed resolution (August, 2012):</B></P>

<OL><LI><P>Change the example in 7.6.4 [dcl.attr.depend] paragraph
4 as follows:</P></LI>

<PRE>
  /*<SPAN style="font-family:Times;font-style:italic"> Translation unit A. </SPAN>*/

  struct foo { int* a; int* b; };
  std::atomic&lt;struct foo *&gt; foo_head[10];
  int foo_array[10][10];

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

  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">[[carries_dependency]]</SPAN> int g(int* x, int* y <SPAN style="font-weight:bold;background-color:#A0FFA0">[[carries_dependency]]</SPAN>) {
    return kill_dependency(foo_array[*x][*y]);
  }

  /*<SPAN style="font-family:Times;font-style:italic"> Translation unit B. </SPAN>*/

  [[carries_dependency]] struct foo* f(int i);
  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">[[carries_dependency]] int*</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">int</SPAN> g(int* x, int* y <SPAN style="font-weight:bold;background-color:#A0FFA0">[[carries_dependency]]</SPAN>);

  int c = 3;

  void h(int i) {
    struct foo* p;
    p = f(i);
    do_something_with(g(&amp;c, p-&gt;a));
    do_something_with(g(p-&gt;a, &amp;c));
  }
</PRE>

<LI><P>Change 7.6.4 [dcl.attr.depend] paragraph 6 as follows:</P></LI>

<BLOCKQUOTE>

Function <TT>g</TT>'s second <SPAN style="text-decoration:line-through;background-color:#FFA0A0">argument</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">parameter</SPAN>
has a <TT>carries_dependency</TT> attribute, but its first
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">argument</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">parameter</SPAN> does not. Therefore, function
<TT>h</TT>'s first call to <TT>g</TT> carries a dependency into
<TT>g</TT>, but its second call does not. The implementation might
need to insert a fence prior to the second call to <TT>g</TT>.

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1528"></A><H4>1528.
  
Repeated <I>cv-qualifier</I>s in declarators
</H4><B>Section: </B>8&#160; [dcl.decl]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2012-07-23<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>There is no restriction against repeated <I>cv-qualifier</I>s in
declarators, although there is (in 7.1.6 [dcl.type] paragraph
2) for those appearing in a <I>decl-specifier-seq</I>.  However, most
or all current implementations reject such code.  Is a change needed?</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 7.1.6.1 [dcl.type.cv] paragraph 1 as follows:</P>

<BLOCKQUOTE>

There are two <I>cv-qualifier</I>s, <TT>const</TT> and
<TT>volatile</TT>. <SPAN style="font-weight:bold;background-color:#A0FFA0">Each <I>cv-qualifier</I> shall appear at most
once in a <I>cv-qualifier-seq</I>.</SPAN> If a <I>cv-qualifier</I>
appears in a <I>decl-specifier-seq</I>, the
<I>init-declarator-list</I> of the declaration shall not be
empty. [<I>Note:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1435"></A><H4>1435.
  
<I>template-id</I> as the declarator for a class template constructor
</H4><B>Section: </B>8.3&#160; [dcl.meaning]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Johannes Schaub
 &#160;&#160;&#160;

 <B>Date: </B>2011-12-24<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>The status of a declaration like the following is unclear:</P>

<PRE>
  template&lt;typename T&gt; struct A {
    A&lt;T&gt;();
  };
</PRE>

<P>8.3 [dcl.meaning] paragraph 1 appears to say that it is
not allowed, but it is not clear.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<OL><LI><P>Change 8.3 [dcl.meaning] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

A list of declarators appears after an optional (Clause 7 [dcl.dcl])
<I>decl-specifier-seq</I> (7.1 [dcl.spec]).  Each declarator
contains exactly one <I>declarator-id</I>; it names the identifier
that is declared. An <I>unqualified-id</I> occurring in a
<I>declarator-id</I> shall be a simple <I>identifier</I> except for
the declaration of some special functions (<SPAN style="font-weight:bold;background-color:#A0FFA0">12.1 [class.ctor],</SPAN> 12.3 [class.conv], 12.4 [class.dtor], 13.5 [over.oper]) and for the declaration of
template specializations or partial specializations (14.7 [temp.spec]).  A <I>declarator-id</I> shall not...

</BLOCKQUOTE>

<LI><P>Change 12.1 [class.ctor] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<P>Constructors do not have names.  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">A special declarator syntax is
used to declare or define the constructor.  The syntax uses:</SPAN></P>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">an optional <I>decl-specifier-seq</I> in which each
<I>decl-specifier</I> is either a <I>function-specifier</I> or
<TT>constexpr</TT>,</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">the constructor's class name, and</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">a parameter list</SPAN></P></LI>

</UL>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">in that order. In such a declaration, optional parentheses
around the constructor class name are ignored.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">A
declaration of a constructor uses a function declarator (8.3.5 [dcl.fct]) of the form</SPAN></P>

<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><I>ptr-declarator</I> <TT>(</TT> <I>parameter-declaration-clause</I> <TT>)</TT> <I>exception-specification<SUB>opt</SUB> attribute-specifier-seq<SUB>opt</SUB></I></SPAN></UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">where the <I>ptr-declarator</I> consists solely of an
<I>id-expression</I>, an optional <I>attribute-specifier-seq</I>, and
optional surrounding parentheses, and the <I>id-expression</I> has
one of the following forms:</SPAN></P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">in a <I>member-declaration</I> that belongs to the
<I>member-specification</I> of a class but is not a friend declaration
(11.3 [class.friend]), the <I>id-expression</I> is the
injected-class-name (Clause 9 [class]) of the
immediately-enclosing class;</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">in a <I>member-declaration</I> that belongs to the
<I>member-specification</I> of a class template but is not a friend
declaration, the <I>id-expression</I> is a <I>class-name</I> that
names the current instantiation (14.6.2.1 [temp.dep.type]) of the
immediately-enclosing class template; or</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">in a declaration at namespace scope or in a friend declaration, the
<I>id-expression</I> is a <I>qualified-id</I> that names a constructor
(3.4.3.1 [class.qual]).</SPAN></P></LI>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">The <I>class-name</I> shall not be a
<I>typedef-name</I>.  In a constructor declaration, each
<I>decl-specifier</I> in the optional <I>decl-specifier-seq</I> shall
be <TT>friend</TT>, <TT>inline</TT>, <TT>explicit</TT>, or
<TT>constexpr</TT>.</SPAN> [<I>Example:</I>...</P>

</BLOCKQUOTE>

<LI><P>Delete 12.1 [class.ctor] paragraph 3:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A <I>typedef-name</I> shall not be used as the <I>class-name</I> in
the <I>declarator-id</I> for a constructor declaration.</SPAN>

</BLOCKQUOTE>

<LI><P>Change 12.1 [class.ctor] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A constructor shall not be <TT>virtual</TT> (10.3 [class.virtual]) or <TT>static</TT> (9.4 [class.static]).</SPAN> A
constructor can be invoked for a <TT>const</TT>, <TT>volatile</TT> or
<TT>const volatile</TT> object.  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">A constructor shall not be
declared <TT>const</TT>, <TT>volatile</TT>, or <TT>const volatile</TT>
(9.3.2 [class.this]).</SPAN> <TT>const</TT> and
<TT>volatile</TT> semantics (7.1.6.1 [dcl.type.cv]) are not
applied on an object under construction.  They come into effect when
the constructor for the most derived object (1.8 [intro.object])
ends. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">A constructor shall not be declared with a
<I>ref-qualifier</I>.</SPAN>

</BLOCKQUOTE>

<LI><P>Change 12.1 [class.ctor] paragraph 9 as follows:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">No return type (not even <TT>void</TT>) shall be specified for a
constructor.</SPAN> A <TT>return</TT> statement in the body of a
constructor shall not specify a return value. The address of a
constructor shall not be taken.

</BLOCKQUOTE>

<LI><P>Change 12.4 [class.dtor] paragraphs 1-2 as follows:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">A special declarator syntax using an optional
<I>function-specifier</I> (7.1.2 [dcl.fct.spec]) followed by
<TT>~</TT> followed by the destructor's class name followed by an
empty parameter list is used to declare the destructor in a class
definition.  In such a declaration, the <TT>~</TT> followed by the
destructor's class name can be enclosed in optional parentheses; such
parentheses are ignored.  A <I>typedef-name</I> shall not be used as
the class-name following the <TT>~</TT> in the declarator for a
destructor declaration.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">A declaration of a destructor uses a
function declarator (8.3.5 [dcl.fct]) of the form</SPAN></P>

<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><I>ptr-declarator</I> <TT>(</TT> <I>parameter-declaration-clause</I> <TT>)</TT> <I>exception-specification<SUB>opt</SUB> attribute-specifier-seq<SUB>opt</SUB></I></SPAN></UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">where the <I>ptr-declarator</I> consists solely of an
<I>id-expression</I>, an optional <I>attribute-specifier-seq</I>,
and optional surrounding parentheses, and the <I>id-expression</I> has
one of the following forms:</SPAN></P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">in a <I>member-declaration</I> that belongs to the
<I>member-specification</I> of a class but is not a friend declaration
(11.3 [class.friend]), the <I>id-expression</I> is
<TT>~</TT><I>class-name</I> and the <I>class-name</I> is the
injected-class-name (Clause 9 [class]) of the
immediately-enclosing class;</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">in a <I>member-declaration</I> that belongs to the
<I>member-specification</I> of a class template but is not a friend
declaration, the <I>id-expression</I> is <TT>~</TT><I>class-name</I> and the
<I>class-name</I> names the current instantiation (14.6.2.1 [temp.dep.type]) of the immediately-enclosing class template;
or</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">in a declaration at namespace scope or in a friend declaration, the
<I>id-expression</I> is <I>nested-name-specifier</I>
<TT>~</TT><I>class-name</I> and the <I>class-name</I> names the same
class as the <I>nested-name-specifier</I>.</SPAN></P></LI>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0"> The <I>class-name</I> shall not be a <I>typedef-name</I>.  A
destructor shall take no arguments (8.3.5 [dcl.fct]).  In a
destructor declaration, each <I>decl-specifier</I> of the optional
<I>decl-specifier-seq</I> shall be <TT>friend</TT>, <TT>inline</TT>,
or <TT>virtual</TT>.</SPAN></P>

<P>A destructor is used to destroy objects of its class type. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">A
destructor takes no parameters, and no return type can be specified
for it (not even <TT>void</TT>).</SPAN> The address of a destructor
shall not be taken.  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">A destructor shall not be
<TT>static</TT>.</SPAN> A destructor can be invoked for a
<TT>const</TT>, <TT>volatile</TT> or <TT>const volatile</TT>
object. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">A destructor shall not be declared <TT>const</TT>,
<TT>volatile</TT> or <TT>const volatile</TT> (9.3.2 [class.this]).</SPAN> <TT>const</TT> and <TT>volatile</TT> semantics
(<secton_ref ref="7.1.6.1">7.1.6.1 [dcl.type.cv]</secton_ref>) are not applied on an object under
destruction. They stop being in effect when the destructor for the
most derived object (1.8 [intro.object]) starts. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">A
destructor shall not be declared with a
<I>ref-qualifier</I>.</SPAN></P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1510"></A><H4>1510.
  
cv-qualified references via <TT>decltype</TT>
</H4><B>Section: </B>8.3.2&#160; [dcl.ref]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2012-06-14<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>According to 8.3.2 [dcl.ref] paragraph 1,</P>

<BLOCKQUOTE>

Cv-qualified references are ill-formed except when the cv-qualifiers
are introduced through the use of a typedef (7.1.3 [dcl.typedef]) or of a template type argument (14.3 [temp.arg]), in which case the cv-qualifiers are ignored.

</BLOCKQUOTE>

<P>There does not appear to be a good reason not to extend this to
apply to apply to <TT>decltype</TT>, as well.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 8.3.2 [dcl.ref] paragraph 1 as follows:</P>

<BLOCKQUOTE>

...Cv-qualified references are ill-formed except when the
cv-qualifiers are introduced through the use of a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">typedef</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>typedef-name</I></SPAN> (7.1.3 [dcl.typedef]<SPAN style="font-weight:bold;background-color:#A0FFA0">,
14.1 [temp.param]</SPAN>) or <SPAN style="text-decoration:line-through;background-color:#FFA0A0">of a template type argument
(14.3 [temp.arg])</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>decltype-specifier</I>
(7.1.6.2 [dcl.type.simple])</SPAN>, in which case the cv-qualifiers
are ignored. [<I>Example:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1502"></A><H4>1502.
  
Value initialization of unions with member initializers
</H4><B>Section: </B>8.5&#160; [dcl.init]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2012-05-06<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>According to 8.5 [dcl.init] paragraph 7,</P>

<BLOCKQUOTE>

<P>To <I>value-initialize</I> an object of type <TT>T</TT> means:</P>

<UL><LI><P>if <TT>T</TT> is a (possibly cv-qualified) class type (Clause
9 [class]) with either no default constructor
(12.1 [class.ctor]) or a default constructor that is
user-provided or deleted, then the object is default-initialized;
</P></LI>

<LI><P>if <TT>T</TT> is a (possibly cv-qualified) non-union class type without a
user-provided or deleted default constructor, then the object is
zero-initialized and, if <TT>T</TT> has a non-trivial default constructor,
default-initialized;
</P></LI>

<LI><P>if <TT>T</TT> is an array type, then each element is value-initialized;
</P></LI>

<LI><P>otherwise, the object is zero-initialized.
</P></LI>

</UL>

</BLOCKQUOTE>

<P>In an example like</P>

<PRE>
  union U { int a = 5; };
  int main() { return U().a; }
</PRE>

<P>this means that the value returned is <TT>0</TT>, because none of the
first three bullets apply.  Should the &#8220;non-union&#8221;
restriction be dropped from the second bullet?</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 8.5 [dcl.init] paragraph 7 as follows:</P>

<BLOCKQUOTE>

<P>To <I>value-initialize</I> an object of type <TT>T</TT> means:</P>

<UL><LI><P>...</P></LI>

<LI><P>if <TT>T</TT> is a (possibly cv-qualified) <SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-union</SPAN>
class type without a user-provided or deleted default constructor,
then the object is zero-initialized and, if <TT>T</TT> has a
non-trivial default constructor, default-initialized;</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1507"></A><H4>1507.
  
Value initialization with trivial inaccessible default constructor
</H4><B>Section: </B>8.5&#160; [dcl.init]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Johannes Schaub
 &#160;&#160;&#160;

 <B>Date: </B>2012-06-01<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>According to 8.5 [dcl.init] paragraph 7, a trivial default
constructor is not used in value initialization, so the following
example would appear to be well-formed:</P>

<PRE>
  struct A { private: A() = default; };
  int main() { A(); }
</PRE>

<P><B>Proposed resolution (February, 2013):</B></P>

<OL><LI><P>Change 8.5 [dcl.init] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

<P>To <I>default-initialize</I> an object of type <TT>T</TT> means:</P>

<UL><LI><P>if <TT>T</TT> is a (possibly cv-qualified) class type (Clause
9 [class]), the default
constructor <SPAN style="font-weight:bold;background-color:#A0FFA0">(12.1 [class.ctor])</SPAN> for <TT>T</TT> is called
(and the initialization is ill-formed if <TT>T</TT> has no <SPAN style="text-decoration:line-through;background-color:#FFA0A0">accessible
default constructor</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">default constructor or overload
resolution (13.3 [over.match]) results in an ambiguity or
in a function that is deleted or inaccessible from the context of the
initialization</SPAN>);</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 8.5 [dcl.init] paragraph 8 as follows:</P></LI>

<BLOCKQUOTE>

<P>To <I>value-initialize</I> an object of type <TT>T</TT> means:</P>

<UL><LI><P>...</P></LI>

<LI><P>if <TT>T</TT> is a (possibly cv-qualified) non-union class type
without a user-provided or deleted default constructor, then the object is
zero-initialized and <SPAN style="font-weight:bold;background-color:#A0FFA0">the semantic constraints for
default-initialization are checked</SPAN>, <SPAN style="font-weight:bold;background-color:#A0FFA0">and</SPAN> if <TT>T</TT> has
a non-trivial default constructor, <SPAN style="font-weight:bold;background-color:#A0FFA0">the object is</SPAN>
default-initialized;</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1328"></A><H4>1328.
  
Conflict in reference binding vs overload resolution
</H4><B>Section: </B>8.5.3&#160; [dcl.init.ref]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Johannes Schaub
 &#160;&#160;&#160;

 <B>Date: </B>2011-05-31<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>According to 13.3.1.6 [over.match.ref] paragraph 1, the
determination of the candidate functions is based on whether
8.5.3 [dcl.init.ref] requires an lvalue result or an rvalue
result.  It is not sufficiently clear exactly what this means,
particularly with respect to function lvalues and rvalues.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<OL><LI><P>Change 13.3.1.6 [over.match.ref] paragraph 1 as follows:</P></LI>

<UL><LI><P>The conversion functions of <TT>S</TT> and its base classes
are considered, except that for copy-initialization, only the
non-explicit conversion functions are considered. Those that are not
hidden within <TT>S</TT> and yield type &#8220;lvalue reference to
<I>cv2</I> <TT>T2</TT>&#8221; (when <SPAN style="text-decoration:line-through;background-color:#FFA0A0">8.5.3 [dcl.init.ref]
requires an lvalue result</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">initializing an lvalue reference
or an rvalue reference to function</SPAN>) or &#8220;<I>cv2</I>
<TT>T2</TT>&#8221; or &#8220;rvalue reference to <I>cv2</I>
<TT>T2</TT>&#8221; (when <SPAN style="text-decoration:line-through;background-color:#FFA0A0">8.5.3 [dcl.init.ref] requires an
rvalue result</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">initializing an rvalue reference or an lvalue
reference to function</SPAN>), where &#8220;<I>cv1</I>
<TT>T</TT>&#8221; is reference-compatible (8.5.3 [dcl.init.ref])
with &#8220;<I>cv2</I> <TT>T2</TT>&#8221;, are candidate
functions.</P></LI></UL>

<LI><P>Change 13.3.3 [over.match.best] paragraph 1 as follows:</P></LI>

<UL><LI><P>...</P></LI>

<LI><P>the context is an initialization by user-defined conversion... or
if not that,</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">the context is an initialization by conversion function
for direct reference binding (13.3.1.6 [over.match.ref]) of a
reference to function type, the return type of <TT>F1</TT> is the same
kind of reference (i.e. lvalue or rvalue) as the reference being
initialized, and the return type of <TT>F2</TT> is not
[<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  template &lt;class T&gt; struct A {
    operator T&amp;();  //<SPAN style="font-family:Times;font-style:italic"> #1</SPAN>
    operator T&amp;&amp;(); //<SPAN style="font-family:Times;font-style:italic"> #2</SPAN>
  };
  typedef int Fn();
  A&lt;Fn&gt; a;
  Fn&amp; lf = a;      //<SPAN style="font-family:Times;font-style:italic"> calls #1</SPAN>
  Fn&amp;&amp; rf = a;     //<SPAN style="font-family:Times;font-style:italic"> calls #2</SPAN></SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>] or, if not that,</SPAN></P>

</LI>

<LI><P><TT>F1</TT> is a non-template function...</P></LI>

</UL>

</OL>

<BR><BR><HR><A NAME="1494"></A><H4>1494.
  
Temporary initialization for reference binding in list-initialization
</H4><B>Section: </B>8.5.4&#160; [dcl.init.list]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>2012-04-12<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>

<P>One of the bullets in 8.5.4 [dcl.init.list] paragraph 3 reads,</P>

<BLOCKQUOTE>

Otherwise, if T is a reference type, a prvalue temporary of the type
referenced by T is list-initialized, and the reference is bound to
that temporary.

</BLOCKQUOTE>

<P>This does not say whether the initialization of the temporary is
direct-list-initialization, copy-list-initialization, or the same
kind of list-initialization as the top-level initialization.</P>

<P><B>Proposed resolution (December, 2012):</B></P>

<P>Change 8.5.4 [dcl.init.list] paragraph 3 as follows:</P>

<UL><LI><P>...</P></LI>

<LI><P>Otherwise, if <TT>T</TT> is a reference type, a prvalue
temporary of the type referenced by <TT>T</TT> is
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">list-initialized</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">copy-list-initialized or
direct-list-initialized, depending on the kind of initialization for
the reference</SPAN>, and the reference is bound to that
temporary. [<I>Note:</I> As usual...</P></LI>

<LI><P>...</P></LI>

</UL>

<BR><BR><HR><A NAME="1506"></A><H4>1506.
  
Value category of <TT>initializer_list</TT> object
</H4><B>Section: </B>8.5.4&#160; [dcl.init.list]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>2012-05-29<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>

<P>One of the bullets in 8.5.4 [dcl.init.list] paragraph 3
says,</P>

<BLOCKQUOTE>

Otherwise, if <TT>T</TT> is a specialization of
<TT>std::initializer_list&lt;E&gt;,</TT> an <TT>initializer_list</TT>
object is constructed as described below and used to initialize the
object according to the rules for initialization of an object from a
class of the same type (8.5 [dcl.init]).

</BLOCKQUOTE>

<P>This does not, but should, say whether the <TT>initializer_list</TT>
object is treated as an lvalue or prvalue for the purpose of the
8.5 [dcl.init] initialization.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 8.5.4 [dcl.init.list] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<P>List-initialization of an object or reference of type <TT>T</TT> is
defined as follows:</P>

<UL><LI><P>...</P></LI>

<LI><P>Otherwise, if <TT>T</TT> is a specialization of
<TT>std::initializer_list&lt;E&gt;</TT>, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">an</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">a
prvalue</SPAN> <TT>initializer_list</TT> object is constructed as
described below and used to initialize the object according to the
rules for initialization of an object from a class of the same type
(8.5 [dcl.init]).</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1522"></A><H4>1522.
  
Access checking for <TT>initializer_list</TT> array initialization
</H4><B>Section: </B>8.5.4&#160; [dcl.init.list]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>2012-07-12<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>

<P>In constructing an <TT>initializer_list</TT> object from an initializer
list, 8.5.4 [dcl.init.list] paragraph 5 says of the underlying array,</P>

<BLOCKQUOTE>

Each element of that array is copy-initialized with the corresponding
element of the initializer list

</BLOCKQUOTE>

<P>It would probably be good to mention that the copy/move constructor
for this copy must be accessible in the context in which the initialization
occurs.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 8.5.4 [dcl.init.list] paragraph 4 as follows:</P>

<BLOCKQUOTE>

...Each element of that array is copy-initialized with the
corresponding element of the initializer list, and the
<TT>std::initializer_list&lt;E&gt;</TT> object is constructed to refer
to that array. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> A constructor or conversion function
selected for the copy shall be accessible (Clause 11 [class.access]) in the context of the initializer list. &#8212;<I>end
note</I>]</SPAN> If a narrowing conversion is required...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1318"></A><H4>1318.
  
Syntactic ambiguities with <TT>final</TT>
</H4><B>Section: </B>9&#160; [class]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Johannes Schaub
 &#160;&#160;&#160;

 <B>Date: </B>2011-05-14<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>The ambiguity in an example like</P>

<PRE>
  struct A final { };
</PRE>

<P>is resolved by 2.11 [lex.name] paragraph 2 to be the
declaration of a variable named <TT>final</TT>:</P>

<BLOCKQUOTE>

any ambiguity as to whether a given <I>identifier</I> has a special
meaning is resolved to interpret the token as a regular
<I>identifier</I>.

</BLOCKQUOTE>

<P>Similarly, in an example like</P>

<PRE>
  struct C { constexpr operator int() { return 5; } };
  struct A {
   struct B final : C{};
  };
</PRE>

<P><TT>final</TT> is taken as the name of a bit-field member rather than
as the name of a nested class.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<OL><LI><P>Change 2.11 [lex.name] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

The identifiers in Table 3 have a special meaning when appearing in a
certain context.  When referred to in the grammar, these identifiers
are used explicitly rather than using the <I>identifier</I> grammar
production. <SPAN style="font-weight:bold;background-color:#A0FFA0">Unless otherwise specified,</SPAN> any ambiguity as to
whether a given identifier has a special meaning is resolved to
interpret the token as a regular
<I>identifier</I>.

</BLOCKQUOTE>

<LI><P>Change 9 [class] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

<P>If a class is marked with the <I>class-virt-specifier</I>
<TT>final</TT> and it appears as a <I>base-type-specifier</I> in a
<I>base-clause</I> (Clause 10 [class.derived]), the program is
ill-formed. <SPAN style="font-weight:bold;background-color:#A0FFA0">Whenever a <I>class-key</I> is followed by a
<I>class-head-name</I>, the <I>identifier</I> <TT>final</TT>, and a
colon or left brace, <TT>final</TT> is interpreted as a
<I>class-virt-specifier</I>. [<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  struct A;
  struct A final {};      //<SPAN style="font-family:Times;font-style:italic"> OK: definition of </SPAN>struct A<SPAN style="font-family:Times;font-style:italic">,</SPAN>
                          //<SPAN style="font-family:Times;font-style:italic"> not value-initialization of variable </SPAN>final

  struct X {
   struct C { constexpr operator int() { return 5; } };
   struct B final : C{};  //<SPAN style="font-family:Times;font-style:italic"> OK: definition of nested class </SPAN>B<SPAN style="font-family:Times;font-style:italic">,</SPAN>
                          //<SPAN style="font-family:Times;font-style:italic"> not declaration of a bit-field member </SPAN>final
  };</SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1411"></A><H4>1411.
  
More on global scope <TT>::</TT> in <I>nested-name-specifier</I>
</H4><B>Section: </B>9&#160; [class]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>David Blaikie
 &#160;&#160;&#160;

 <B>Date: </B>2011-10-28<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>The resolution of <A HREF="
     cwg_defects.html#355">issue 355</A> failed to
update the grammar for <I>class-head-name</I> in 9 [class]
paragraph 1 and removed the optional <TT>::</TT> from
<I>class-or-decltype</I> in 10 [class.derived]
paragraph 1, with the result that it is still not possible to
globally-qualify a class name in a class definition, and the ability to
globally-qualify a base class name has been lost.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change the grammar in 5.1.1 [expr.prim.general] paragraph 8 as follows:</P>

<UL><I>qualified-id:</I>
<UL><I>nested-name-specifier</I> <TT>template</TT><I><SUB>opt</SUB> unqualified-id</I><BR>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>::</TT> <I>identifier</I><BR>
<TT>::</TT> <I>operator-function-id</I><BR>
<TT>::</TT> <I>literal-operator-id</I><BR>
<TT>::</TT> <I>template-id</I></SPAN>

</UL>

<I>nested-name-specifier:</I>
<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>::</TT></SPAN><BR>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>::</TT><I><SUB>opt</SUB></I></SPAN> <I>type-name</I> <TT>::</TT><BR>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>::</TT><I><SUB>opt</SUB></I></SPAN> <I>namespace-name</I> <TT>::</TT><BR>
<I>decltype-specifier</I> <TT>::</TT><BR>
<I>nested-name-specifier identifier</I> <TT>::</TT><BR>
<I>nested-name-specifier</I> <TT>template</TT><I><SUB>opt</SUB> simple-template-id</I> <TT>::</TT>

</UL>

</UL>

<BR><BR><HR><A NAME="1425"></A><H4>1425.
  
Base-class subobjects of standard-layout structs
</H4><B>Section: </B>9.2&#160; [class.mem]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Ville Voutilainen
 &#160;&#160;&#160;

 <B>Date: </B>2011-12-07<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>According to 9.2 [class.mem] paragraph 20,</P>

<BLOCKQUOTE>

A pointer to a standard-layout struct object, suitably converted
using a <TT>reinterpret_cast</TT>, points to its initial member (or if
that member is a bit-field, then to the unit in which it resides)
and vice versa.

</BLOCKQUOTE>

<P>Given a standard-layout struct in which the non-static data members
are in a base class (and hence the derived class is empty), it is not
clear what the &#8220;initial member&#8221; is.  Presumably the intent
behind allowing such standard-layout classes was to treat the base
class object and its first non-static data member as the initial
member of the derived class, but this does not appear to be spelled out
anywhere.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 9.2 [class.mem] paragraph 20 as follows:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A pointer to a standard-layout struct object, suitably converted
using a <TT>reinterpret_cast</TT>, points to its initial member (or if
that member is a bit-field, then to the unit in which it resides) and
vice versa.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">If a standard-layout class object has any
non-static data members, its address is the same as the address of its
first non-static data member. Otherwise, its address is the same as
the address of its first base class subobject (if any).</SPAN>
[<I>Note:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1605"></A><H4>1605.
  
Misleading parenthetical comment for explicit destructor call
</H4><B>Section: </B>12.4&#160; [class.dtor]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>2013-01-13<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>

<P>According to 12.4 [class.dtor] paragraph 13,</P>

<BLOCKQUOTE>

The invocation of a destructor is subject to the usual rules for
member functions (9.3 [class.mfct]), that is, if the object is
not of the destructor's class type and not of a class derived from the
destructor's class type, the program has undefined behavior (except
that invoking <TT>delete</TT> on a null pointer has no effect).

</BLOCKQUOTE>

<P>While true, the final parenthetical comment concerns a
<I>delete-expression</I>, not an explicit destructor call.  Its
presence here could mislead a careless reader to think that invoking
a destructor with a null pointer is harmless.  It should be deleted.</P>

<P><B>Proposed resolution (February, 2013):</B></P>

<P>Change 12.4 [class.dtor] paragraph 13 as follows:</P>

<BLOCKQUOTE>

In an explicit destructor call, the destructor name appears as a <TT>~</TT>
followed by a <I>type-name</I> or <I>decltype-specifier</I> that denotes
the destructor's class type. The invocation of a destructor is subject to
the usual rules for member functions
(9.3 [class.mfct])<SPAN style="text-decoration:line-through;background-color:#FFA0A0">,</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">;</SPAN> that is, if the object
is not of the destructor's class type and not of a class derived from the
destructor's class type <SPAN style="font-weight:bold;background-color:#A0FFA0">(including when the destructor is invoked via
a null pointer value)</SPAN>, the program has undefined
behavior <SPAN style="text-decoration:line-through;background-color:#FFA0A0">(except that invoking delete on a null pointer has no
effect)</SPAN>. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> invoking <TT>delete</TT> on a null
pointer does not call the destructor; see
5.3.5 [expr.delete]. &#8212;<I>end note</I>]</SPAN>
[<I>Example:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1402"></A><H4>1402.
  
Move functions too often deleted
</H4><B>Section: </B>12.8&#160; [class.copy]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2011-10-03<BR>


<P>[Moved to DR status at the April, 2013 meeting as paper N3667.]</P>



<P>Paragraphs 11 and 23 of 12.8 [class.copy] make a
defaulted move constructor and assignment operator, respectively,
deleted if there is a subobject with no corresponding move
function and for which the copy operation is non-trivial.  This
seems excessive and unnecessary.  For example:</P>

<PRE>
    template&lt;typename T&gt;
     struct wrap
     {
      wrap() = default;

    #ifdef USE_DEFAULTED_MOVE
      wrap(wrap&amp;&amp;) = default;
    #else
      wrap(wrap&amp;&amp; w) : t(static_cast&lt;T&amp;&amp;&gt;(w.t)) { }
    #endif

      wrap(const wrap&amp;) = default;

      T t;
     };

    struct S {
      S(){}
      S(const S&amp;){}
      S(S&amp;&amp;){}
    };

    typedef wrap&lt;const S&gt; W;

    W get() { return W(); }  //<SPAN style="font-family:Times;font-style:italic"> Error, if </SPAN>USE_DEFAULTED_MOVE<SPAN style="font-family:Times;font-style:italic"> is defined, else OK</SPAN>
</PRE>

<P>In this example the defaulted move constructor of
<TT>wrap</TT> is selected by overload resolution, but this
move-constructor is deleted, because <TT>S</TT> has no
<I>trivial</I> copy-constructor.</P>

<P>I think that we overshoot here with the delete rules: I see no
problem for the defaulted move-constructor in this example. Our
triviality-deduction rules already cover this case (12.8 [class.copy] paragraph 12: <TT>W::W(W&amp;&amp;)</TT> is not
trivial) and our exception-specification rules (15.4 [except.spec] paragraph 14) already correctly deduce a
<TT>noexcept(false)</TT> specification for
<TT>W::W(W&amp;&amp;)</TT>.</P>

<P>It would still be OK to prevent that a move-constructor
would be generated for the following example where no
user-declared defaulted copy/move members are present:</P>

<PRE>
    template&lt;typename T&gt;
     struct wrap_2
     {
      wrap_2() = default;
      T t;
     };

    typedef wrap_2&lt;const S&gt; W2;

    W2 get() { return W2(); }  //<SPAN style="font-family:Times;font-style:italic"> OK, selects copy constructor</SPAN>
</PRE>

<P>if we want. This would mean that we add a new bullet
to 12.8 [class.copy] paragraph 9 and paragraph 20.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<OL><LI><P>Change 12.8 [class.copy] paragraph 9 as follows:</P></LI>

<BLOCKQUOTE>

<P>If the definition of a class <TT>X</TT> does not explicitly declare
a move constructor, one will be implicitly declared as defaulted if
and only if</P>

<UL><LI><P>...</P></LI>

<LI><P>X does not have a user-declared destructor, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">and</SPAN></P></LI>

<LI><P>the move constructor would not be implicitly defined as
deleted<SPAN style="text-decoration:line-through;background-color:#FFA0A0">.</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">, and</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">each of <TT>X</TT>'s non-static data members and direct or
virtual base classes has a type that either has a move constructor or
is trivially copyable.</SPAN></P></LI>

</UL>

<P>[<I>Note:</I>...</P>

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraph 11 as follows:</P></LI>

<BLOCKQUOTE>

<P>An implicitly-declared copy/move constructor is an <TT>inline
public</TT> member of its class. A defaulted copy/move constructor for
a class <TT>X</TT> is defined as deleted (8.4.3 [dcl.fct.def.delete])
if <TT>X</TT> has:</P>

<UL><LI><P>...</P></LI>

<LI><P>any direct or virtual base class or non-static data member of a
type with a destructor that is deleted or inaccessible from the
defaulted constructor, <SPAN style="font-weight:bold;background-color:#A0FFA0">or</SPAN></P></LI>

<LI><P>for the copy constructor, a non-static data member of rvalue
reference type<SPAN style="font-weight:bold;background-color:#A0FFA0">.</SPAN><SPAN style="text-decoration:line-through;background-color:#FFA0A0">, or</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">for the move constructor, a non-static data member or
direct or virtual base class with a type that does not have a move
constructor and is not trivially copyable.</SPAN></P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraph 20 as follows:</P></LI>

<BLOCKQUOTE>

<P>If the definition of a class <TT>X</TT> does not explicitly declare
a move assignment operator, one will be implicitly declared as
defaulted if and only if</P>

<UL><LI><P>...</P></LI>

<LI><P><TT>X</TT> does not have a user-declared destructor,
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">and</SPAN></P></LI>

<LI><P>the move assignment operator would not be implicitly defined as
deleted<SPAN style="text-decoration:line-through;background-color:#FFA0A0">.</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>X</TT> has no direct or indirect virtual base class
with a non-trivial move assignment operator, and</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">each of <TT>X</TT>'s non-static data members and direct or
virtual base classes has a type that either has a move assignment
operator or is trivially copyable.</SPAN></P></LI>

</UL>

<P><I>Example:...</I></P>

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraph 23 as follows:</P></LI>

<BLOCKQUOTE>

<P>A defaulted copy/move assignment operator for class <TT>X</TT> is
defined as deleted if <TT>X</TT> has:</P>

<UL><LI><P>...</P></LI>

<LI><P>a direct or virtual base class <TT>B</TT> that cannot be
copied/moved because overload resolution (13.3 [over.match]),
as applied to <TT>B</TT>'s corresponding assignment operator, results
in an ambiguity or a function that is deleted or inaccessible from the
defaulted assignment operator<SPAN style="font-weight:bold;background-color:#A0FFA0">.</SPAN><SPAN style="text-decoration:line-through;background-color:#FFA0A0">, or</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">for the move assignment operator, a non-static data member or
direct base class with a type that does not have a move assignment
operator and is not trivially copyable, or any direct or indirect
virtual base class.</SPAN></P></LI>

</UL>

</BLOCKQUOTE>

</OL>

<P><B>Additional notes (August, 2012):</B></P>

<P>The proposed resolution was extensively discussed  and additional alternatives were
suggested.  A paper is being produced  for the October, 2012 meeting describing
the various options, so the issue has been returned to "review" status
to wait for the outcome of that deliberation.</P>

<P>See also the discussion of <A HREF="
     cwg_active.html#1491">issue 1491</A> for
additional considerations.</P>

<P><B>Proposed resolution (December, 2012):</B></P>

<OL><LI><P>Change 12.8 [class.copy] paragraph 9 as
follows:</P></LI>

<BLOCKQUOTE>

<P>If the definition of a class <TT>X</TT> does not explicitly declare
a move constructor, one will be implicitly declared as defaulted if
and only if</P>

<UL><LI><P><TT>X</TT> does not have a user-declared copy constructor,</P></LI>

<LI><P><TT>X</TT> does not have a user-declared copy assignment
operator,</P></LI>

<LI><P><TT>X</TT> does not have a user-declared move assignment
operator, <SPAN style="font-weight:bold;background-color:#A0FFA0">and</SPAN></P></LI>

<LI><P><TT>X</TT> does not have a user-declared
destructor<SPAN style="font-weight:bold;background-color:#A0FFA0">.</SPAN><SPAN style="text-decoration:line-through;background-color:#FFA0A0">, and</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">the move constructor would not be implicitly defined as
deleted.</SPAN></P></LI>

</UL>

<P>[<I>Note:</I>...</P>

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraph 11 as follows:</P></LI>

<BLOCKQUOTE>

<P>...A defaulted copy/move constructor for a class <TT>X</TT> is
defined as deleted (8.4.3 [dcl.fct.def.delete]) if <TT>X</TT> has:</P>

<UL><LI><P>a variant member with a non-trivial corresponding
constructor and <TT>X</TT> is a union-like class,</P></LI>

<LI><P>a non-static data member of class type <TT>M</TT> (or array
thereof) that cannot be copied/moved because overload resolution
(13.3 [over.match]), as applied to <TT>M</TT>'s corresponding
constructor, results in an ambiguity or a function that is deleted or
inaccessible from the defaulted constructor,</P></LI>

<LI><P>a direct or virtual base class <TT>B</TT> that cannot be
copied/moved because overload resolution (13.3 [over.match]),
as applied to <TT>B</TT>'s corresponding constructor, results in an
ambiguity or a function that is deleted or inaccessible from the
defaulted constructor,</P></LI>

<LI><P>any direct or virtual base class or non-static data member of a
type with a destructor that is deleted or inaccessible from the
defaulted constructor, <SPAN style="font-weight:bold;background-color:#A0FFA0">or</SPAN></P></LI>

<LI><P>for the copy constructor, a non-static data member of rvalue
reference type<SPAN style="font-weight:bold;background-color:#A0FFA0">.</SPAN><SPAN style="text-decoration:line-through;background-color:#FFA0A0">, or</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">for the move constructor, a non-static data member or
direct or virtual base class with a type that does not have a move
constructor and is not trivially copyable.</SPAN></P></LI>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">A defaulted move constructor that is defined as deleted is
ignored by overload resolution (13.3 [over.match]).
[<I>Note:</I> A deleted move constructor would otherwise interfere
with initialization from an rvalue which can use the copy constructor
instead. &#8212;<I>end note</I>]</SPAN></P>

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraph 20 as follows:</P></LI>

<BLOCKQUOTE>

<P>If the definition of a class <TT>X</TT> does not explicitly declare
a move assignment operator, one will be implicitly declared as
defaulted if and only if</P>

<UL><LI><P><TT>X</TT> does not have a user-declared copy
constructor,</P></LI>

<LI><P><TT>X</TT> does not have a user-declared move
constructor,</P></LI>

<LI><P><TT>X</TT> does not have a user-declared copy assignment
operator, <SPAN style="font-weight:bold;background-color:#A0FFA0">and</SPAN></P></LI>

<LI><P><TT>X</TT> does not have a user-declared
destructor<SPAN style="font-weight:bold;background-color:#A0FFA0">.</SPAN><SPAN style="text-decoration:line-through;background-color:#FFA0A0">, and</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">the move assignment operator would not be implicitly
defined as deleted.</SPAN></P></LI>

</UL>

<P>[<I>Example:</I>...</P>

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraph 23 as follows:</P></LI>

<BLOCKQUOTE>

<P>A defaulted copy/move assignment operator for class <TT>X</TT> is
defined as deleted if <TT>X</TT> has:</P>

<UL><LI><P>a variant member with a non-trivial corresponding assignment
operator and <TT>X</TT> is a union-like class, or</P></LI>

<LI><P>a non-static data member of const non-class type (or array
thereof), or</P></LI>

<LI><P>a non-static data member of reference type, or</P></LI>

<LI><P>a non-static data member of class type <TT>M</TT> (or array
thereof) that cannot be copied/moved because overload resolution
(13.3 [over.match]), as applied to <TT>M</TT>'s corresponding
assignment operator, results in an ambiguity or a function that is
deleted or inaccessible from the defaulted assignment operator,
or</P></LI>

<LI><P>a direct or virtual base class <TT>B</TT> that cannot be
copied/moved because overload resolution (13.3 [over.match]),
as applied to <TT>B</TT>'s corresponding assignment operator, results
in an ambiguity or a function that is deleted or inaccessible from the
defaulted assignment operator<SPAN style="font-weight:bold;background-color:#A0FFA0">.</SPAN><SPAN style="text-decoration:line-through;background-color:#FFA0A0">, or</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">for the move assignment operator, a non-static data member
or direct base class with a type that does not have a move assignment
operator and is not trivially copyable, or any direct or indirect
virtual base class.</SPAN></P></LI>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">A defaulted move assignment operator that is defined as deleted is
ignored by overload resolution (13.3 [over.match],
13.4 [over.over]).</SPAN></P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1487"></A><H4>1487.
  
When are inheriting constructors declared?
</H4><B>Section: </B>12.9&#160; [class.inhctor]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2012-03-27<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>According to 12.9 [class.inhctor] paragraph 3,</P>

<BLOCKQUOTE>

For each non-template constructor in the candidate set of inherited
constructors other than a constructor having no parameters or a
copy/move constructor having a single parameter, a constructor is
implicitly declared with the same constructor characteristics unless
there is a user-declared constructor with the same signature in the
class where the <I>using-declaration</I> appears.

</BLOCKQUOTE>

<P>It is not clear whether that determination is intended to include
constructors declared after the point of the <I>using-declaration</I>
or not.</P>

<P><B>Proposed resolution (February, 2013):</B></P>

<OL><LI><P>Change 9.2 [class.mem] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

A class is considered a completely-defined object type (3.9 [basic.types]) (or complete type) at the closing <TT>}</TT> of the
<I>class-specifier</I>.  Within the class <I>member-specification</I>,
the class is regarded as complete within function bodies, default
arguments, <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>using-declaration</I>s introducing inheriting
constructors (12.9 [class.inhctor]),</SPAN> and
<I>brace-or-equal-initializer</I>s for non-static data members
(including such things in nested classes). Otherwise it is regarded as
incomplete within its own class
<I>member-specification</I>.

</BLOCKQUOTE>

<LI><P>Change 12 [special] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...See 12.1 [class.ctor], 12.4 [class.dtor] and
12.8 [class.copy].  &#8212;<I>end note</I>] <SPAN style="font-weight:bold;background-color:#A0FFA0">An
implicitly-declared special member function is declared at the closing
<TT>}</TT> of the <I>class-specifier</I>.</SPAN> Programs shall not
define implicitly-declared special member functions.

</BLOCKQUOTE>

<LI><P>Change 12.9 [class.inhctor] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

For each non-template constructor in the candidate set of inherited
constructors other than a constructor having no parameters or a
copy/move constructor having a single parameter, a constructor is
implicitly declared with the same constructor characteristics unless
there is a user-declared constructor with the same signature in the
<SPAN style="font-weight:bold;background-color:#A0FFA0">complete</SPAN> class where the <I>using-declaration</I> appears.
Similarly, for each constructor template in the candidate set of
inherited constructors, a constructor template is implicitly declared
with the same constructor characteristics unless there is an
equivalent user-declared constructor template (14.5.6.1 [temp.over.link]) in the <SPAN style="font-weight:bold;background-color:#A0FFA0">complete</SPAN> class where the
<I>using-declaration</I> appears.  [<I>Note:</I> Default arguments are
not inherited.  An <I>exception-specification</I> is implied as
specified in 15.4 [except.spec]. &#8212;<I>end note</I>]

</BLOCKQUOTE>

</OL>

<P><B>Additional note (January, 2013):</B></P>

<P>A question has been raised  as to
whether it is necessary to prohibit inheriting constructors from
base classes that are also enclosing classes when the derived class
is defined outside the <I>member-specification</I> of the enclosing
class.  This issue has been returned to "review" status to allow
discussion of this question.</P>

<P><B>Additional note (February, 2013):</B></P>

<P>It was observed that it is not permitted to derive from an
incomplete class, which prevents the problem intended to be addressed
by the prohibition of inheriting constructors from an enclosing
class without disallowing such usage when the nested class is defined
outside its enclosing class.  That restriction has been removed from
the proposed resolution.</P>

<BR><BR><HR><A NAME="1556"></A><H4>1556.
  
Constructors and explicit conversion functions in direct initialization
</H4><B>Section: </B>13.3.1.4&#160; [over.match.copy]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Edward Catmur
 &#160;&#160;&#160;

 <B>Date: </B>2012-09-18<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P><A HREF="
     cwg_defects.html#899">Issue 899</A> added wording to the second
bullet of 13.3.1.4 [over.match.copy] paragraph 1 permitting use of
<TT>explicit</TT> conversion functions when calling a copy constructor
in a direct-initialization context.  <A HREF="
     cwg_defects.html#1087">Issue 1087</A> addressed the problem in the earlier resolution that the
phrase &#8220;copy constructor&#8221; did not include move
constructors and template constructors.  However, the term &#8220;copy
constructor&#8221; implicitly (and correctly) restricted the
constructor parameter to be the constructor's class, i.e., the class
of the object being directly initialized.  The new phrasing, &#8220;a
constructor that takes a reference to possibly cv-qualified <TT>T</TT>
as its first argument,&#8221; incorrectly assumed that <TT>T</TT>
referred to the type of the object being initialized; however, that is
not the case, and a converting constructor from <TT>T</TT> to the type
of the object being initialized is inadvertently permitted.  The
wording needs a further tweak to restore the intended context.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change the second bullet of 13.3.1.4 [over.match.copy]
paragraph 1 as follows:</P>

<BLOCKQUOTE>

<P>...Assuming that &#8220;<I>cv1</I> <TT>T</TT>&#8221; is the type of the
object being initialized, with <TT>T</TT> a class type, the candidate
functions are selected as follows:</P>

<UL><LI><P>The converting constructors (12.3.1 [class.conv.ctor])
of <TT>T</TT> are candidate functions.</P></LI>

<LI><P>When the type of the initializer expression is a class type
&#8220;<I>cv</I> <TT>S</TT>&#8221;, the non-explicit conversion
functions of <TT>S</TT> and its base classes are considered. When
initializing a temporary to be bound to the first parameter of a
constructor that takes a reference to possibly cv-qualified <TT>T</TT>
as its first argument, called with a single argument in the context of
direct-initialization <SPAN style="font-weight:bold;background-color:#A0FFA0">of an object of type &#8220;<I>cv2</I>
<TT>T</TT>&#8221;</SPAN>, explicit conversion functions are also
considered.  Those that are not hidden within <TT>S</TT> and yield a
type whose cv-unqualified version is the same type as <TT>T</TT> or is
a derived class thereof are candidate functions. Conversion functions
that return &#8220;reference to <TT>X</TT>&#8221; return lvalues or
xvalues, depending on the type of reference, of type <TT>X</TT> and
are therefore considered to yield <TT>X</TT> for this process of
selecting candidate functions.</P></LI>



</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1543"></A><H4>1543.
  
Implicit conversion sequence for empty initializer list
</H4><B>Section: </B>13.3.3.1.5&#160; [over.ics.list]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>2012-08-21<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>

<P>According to 13.3.3.1.5 [over.ics.list] paragraph 6, when passing
an initializer-list argument to a non-class parameter,</P>

<BLOCKQUOTE>

if the initializer list has no elements, the implicit conversion
sequence is the identity conversion.

</BLOCKQUOTE>

<P>However, there is no similar provision for an empty initializer
list passed to a specialization of <TT>std::initializer_list</TT> or
an array, as described in paragraph 2:</P>

<BLOCKQUOTE>

If the parameter type is <TT>std::initializer_list&lt;X&gt;</TT> or
&#8220;array of <TT>X</TT>&#8221;<SUP>134</SUP> and all the elements of the
initializer list can be implicitly converted to <TT>X</TT>, the implicit
conversion sequence is the worst conversion necessary to convert an
element of the list to <TT>X</TT>.

</BLOCKQUOTE>

<P>It is not clear what the result should be for a list with no
elements.  For example, given</P>

<PRE>
  void f(int) { printf("int\n"); }
  void f(std::initializer_list&lt;int&gt;) { printf("init list\n"); }
  int main() {
      f({});
  }
</PRE>

<P>current implementations result in <TT>init list</TT> being printed,
presumably on the basis of the last bullet of 13.3.3.2 [over.ics.rank]
paragraph 3:</P>

<UL><LI><P>List-initialization sequence <TT>L1</TT> is a better
conversion sequence than list-initialization sequence <TT>L2</TT> if
<TT>L1</TT> converts to <TT>std::initializer_list&lt;X&gt;</TT> for
some <TT>X</TT>\and <TT>L2</TT> does not.</P></LI></UL>

<P>That would imply that both conversion sequences are the identity
conversion, which is reasonable, but it should be stated clearly if that
is the intent.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 13.3.3.1.5 [over.ics.list] paragraph 2 as follows:</P>

<BLOCKQUOTE>

<P>If the parameter type is <TT>std::initializer_list&lt;X&gt;</TT> or
&#8220;array of <TT>X</TT>&#8221;<SUP>134</SUP> and all the elements
of the initializer list can be implicitly converted to <TT>X</TT>, the
implicit conversion sequence is the worst conversion necessary to
convert an element of the list to <TT>X</TT><SPAN style="font-weight:bold;background-color:#A0FFA0">, or if the
initializer list has no elements, the identity conversion</SPAN>. This
conversion can be a user-defined conversion even in the context of a
call to an initializer-list constructor. [<I>Example:</I></P>

<PRE>
  void f(std::initializer_list&lt;int&gt;);
<SPAN style="font-weight:bold;background-color:#A0FFA0">  f( {} );        //<SPAN style="font-family:Times;font-style:italic"> OK: </SPAN>f(initializer_list&lt;int&gt;)<SPAN style="font-family:Times;font-style:italic"> identity conversion</SPAN></SPAN>
  f( {1,2,3} );   //<SPAN style="font-family:Times;font-style:italic"> OK: </SPAN>f(initializer_list&lt;int&gt;)<SPAN style="font-family:Times;font-style:italic"> identity conversion</SPAN>
  f( {'a','b'} ); //<SPAN style="font-family:Times;font-style:italic"> OK: </SPAN>f(initializer_list&lt;int&gt;)<SPAN style="font-family:Times;font-style:italic"> integral promotion</SPAN>
  f( {1.0} );     //<SPAN style="font-family:Times;font-style:italic"> error: narrowing</SPAN>
  ...
</PRE>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1374"></A><H4>1374.
  
Qualification conversion vs difference in reference binding
</H4><B>Section: </B>13.3.3.2&#160; [over.ics.rank]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Michael Wong
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-15<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>

<P>The rule in 13.3.3.2 [over.ics.rank] paragraph 3 for ranking
based on a difference in qualification conversion applies only if they
"differ only in their qualification conversion".</P>

<P>It is unclear as to whether the property of being a reference
binding is a factor in determining if there is a difference
between conversion sequences. Notice that 13.3.3.1.4 [over.ics.ref] maps reference bindings to other forms of
implicit conversion sequences, but does not state that the
property of being a reference binding is preserved; however,
13.3.3.2 [over.ics.rank] has cases which depend on whether
certain standard conversion sequences are reference bindings or
not and on the specifics of the bindings.</P>

<P>In the following, picking <TT>T2 &amp;&amp;</TT> would bind an
rvalue to an rvalue reference. Picking <TT>T1 &amp;</TT> would
bind an rvalue to an lvalue reference, but the qualification
conversion to <TT>T1</TT> is "better". Which is better?</P>

<PRE>
    typedef int *      *      *const *const T1;
    typedef int *const *const *const *const T2;
    void foo(T1 &amp;);
    void foo(T2 &amp;&amp;) { }

    int main() {
       foo((int ****)0);
       return 0;
    }
</PRE>

<P><B>Notes from the February, 2012 meeting:</B></P>

<P>The CWG agreed that bullets 3 and 4 should be reversed, to check
the reference binding first and then for qualification conversion.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Move 13.3.3.2 [over.ics.rank] paragraph 3, first bullet, third
sub-bullet, after the current fifth sub-bullet, as follows:</P>

<BLOCKQUOTE>

<P>Two implicit conversion sequences of the same form are
indistinguishable conversion sequences unless one of the following
rules applies:</P>

<UL><LI><P>Standard conversion sequence <TT>S1</TT> is a better
conversion sequence...</P></LI>

<UL><LI><P><TT>S1</TT> is a proper subsequence of <TT>S2</TT>...</P></LI>

<LI><P>the rank of <TT>S1</TT> is better...</P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>S1</TT> and <TT>S2</TT> differ only in their
qualification conversion... &#8212;<I>end example</I>] or if not
that,</SPAN></P></LI>

<LI><P><TT>S1</TT> and <TT>S2</TT> are reference bindings
(8.5.3 [dcl.init.ref]) and neither refers...  or if not
that,</P></LI>

<LI><P><TT>S1</TT> and <TT>S2</TT> are reference bindings
(8.5.3 [dcl.init.ref]) and S1 binds... &#8212;<I>end
example</I>] <SPAN style="font-weight:bold;background-color:#A0FFA0">or if not that,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>S1</TT> and <TT>S2</TT> differ only in their
qualification conversion... &#8212;<I>end example</I>]
or if not that,</SPAN></P></LI>

<LI><P><TT>S1</TT> and <TT>S2</TT> are reference bindings
(8.5.3 [dcl.init.ref]), and the types to which the references
refer...</P></LI>

</UL>

<LI>User-defined conversion sequence <TT>U1</TT>...</LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1563"></A><H4>1563.
  
List-initialization and overloaded function disambiguation
</H4><B>Section: </B>13.4&#160; [over.over]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2012-10-08<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>Presumably, 13.4 [over.over] paragraph 1,</P>

<BLOCKQUOTE>

<P>A use of an overloaded function name without arguments is resolved in
certain contexts to a function, a pointer to function or a pointer to
member function for a specific function from the overload set. A
function template name is considered to name a set of overloaded
functions in such contexts.  The function selected is the one whose
type is identical to the function type of the target type required in
the context.  [<I>Note:</I> That is, the class of which the function
is a member is ignored when matching a pointer-to-member-function
type.  &#8212;<I>end note</I>] The target can be</P>

<UL><LI><P>an object or reference being initialized (8.5 [dcl.init],
8.5.3 [dcl.init.ref]),</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<P>should apply to an example like</P>

<PRE>
  double bar(double) { return 0.0; }
  float bar(float) { return 0.0f; }

  using fun = double(double);
  fun &amp;foo{bar};
</PRE>

<P>However, there is implementation variance in whether the use of
<TT>bar</TT> is accepted or not, and the omission of a cross-reference
to 8.5.4 [dcl.init.list] might be read as indicating that
list-initialization is not included.</P>

<P><B>Proposed resolution (February, 2013):</B></P>

<P>Change 13.4 [over.over] paragraph 1 as follows:</P>

<BLOCKQUOTE>

<P>...The target can be</P>

<UL><LI><P>an object or reference being initialized
(8.5 [dcl.init], 8.5.3 [dcl.init.ref]<SPAN style="font-weight:bold;background-color:#A0FFA0">,
8.5.4 [dcl.init.list]</SPAN>),</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1481"></A><H4>1481.
  
Increment/decrement operators with reference parameters
</H4><B>Section: </B>13.5.7&#160; [over.inc]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Ryou Ezoe
 &#160;&#160;&#160;

 <B>Date: </B>2012-03-20<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>The phrase in 13.5.7 [over.inc] paragraph 1,</P>

<BLOCKQUOTE>

a non-member function with one parameter of class or enumeration type

</BLOCKQUOTE>

<P>inadvertently excludes reference parameters, and in fact, no
mention of the type is necessary in light of 13.5 [over.oper]
paragraph 6:</P>

<BLOCKQUOTE>

An operator function shall either be a non-static member function or
be a non-member function and have at least one parameter whose type is
a class, a reference to a class, an enumeration, or a reference to an
enumeration.

</BLOCKQUOTE>

<P><B>Proposed resolution (August, 2012):</B></P>

<P>Change 13.5.7 [over.inc] paragraph 1 as follows:</P>

<BLOCKQUOTE>

The user-defined function called <TT>operator++</TT> implements the
prefix and postfix <TT>++</TT> operator. If this function is a member
function with no parameters, or a non-member function with one
parameter <SPAN style="text-decoration:line-through;background-color:#FFA0A0">of class or enumeration type</SPAN>, it defines the prefix
increment operator ++ for objects of that type. If the function...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1473"></A><H4>1473.
  
Syntax of <I>literal-operator-id</I>
</H4><B>Section: </B>13.5.8&#160; [over.literal]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2012-03-05<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>The current grammar requires that there be no whitespace between the
literal and the <I>ud-suffix</I>, e.g., <TT>""_abc</TT>, but that there
be whitespace between the <TT>""</TT> and the <I>identifier</I> in a
<I>literal-operator-id</I>, e.g., <TT>operator&#160;""&#160;_abc</TT>.
This seems unfortunate.  Would it be possible to provide an alternate
production,</P>

<UL><TT>operator</TT> <I>user-defined-string-literal</I></UL>

<P>with the requirement that the <I>string-literal</I> be empty?</P>

<P>The current wording is also unclear regarding interactions with phases
of translation. We have the following production:
</P>

<UL><I>literal-operator-id:</I>
<UL><TT>operator ""</TT> <I>identifier</I></UL>
</UL>

<P>As this is after translation phase 6, would something like</P>

<PRE>
  operator "" "" _foo
</PRE>

<P>be accepted?</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<OL><LI><P>Change 13.5.8 [over.literal] as follows:</P></LI>

<UL><I>literal-operator-id:</I>
<UL><TT>operator <SPAN style="text-decoration:line-through;background-color:#FFA0A0">""</SPAN></TT> <I><SPAN style="font-weight:bold;background-color:#A0FFA0">string-literal</SPAN> identifier</I><BR>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>operator</TT> <I>user-defined-string-literal</I></SPAN>
</UL>
</UL>

<LI><P>Change 13.5.8 [over.literal] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<SPAN style="font-weight:bold;background-color:#A0FFA0">The <I>string-literal</I> or <I>user-defined-string-literal</I> in a
<I>literal-operator-id</I> shall have no <I>encoding-prefix</I> and
shall contain no characters other than the implicit terminating
<TT>'\0'</TT>.</SPAN> The <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>ud-suffix</I> of the
<I>user-defined-string-literal</I> or the</SPAN> <I>identifier</I> in a
<I>literal-operator-id</I> is called a <I>literal suffix
identifier</I>. [<I>Note:</I> some literal suffix identifiers are
reserved for future standardization; see 17.6.4.3.5 [usrlit.suffix].  &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Change the example in 13.5.8 [over.literal] paragraph 8
as follows:</P></LI>

<PRE>
  void operator "" _km(long double);                  //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
  string operator "" _i18n(const char*, std::size_t); //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
  template &lt;char...&gt; int operator "" \u03C0();        //<SPAN style="font-family:Times;font-style:italic"> OK: UCN for lowercase pi</SPAN>
  float operator ""E(const char*);                    //<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><SPAN style="font-family:Times;font-style:italic"> error: ""E (with no intervening space)</SPAN>
                                                      //<SPAN style="font-family:Times;font-style:italic"> is a single token</SPAN></SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0"><SPAN style="font-family:Times;font-style:italic"> OK</SPAN></SPAN>
  float operator " " B(const char*);                  //<SPAN style="font-family:Times;font-style:italic"> error: non-<SPAN style="text-decoration:line-through;background-color:#FFA0A0">adjacent quotes</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">empty string-literal</SPAN></SPAN>
  string operator "" 5X(const char*, std::size_t);    //<SPAN style="font-family:Times;font-style:italic"> error: invalid literal suffix identifier</SPAN>
  double operator "" _miles(double);                  //<SPAN style="font-family:Times;font-style:italic"> error: invalid parameter-declaration-clause</SPAN>
  template &lt;char...&gt; int operator "" <SPAN style="font-weight:bold;background-color:#A0FFA0">_</SPAN>j(const char*); //<SPAN style="font-family:Times;font-style:italic"> error: invalid parameter-declaration-clause</SPAN>
</PRE>

</OL>

<BR><BR><HR><A NAME="1479"></A><H4>1479.
  
Literal operators and default arguments
</H4><B>Section: </B>13.5.8&#160; [over.literal]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2012-03-13<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>It appears that an example like</P>

<PRE>
  int operator"" _a (const char *, std::size_t = 0);
  int operator"" _a (const char *);

  int i = 123_a;
</PRE>

<P>is ambiguous: although only the second declaration is a raw literal
operator, the corresponding call</P>

<PRE>
  operator"" _a ("123")
</PRE>

<P>could match either declaration.  Should default arguments for
literal operators be prohibited?</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 13.5.8 [over.literal] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<P>The declaration of a literal operator shall have a
<I>parameter-declaration-clause</I> equivalent to one of the
following:</P>

<P>...</P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">If a parameter has a default argument (8.3.6 [dcl.fct.default]), the program is ill-formed.</SPAN></P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1533"></A><H4>1533.
  
Function pack expansion for member initialization
</H4><B>Section: </B>14.5.3&#160; [temp.variadic]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Jonathan Caves
 &#160;&#160;&#160;

 <B>Date: </B>2012-08-06<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>

<P>The list of pack expansion contexts in 14.5.3 [temp.variadic]
paragraph 4 includes a <I>mem-initializer-list</I>, with no restriction
on whether the <I>mem-initializer</I> corresponds to a base class or
a member. However, it appears from 12.6.2 [class.base.init]
paragraph 15 that such a pack expansion is intended for bases:

<BLOCKQUOTE>

A <I>mem-initializer</I> followed by an ellipsis is a pack expansion
(14.5.3 [temp.variadic]) that initializes the base classes
specified by a pack expansion in the <I>base-specifier-list</I> for
the class.

</BLOCKQUOTE></P>

<P>This is not conclusive, however, and use of a pack expansion with
a <I>mem-initializer</I> for a member could be used with packs containing
zero or one element:</P>

<PRE>
  class S { };

  template&lt;typename... T&gt; class X {
  public:
    X(T ...args) : data_(args)... { }
  private:
    S data_;
  };

  int main() {
    S s;
    X&lt;&gt; x1;
    X&lt;S&gt; x2(s);
  }
</PRE>

<P>The Standard should be clarified as to whether such a usage is
permitted or not.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 14.5.3 [temp.variadic] paragraph 4 as follows:</P>

<BLOCKQUOTE>

<P>...Pack expansions can occur in the following contexts:</P>

<UL><LI><P>...</P></LI>

<LI><P>In a <I>mem-initializer-list</I> (12.6.2 [class.base.init])
<SPAN style="font-weight:bold;background-color:#A0FFA0">for a <I>mem-initializer</I> whose <I>mem-initializer-id</I>
denotes a base class</SPAN>; the pattern is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">the</SPAN>
<I>mem-initializer</I>.</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1495"></A><H4>1495.
  
Partial specialization of variadic class template
</H4><B>Section: </B>14.5.5&#160; [temp.class.spec]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2012-04-16<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>Consider an example like</P>

<PRE>
  template &lt;int B, typename Type1, typename... Types&gt;
  struct A;

  template&lt;typename... Types&gt;
  struct A&lt;0, Types...&gt; { };

  A&lt;0,int,int&gt; t;
</PRE>

<P>In this case, the partial specialization seems well-formed by the
rules in 14.5.5 [temp.class.spec], but it is not more specialized
than the primary template.  However, 14.5.5.1 [temp.class.spec.match]
says that if exactly one matching specialization is found, it is used,
which suggests that the testcase is well-formed.  That seems
undesirable; I think a partial specialization that is not more
specialized than the primary template should be ill-formed.
</P>

<P>If the example is rewritten so that both versions are partial
specializations, i.e.,</P>

<PRE>
  template &lt;int B, typename... Types&gt;
  struct A;

  template &lt;int B, typename Type1, typename... Types&gt;
  struct A&lt;B, Type1, Types...&gt; { }

  template&lt;typename... Types&gt;
  struct A&lt;0, Types...&gt; { };

  A&lt;0,int,int&gt; t;
</PRE>

<P>There is implementation variance, with gcc and clang reporting an
ambiguity and EDG choosing the second specialization.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Add the following as a new bullet in 14.5.5 [temp.class.spec]
paragraph 8:</P>

<UL><LI><P>...</P></LI>

<LI><P>The argument list of the specialization shall not be identical to the
implicit argument list of the primary template.</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">The specialization shall be more specialized than the primary
template (14.5.5.2 [temp.class.order]).</SPAN></P></LI>

<LI><P>...</P></LI>

</UL>

<BR><BR><HR><A NAME="1471"></A><H4>1471.
  
Nested type of non-dependent base
</H4><B>Section: </B>14.6.2.1&#160; [temp.dep.type]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Johannes Schaub
 &#160;&#160;&#160;

 <B>Date: </B>2012-02-26<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>Even though <TT>A::C</TT> is a nested type and member of the current
instantiation, and thus dependent by the rules of
14.6.2.1 [temp.dep.type] paragraph 8, there does not seem to be a
good reason for making it so:</P>

<PRE>
  struct B {
   struct C { };
  };

  template&lt;typename T&gt; struct A : B {
   A::C c;
  };
</PRE>

<P><B>Proposed resolution (October, 2012):</B></P>

<P><I>[Some existing uses of the term &#8220;member of the current
instantiation&#8221; are consistent with the definition in
14.6.2.1 [temp.dep.type] paragraph 4; others are intended to
refer to members of the &#8220;current instantiation,&#8221; as
defined in paragraph 1.  The following resolution changes the
latter to use the phrase &#8220;member of a class that is the
current instantiation.&#8221;]</I></P>

<OL><LI><P>Change 14.6.2.1 [temp.dep.type] paragraph 4 as
follows:</P></LI>

<BLOCKQUOTE>

<P>A name is a <I>member of the current instantiation</I> if it is</P>

<UL><LI><P>An unqualified name that, when looked up, refers to at
least one member of <SPAN style="font-weight:bold;background-color:#A0FFA0">a class that is</SPAN> the current
instantiation or a non-dependent base class thereof. [<I>Note:</I>
This can only occur when looking up a name in a scope enclosed by the
definition of a class template.  &#8212;<I>end note</I>]</P></LI>

<LI><P>A <I>qualified-id</I> in which the <I>nested-name-specifier</I>
refers to the current instantiation and that, when looked up, refers
to at least one member of <SPAN style="font-weight:bold;background-color:#A0FFA0">a class that is</SPAN> the current
instantiation or a non-dependent base class thereof.  [<I>Note:</I> if
no such member is found, and the current instantiation has any
dependent base classes, then the <I>qualified-id</I> is a member of an
unknown specialization; see below.  &#8212;<I>end note</I>]</P></LI>

<LI><P>An <I>id-expression</I> denoting the member in a class member access
expression (5.2.5 [expr.ref]) for which the type of the
object expression is the current instantiation, and the
<I>id-expression</I>, when looked up (3.4.5 [basic.lookup.classref]),
refers to at least one member of <SPAN style="font-weight:bold;background-color:#A0FFA0">a class that is</SPAN> the
current instantiation or a non-dependent base class
thereof. [<I>Note:</I> if no such member is found, and the current
instantiation has any dependent base classes, then the
<I>id-expression</I> is a member of an unknown specialization; see
below.  &#8212;<I>end note</I>]</P></LI>

</UL>

<P>[<I>Example:</I> ... &#8212;<I>end example</I>]</P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">A name is a <I>dependent member of the current instantiation</I>
if it is a member of the current instantiation which, when looked up,
refers to at least one member of a class that is the current
instantiation.</SPAN></P>

</BLOCKQUOTE>

<LI><P>Change 14.6.2.1 [temp.dep.type] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

<P>A name is a <I>member of an unknown specialization</I> if it is</P>

<UL><LI><P>A <I>qualified-id</I> in which the
<I>nested-name-specifier</I> names a dependent type that is not the
current instantiation.</P></LI>

<LI><P>A <I>qualified-id</I> in which the <I>nested-name-specifier</I>
refers to the current instantiation, the current instantiation has at
least one dependent base class, and name lookup of the
<I>qualified-id</I> does not find any member of <SPAN style="font-weight:bold;background-color:#A0FFA0">a class that
is</SPAN> the current instantiation or a non-dependent base class
thereof.</P></LI>

<LI><P>An <I>id-expression</I> denoting the member in a class member access
expression (5.2.5 [expr.ref]) in which either</P></LI>

<UL><LI><P>the type of the object expression is the current
instantiation, the current instantiation has at least one dependent
base class, and name lookup of the <I>id-expression</I> does not find
a member of <SPAN style="font-weight:bold;background-color:#A0FFA0">a class that is</SPAN> the current instantiation or a
non-dependent base class thereof; or</P></LI>

<LI><P>the type of the object expression is dependent and is not the
current instantiation.</P></LI>

</UL>

</UL>

</BLOCKQUOTE>

<LI><P>Change 14.6.2.1 [temp.dep.type] paragraph 8 as follows:</P></LI>

<BLOCKQUOTE>

<P>A type is dependent if it is</P>

<UL><LI><P>...</P></LI>

<LI><P>a nested class or enumeration that is a <SPAN style="font-weight:bold;background-color:#A0FFA0">dependent</SPAN>
member of the current instantiation,</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 14.6.2.2 [temp.dep.expr] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

<P>An <I>id-expression</I> is type-dependent if it contains</P>

<UL><LI><P>...</P></LI></UL>

<P>or if it names a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">static data</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">dependent</SPAN> member
of the current instantiation that <SPAN style="text-decoration:line-through;background-color:#FFA0A0">has</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">is a static data
member of</SPAN> type &#8220;array of unknown bound of
<TT>T</TT>&#8221; for some <TT>T</TT> (14.5.1.3 [temp.static]). Expressions of the following forms...</P>

</BLOCKQUOTE>

<LI><P>Change 14.6.2.3 [temp.dep.constexpr] paragraph 2 as follows
(assumes the base text is as modified by <A HREF="
     cwg_defects.html#1413">issue 1413</A>):</P></LI>

<BLOCKQUOTE>

<P>An <I>id-expression</I> is value-dependent if:</P>

<UL><LI><P>it is a name declared with a dependent type,</P></LI>

<LI><P>it is the name of a non-type template parameter,</P></LI>

<LI><P>it names a member of an unknown specialization,</P></LI>

<LI><P>it names a static data member <SPAN style="text-decoration:line-through;background-color:#FFA0A0">of the current
instantiation</SPAN> that is <SPAN style="font-weight:bold;background-color:#A0FFA0">a dependent member of the current
instantiation and is</SPAN> not initialized in a
<I>member-declarator</I>,</P></LI>

<LI><P>it names a static member function that is a
<SPAN style="font-weight:bold;background-color:#A0FFA0">dependent</SPAN> member of the current instantiation, or</P></LI>

<LI><P>it is a constant with literal type and is initialized with an
expression that is value-dependent.</P></LI>

</UL>

<P>Expressions of the following form...</P>

</BLOCKQUOTE>

<LI><P>Change 14.6.2.3 [temp.dep.constexpr] paragraph 5 as follows
(assumes the base text is as modified by <A HREF="
     cwg_defects.html#1413">issue 1413</A>):</P></LI>

<BLOCKQUOTE>

An expression of the form <TT>&amp;</TT><I>qualified-id</I> where the
<I>qualified-id</I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">'s <I>nested-name-specifier</I></SPAN> names
<SPAN style="font-weight:bold;background-color:#A0FFA0">a dependent member of</SPAN> the current instantiation is
value-dependent.

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="903"></A><H4>903.
  
Value-dependent integral null pointer constants
</H4><B>Section: </B>14.6.2.3&#160; [temp.dep.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Doug Gregor
 &#160;&#160;&#160;

 <B>Date: </B>22 May, 2009<BR>


<P>[Moved to DR status at the April, 2013 meeting.]</P>



<P>Consider the following example:</P>

<PRE>
    void f(int*);
    void f(...);

    template &lt;int N&gt; void g() {
      f(N);
    }

    int main() {
      g&lt;0&gt;();
      g&lt;1&gt;();
    }
</PRE>

<P>The call to <TT>f</TT> in <TT>g</TT> is not type-dependent, so the
overload resolution must be done at definition time rather than at
instantiation time.  As a result, both of the calls to <TT>g</TT>
will result in calls to <TT>f(...)</TT>, i.e., <TT>N</TT> will not
be a null pointer constant, even if the value of <TT>N</TT> is 0.</P>

<P>It would be most consistent to adopt a rule that a value-dependent
expression can never be a null pointer constant, even in cases like</P>

<PRE>
    template &lt;int N&gt; void g() {
      int* p = N;
    }
</PRE>

<P>This would always be ill-formed, even when <TT>N</TT> is 0.</P>

<P><U>John Spicer</U>: It's clear that this treatment is required for
overload resolution, but it seems too expansive given that there are
other cases in which the value of a template parameter can affect
the validity of the program, and an implementation is forbidden to
issue a diagnostic on a template definition unless there are no
possible valid specializations.</P>

<P><B>Notes from the July, 2009 meeting:</B></P>

<P>There was a strong consensus among the CWG that only the literal
<TT>0</TT> should be considered a null pointer constant, not any
arbitrary zero-valued constant expression as is currently specified.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<OL><LI><P>Change 4.10 [conv.ptr] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

A <I>null pointer constant</I> is an <SPAN style="text-decoration:line-through;background-color:#FFA0A0">integral constant expression
(5.19 [expr.const]) prvalue of integer type that evaluates
to</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">integer literal (2.14.2 [lex.icon]) with
value</SPAN> zero or a prvalue of type <TT>std::nullptr_t</TT>. A null
pointer constant can be converted...

</BLOCKQUOTE>

<LI><P>Change 5.19 [expr.const] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

...[<I>Note:</I> Such expressions may be used as array bounds
(8.3.4 [dcl.array], 5.3.4 [expr.new]), as bit-field
lengths (9.6 [class.bit]), as enumerator initializers if the
underlying type is not fixed (7.2 [dcl.enum]), <SPAN style="text-decoration:line-through;background-color:#FFA0A0">as null
pointer constants (4.10 [conv.ptr]),</SPAN> and as alignments
(7.6.2 [dcl.align]). &#8212;<I>end note</I>]...

</BLOCKQUOTE>

<LI><P>Change 8.5 [dcl.init] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

<P>To <I>zero-initialize</I> an object or reference of type <TT>T</TT>
means:</P>

<UL><LI><P>if <TT>T</TT> is a scalar type (3.9 [basic.types]),
the object is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">set to the value <TT>0</TT> (zero), taken as an integral
constant expression, converted</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">initialized to the value
obtained by converting integer literal <TT>0</TT> (zero)</SPAN> to
<TT>T</TT>; [<I>Footnote:</I> As specified in 4.10 [conv.ptr], converting an <SPAN style="text-decoration:line-through;background-color:#FFA0A0">integral constant expression</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">integer literal</SPAN> whose value is 0 to a pointer type results
in a null pointer value. &#8212;<I>end footnote</I>]</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 14.3.2 [temp.arg.nontype] paragraph 5 as follows:</P></LI>

<UL><LI><P>...</P></LI>

<LI><P>for a non-type <I>template-parameter</I> of type pointer to
object, qualification conversions (4.4 [conv.qual]) and the
array-to-pointer conversion (4.2 [conv.array]) are applied; if
the <I>template-argument</I> is of type <TT>std::nullptr_t</TT>, the
null pointer conversion (4.10 [conv.ptr]) is applied.
[<I>Note:</I> In particular, neither the null pointer conversion for a
zero-valued <SPAN style="text-decoration:line-through;background-color:#FFA0A0">integral constant expression</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">integer
literal</SPAN> (4.10 [conv.ptr]) nor the derived-to-base
conversion (4.10 [conv.ptr]) are applied.  Although 0
is...</P></LI>

<LI><P>...</P></LI>

</UL>

<LI><P>Change 15.3 [except.handle] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

...[<I>Note:</I> A <I>throw-expression</I> whose operand is an
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">integral constant expression of integer type that evaluates
to</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">integer literal with value</SPAN> zero does not match a
handler of pointer or pointer to member type. &#8212;<I>end
note</I>]. [<I>Example:</I> ...

</BLOCKQUOTE>

<LI><P>Add a new section to C.2 [diff.cpp03] as follows:</P></LI>

<BLOCKQUOTE>

<P><TABLE WIDTH="100%"><TR><TD><SPAN style="font-weight:bold;background-color:#A0FFA0"><B>C.2.x Clause 4: standard
conversions</B></SPAN></TD>
<TD ALIGN="right"><SPAN style="font-weight:bold;background-color:#A0FFA0"><B>[diff.cpp03.conv]</B></SPAN></TD> </TR></TABLE></P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">
4.10 [conv.ptr]<BR>
<B>Change:</B> Only literals are integer null pointer constants<BR>
<B>Rationale:</B> Removing surprising interactions with templates
and constant expressions<BR>
<B>Effect on original feature:</B> Valid C++ 2003 code may fail to
compile or produce different results in this International Standard,
as the following example illustrates:<BR></SPAN>
<BR>
<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  void f(void *);  //<SPAN style="font-family:Times;font-style:italic"> #1</SPAN>
  void f(...);     //<SPAN style="font-family:Times;font-style:italic"> #2</SPAN>
  template&lt;int N&gt; void g() {
      f(0*N);      //<SPAN style="font-family:Times;font-style:italic"> calls #2; used to call #1</SPAN>
  }</SPAN>
</PRE>
</P>

</BLOCKQUOTE>

</OL>

<P><B>Additional note (January, 2013):</B></P>

<P>Concerns were raised at the Portland (October, 2012) meeting
 that the value <TT>false</TT>
has been used in existing code as a null pointer constant, and
such code would be broken by this change.  This issue has been returned
to "review" status to allow discussion of whether to accommodate such
code or not.</P>

<BR><BR><HR><A NAME="1413"></A><H4>1413.
  
Missing cases of value-dependency
</H4><B>Section: </B>14.6.2.3&#160; [temp.dep.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2011-11-09<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>The list of cases in 14.6.2.3 [temp.dep.constexpr] paragraph 2
in which an <I>identifier</I> is value-dependent should also
include:</P>

<UL><LI><P>an entity with reference type and is initialized with
an expression that is value-dependent</P></LI>

<LI><P>a member function or a static data member of the current
instantiation</P></LI>

</UL>

<P><B>Proposed resolution (October, 2012):</B></P>

<OL><LI><P>Change 14.6.2.3 [temp.dep.constexpr] paragraph 2 as follows
and move the text following the bulleted list into a new paragraph:</P></LI>

<BLOCKQUOTE>

<P>An <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>identifier</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>id-expression</I></SPAN> is
value-dependent if <SPAN style="text-decoration:line-through;background-color:#FFA0A0">it is</SPAN>:</P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">it is</SPAN> a name declared with a dependent type,</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">it is</SPAN> the name of a non-type template parameter,</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">it names a member of an unknown specialization,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">it names a static data member of the current instantiation
that is not initialized in a <I>member-declarator</I>,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">it names a static member function that is a member of the
current instantiation, or</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">it is</SPAN> a constant with literal type and is
initialized with an expression that is value-dependent.</P></LI>

</UL>

<P>Expressions of the following form...</P>

</BLOCKQUOTE>

<LI><P>Change 14.6.2.3 [temp.dep.constexpr] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">An <I>id-expression</I> is value-dependent if it names a member
of an unknown specialization.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">An expression of the form
<TT>&amp;</TT><I>qualified-id</I> where the <I>qualified-id</I>'s
<I>nested-name-specifier</I> names the current instantiation is
value-dependent.</SPAN>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1532"></A><H4>1532.
  
Explicit instantiation and member templates
</H4><B>Section: </B>14.7.2&#160; [temp.explicit]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Johannes Schaub
 &#160;&#160;&#160;

 <B>Date: </B>2012-08-04<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>According to 14.7.2 [temp.explicit] paragraph 8,</P>

<BLOCKQUOTE>

An explicit instantiation that names a class template specialization
is also an explicit instantiation of the same kind (declaration or
definition) of each of its members (not including members inherited
from base classes) that has not been previously explicitly specialized
in the translation unit containing the explicit instantiation, except
as described below.

</BLOCKQUOTE>

<P>This could be read as an indication that member class templates
and member function templates are instantiated (as templates) when
their containing class template is instantiated.  For example,</P>

<PRE>
  template&lt;typename T&gt; struct A {
    template&lt;typename U&gt; void f() {
      T t;
      t.f();
    }
  };

  template struct A&lt;int&gt;;
</PRE>

<P>In this view, the result would be a member function template definition
in class <TT>A&lt;int&gt;</TT> equivalent to</P>

<PRE>
  template&lt;typename U&gt; void f() {
    int t;
    t.f();
  }
</PRE>

<P>Such a template could never be validly instantiated and thus would
presumably fall under the rule in 14.6 [temp.res] paragraph
8,</P>

<BLOCKQUOTE>

If no valid specialization can be generated for a template, and that
template is not instantiated, the template is ill-formed, no
diagnostic required.

</BLOCKQUOTE>

<P>The wording of 14.7.2 [temp.explicit] paragraph 1 appears not
to allow member templates to be instantiated as templates, however,
mentioning only a &#8220;member template specialization&#8221; as
a possibility:</P>

<BLOCKQUOTE>

A class, a function or member template specialization can be
explicitly instantiated from its template.  A member function, member
class or static data member of a class template can be explicitly
instantiated from the member definition associated with its class
template.

</BLOCKQUOTE>

<P>This appears to be a contradiction, and although a diagnostic for
a member template such as the example above would be helpful, most or
all current implementations do not do so.  Either the wording of
paragraph 1 should be changed to allow explicit instantiation of a
member template as a template, analogous to explicitly specializing
a member template as a template, or paragraph 8 should be clarified
to exclude member templates from the members explicitly instantiated
when the containing class template is explicitly instantiated.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 14.7.2 [temp.explicit] paragraph 8 as follows:</P>

<BLOCKQUOTE>

An explicit instantiation that names a class template specialization
is also an explicit instantiation of the same kind (declaration or
definition) of each of its members (not including members inherited
from base classes <SPAN style="font-weight:bold;background-color:#A0FFA0">and members that are templates</SPAN>) that has
not been previously explicitly specialized in the translation unit
containing the explicit instantiation, except as described
below. [<I>Note:</I> In addition, it will typically be an explicit
instantiation of certain implementation-dependent data about the
class.  &#8212;<I>end note</I>]

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1330"></A><H4>1330.
  
Delayed instantiation of <TT>noexcept</TT> specifiers
</H4><B>Section: </B>14.8.2&#160; [temp.deduct]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2011-06-05<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>See also issues <A HREF="
     cwg_closed.html#595">595</A> and
<A HREF="
     cwg_active.html#287">287</A>.</P>

<P>The use of <TT>noexcept</TT> specifiers can cause instantiation of
classes and functions that are not actually needed in the program,
just to be able to complete the declaration.  The actual value of the
expression in the <I>noexcept-specification</I> is only needed if the
function is defined (i.e., instantiated) or called, so it would
significantly reduce the number of instantiations (and avoid certain
kinds of errors when the value is currently required before a class is
complete) if <I>exception-specification</I>s were treated like default
arguments and only instantiated when they are actually needed.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<OL><LI><P>Change 14.5 [temp.decls] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

For purposes of name lookup and instantiation, default arguments
<SPAN style="font-weight:bold;background-color:#A0FFA0">and <I>exception-specification</I>s</SPAN> of function templates
and default arguments <SPAN style="font-weight:bold;background-color:#A0FFA0">and <I>exception-specification</I>s</SPAN>
of member functions of class templates are considered definitions;
each default argument <SPAN style="font-weight:bold;background-color:#A0FFA0">or <I>exception-specification</I></SPAN> is
a separate definition which is unrelated to the function template
definition or to any other default arguments <SPAN style="font-weight:bold;background-color:#A0FFA0">or
<I>exception-specification</I>s</SPAN>.

</BLOCKQUOTE>

<LI><P>Change 14.6 [temp.res] paragraph 11 as follows:</P></LI>

<BLOCKQUOTE>

[<I>Note:</I> For purposes of name lookup, default arguments <SPAN style="font-weight:bold;background-color:#A0FFA0">and
<I>exception-specification</I>s</SPAN> of function templates and
default arguments <SPAN style="font-weight:bold;background-color:#A0FFA0">and <I>exception-specification</I>s</SPAN> of
member functions of class templates are considered definitions
(14.5). &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Add a new paragraph following 14.6.4.1 [temp.point]
paragraph 2:</P></LI>

<BLOCKQUOTE>

<P>If a function template or member function of a class template is
called in a way which uses the definition of a default argument of
that function template or member function, the point of instantiation
of the default argument is the point of instantiation of the function
template or member function specialization.</P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">For an <I>exception-specification</I> of a function template
specialization or specialization of a member function of a class
template, if the <I>exception-specification</I> is implicitly
instantiated because it is needed by another template specialization
and the context that requires it depends on a template parameter, the
point of instantiation of the <I>exception-specification</I> is the
point of instantiation of the specialization that requires
it. Otherwise, the point of instantiation for such an
<I>exception-specification</I> immediately follows the namespace scope
declaration or definition that requires the
<I>exception-specification</I>.</SPAN></P>

</BLOCKQUOTE>

<LI><P>Change 14.7.1 [temp.inst] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...The implicit instantiation of a class template specialization
causes the implicit instantiation of the declarations, but not of the
definitions<SPAN style="font-weight:bold;background-color:#A0FFA0">,</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN> default arguments, <SPAN style="font-weight:bold;background-color:#A0FFA0">or
<I>exception-specification</I>s,</SPAN> of the class member functions,
member classes...

</BLOCKQUOTE>

<LI><P>Add a new paragraph following 14.7.1 [temp.inst]
paragraph 13:</P></LI>

<BLOCKQUOTE>

<P>Each default argument is instantiated independently. [<I>Example:</I>
... &#8212;<I>end example</I>]</P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">If the <I>exception-specification</I> of a specialization of a
function template or member function of a class template has not yet
been instantiated, but is needed (e.g., to instantiate the function
definition, to evaluate a <I>noexcept-expression</I> (5.3.7 [expr.unary.noexcept]), or to compare against the
<I>exception-specification</I> of another declaration), the dependent
names are looked up, the semantic constraints are checked, and the
instantiation of any template used in the
<I>exception-specification</I> is done as if it were being done as
part of instantiating the declaration of the specialization. An
<I>exception-specification</I> is not instantiated in order to calculate the
<I>exception-specification</I> of a defaulted function in a derived
class until the <I>exception-specification</I> of the derived member
function becomes necessary.</SPAN></P>

</BLOCKQUOTE>

<LI><P>Change the note 14.8.2 [temp.deduct] paragraph 7 as
follows:</P></LI>

<BLOCKQUOTE>

...[<I>Note:</I> The equivalent substitution in exception
specifications is done only when the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">function</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>exception-specification</I></SPAN> is instantiated, at which
point a program is ill-formed if the substitution results in an
invalid type or expression. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Add a new paragraph following 15.4 [except.spec]
paragraph 15:</P></LI>

<BLOCKQUOTE>

<P>A deallocation function (3.7.4.2 [basic.stc.dynamic.deallocation]) with no explicit
<I>exception-specification</I> is treated as if it were specified with
<TT>noexcept(true)</TT>.</P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">The <I>exception-specification</I> of a function template
specialization is not instantiated along with the function
declaration; it is instantiated when needed (14.7.1 [temp.inst]). The <I>exception-specification</I> of an
implicitly-declared special member function is also evaluated as
needed. [<I>Note:</I> Therefore, an implicit declaration of a member
function of a derived class does not require the
<I>exception-specification</I> of a base member function to be
instantiated. &#8212;<I>end note</I>] </SPAN></P>

</BLOCKQUOTE>

</OL>

<P><B>Notes from the February, 2012 meeting:</B></P>

<P>There should be a specific definition of when an
<I>exception-specification</I> is needed and must thus be instantiated.</P>

<P><B>Additional discussion (September, 2012):</B></P>

<P>Daveed Vandevoorde brought up two additional points.  First, the
rule should be crafted so that an example like the following is
ill-formed:</P>

<PRE>
  template&lt;class T&gt; T f() noexcept(sizeof(T) &lt; 4);

  int main() {
    decltype(f&lt;void&gt;()) *p;
  }
</PRE>

<P>Even though the <I>exception-specification</I> is not needed here,
it should be instantiated (because of the unevaluated reference to
<TT>f</TT>) in order to catch the ill-formed <TT>sizeof(T)</TT>.</P>

<P>In addition, the proposed change creates an asymmetry between class
templates and ordinary classes:</P>

<PRE>
  struct S {
    void f() noexcept(sizeof(g()) &lt; 8); //<SPAN style="font-family:Times;font-style:italic"> Invalid forward reference.</SPAN>
    static int g();
  };
</PRE>

<P>but</P>

<PRE>
  template&lt;typename&gt; struct X {
      void f() noexcept(sizeof(g()) &lt; 8); //<SPAN style="font-family:Times;font-style:italic"> Okay.</SPAN>
      static int g();
  };
</PRE>

<P>If the proposed change is adopted, the rules for
<I>exception-specification</I>s in ordinary classes should be revised
to make the parallel usage well-formed.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<OL><LI><P>Change 3.3.7 [basic.scope.class] paragraph 1 #1 as
follows:</P></LI>

<BLOCKQUOTE>

The potential scope of a name declared in a class consists not only of
the declarative region following the name's point of declaration, but
also of all function bodies, default arguments,
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>exception-specification</I>s,</SPAN> and
<I>brace-or-equal-initializer</I>s of non-static data members in that
class (including such things in nested classes).

</BLOCKQUOTE>

<LI><P>Change 3.4.1 [basic.lookup.unqual] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

A name used in the definition of a class <TT>X</TT> outside of a
member function body, default argument,
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>exception-specification,</I></SPAN>
<I>brace-or-equal-initializer</I> of a non-static data member, or
nested class definition<SUP>29</SUP> shall be declared in one of the
following ways:...

</BLOCKQUOTE>

<LI><P>Change 3.4.1 [basic.lookup.unqual] paragraph 8 as follows:</P></LI>

<BLOCKQUOTE>

For the members of a class <TT>X</TT>, a name used in a member
function body, in a default argument, <SPAN style="font-weight:bold;background-color:#A0FFA0">in an
<I>exception-specification</I>,</SPAN> in the
<I>brace-or-equal-initializer</I> of a non-static data member
(9.2 [class.mem]), or in the definition of a class member
outside of the definition of <TT>X</TT>, following the member's
<I>declarator-id</I><SUP>31</SUP> , shall be declared in one of the
following ways:...

</BLOCKQUOTE>

<LI><P>Change 9.2 [class.mem] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

A class is considered a completely-defined object type (3.9 [basic.types]) (or complete type) at the closing } of the
<I>class-specifier</I>.  Within the class <I>member-specification</I>,
the class is regarded as complete within function bodies, default
arguments, <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>exception-specification</I>s,</SPAN> and
<I>brace-or-equal-initializer</I>s for non-static data members
(including such things in nested classes). Otherwise it is regarded as
incomplete within its own class
<I>member-specification</I>.

</BLOCKQUOTE>

<LI><P>Change 14.5 [temp.decls] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

For purposes of name lookup and instantiation, default arguments
<SPAN style="font-weight:bold;background-color:#A0FFA0">and <I>exception-specification</I>s</SPAN> of function templates
and default arguments <SPAN style="font-weight:bold;background-color:#A0FFA0">and <I>exception-specification</I>s</SPAN>
of member functions of class templates are considered definitions;
each default argument <SPAN style="font-weight:bold;background-color:#A0FFA0">or <I>exception-specification</I></SPAN> is
a separate definition which is unrelated to the function template
definition or to any other default arguments <SPAN style="font-weight:bold;background-color:#A0FFA0">or
<I>exception-specification</I>s</SPAN>.

</BLOCKQUOTE>

<LI><P>Change 14.6 [temp.res] paragraph 11 as follows:</P></LI>

<BLOCKQUOTE>

[<I>Note:</I> For purposes of name lookup, default arguments <SPAN style="font-weight:bold;background-color:#A0FFA0">and
<I>exception-specification</I>s</SPAN> of function templates and
default arguments <SPAN style="font-weight:bold;background-color:#A0FFA0">and <I>exception-specification</I>s</SPAN> of
member functions of class templates are considered definitions
(14.5 [temp.decls]).  &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Add the following as a new paragraph after 14.6.4.1 [temp.point] paragraph 2:</P></LI>

<BLOCKQUOTE>

<P>If a function template or member function of a class template is
called in a way which uses the definition of a default argument of
that function template or member function, the point of instantiation
of the default argument is the point of instantiation of the function
template or member function specialization.</P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">For an <I>exception-specification</I> of a function template
specialization or specialization of a member function of a class
template, if the <I>exception-specification</I> is implicitly
instantiated because it is needed by another template specialization
and the context that requires it depends on a template parameter, the
point of instantiation of the <I>exception-specification</I> is the
point of instantiation of the specialization that requires
it. Otherwise, the point of instantiation for such an
<I>exception-specification</I> immediately follows the namespace scope
declaration or definition that requires the
<I>exception-specification</I>.</SPAN>
</P>

</BLOCKQUOTE>

<LI><P>Change 14.7.1 [temp.inst] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

Unless a class template specialization has been explicitly
instantiated (14.7.2 [temp.explicit]) or explicitly specialized
(14.7.3 [temp.expl.spec]), the class template specialization is
implicitly instantiated when the specialization is referenced in a
context that requires a completely-defined object type or when the
completeness of the class type affects the semantics of the program.
The implicit instantiation of a class template specialization causes
the implicit instantiation of the declarations, but not of the
definitions<SPAN style="font-weight:bold;background-color:#A0FFA0">,</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN> default arguments, <SPAN style="font-weight:bold;background-color:#A0FFA0">or
<I>exception-specification</I>s</SPAN> of the class member functions,
member classes, scoped member enumerations, static data members and
member templates; and it causes the implicit instantiation of the
definitions of unscoped member enumerations and member anonymous
unions.  However, for the purpose...

</BLOCKQUOTE>

<LI><P>Insert the following as a new paragraph immediately preceding
14.7.1 [temp.inst] paragraph 14:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">The <I>exception-specification</I> of a function template
specialization is not instantiated along with the function
declaration; it is instantiated when needed (15.4 [except.spec]). If such an <I>exception-specification</I> is needed but
has not yet been instantiated, the dependent names are looked up, the
semantics constraints are checked, and the instantiation of any
template used in the <I>exception-specification</I> is done as if it
were being done as part of instantiating the declaration of the
specialization at that point.</SPAN></P>

<P>[<I>Note:</I> 14.6.4.1 [temp.point] defines the point of
instantiation of a template specialization.  &#8212;<I>end note</I>]
</P>

</BLOCKQUOTE>

<LI><P>Change 14.8.2 [temp.deduct] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

The substitution occurs in all types and expressions that are used in
the function type and in template parameter declarations. The
expressions include not only constant expressions such as those that
appear in array bounds or as nontype template arguments but also
general expressions (i.e., non-constant expressions) inside sizeof,
decltype, and other contexts that allow non-constant expressions.
[<I>Note:</I> The equivalent substitution in exception specifications
is done only when the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">function</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>exception-specification</I></SPAN> is instantiated, at which
point a program is ill-formed if the substitution results in an
invalid type or expression.  &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Change 15.4 [except.spec] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

...A type denoted in an <I>exception-specification</I> shall not
denote an incomplete type <SPAN style="text-decoration:line-through;background-color:#FFA0A0">other than a class currently being
defined</SPAN>. A type denoted in an <I>exception-specification</I>
shall not denote a pointer or reference to an incomplete type, other
than <I>cv</I> <TT>void*</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or a pointer or reference to a
class currently being defined</SPAN>.  A type <I>cv</I> <TT>T</TT>,
&#8220;array of <TT>T</TT>&#8221;, or &#8220;function returning
<TT>T</TT>&#8221; denoted in an <I>exception-specification</I> is
adjusted to type <TT>T</TT>, &#8220;pointer to <TT>T</TT>&#8221;, or
&#8220;pointer to function returning <TT>T</TT>&#8221; respectively.

</BLOCKQUOTE>

<LI><P>Add the following as a new paragraph following
15.4 [except.spec] paragraph 15:</P></LI>

<BLOCKQUOTE>

<P>A deallocation function (3.7.4.2 [basic.stc.dynamic.deallocation]) with no
explicit <I>exception-specification</I> is treated as if it were
specified with <TT>noexcept(true)</TT>.</P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">An <I>exception-specification</I> is considered to be
<I>needed</I> when:</SPAN></P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">in an expression, the function is the unique lookup
result or the selected member of a set of overloaded functions
(3.4 [basic.lookup], 13.3 [over.match], 13.4 [over.over]);</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">the function is odr-used (3.2 [basic.def.odr]) or, if
it appears in an unevaluated operand, would be odr-used if the
expression were potentially-evaluated;</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">the <I>exception-specification</I> is compared to that of another
declaration (e.g. an explicit specialization or an overriding virtual
function);</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">the function is defined; or</SPAN></P></LI>

<LI>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">the <I>exception-specification</I> is needed for a defaulted special
member function that calls the function. [<I>Note:</I> A defaulted
declaration does not require the <I>exception-specification</I> of a
base member function to be evaluated until the implicit
<I>exception-specification</I> of the derived function is needed, but
an explicit <I>exception-specification</I> needs the implicit
<I>exception-specification</I> to compare
against. &#8212;<I>end note</I>]</SPAN></P></LI>

</UL><P><SPAN style="font-weight:bold;background-color:#A0FFA0">The <I>exception-specification</I> of a defaulted special member
function is evaluated as described above only when needed; similarly,
the <I>exception-specification</I> of a specialization of a function
template or member function of a class template is instantiated only
when needed.</SPAN></P>

</BLOCKQUOTE>

</OL>

<P><I>[Note: this resolution reverses the decision in
<A HREF="
     cwg_defects.html#1308">issue 1308</A>.]</I></P>

<BR><BR><HR><A NAME="1462"></A><H4>1462.
  
Deduction failure vs &#8220;ill-formed, no diagnostic required&#8221;
</H4><B>Section: </B>14.8.2&#160; [temp.deduct]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>2012-02-08<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>

<P>The relationship between errors that render a program ill-formed
but for which no diagnostic is required and things that cause deduction
failure is not clearly specified.  Presumably failures that need not
be diagnosed cannot be the basis for SFINAE, lest different implementations
perform deduction differently depending on how thoroughly they handle
such cases.  This should be spelled out explicitly.</P>

<P><B>Proposed resolution (October, 2012):</B></P>

<P>Change 14.8.2 [temp.deduct] paragraph 8 as follows:</P>

<BLOCKQUOTE>

If a substitution results in an invalid type or expression, type
deduction fails. An invalid type or expression is one that would be
ill-formed<SPAN style="font-weight:bold;background-color:#A0FFA0">, with a diagnostic required,</SPAN> if written using
the substituted arguments. [<I>Note:</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">If no diagnostic is
required, the program is still ill-formed.</SPAN> Access checking is
done as part of the substitution process.  &#8212;<I>end note</I>]
Only invalid types and expressions...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1503"></A><H4>1503.
  
Exceptions during copy to exception object
</H4><B>Section: </B>15.1&#160; [except.throw]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2012-05-11<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>



<P>According to 15.1 [except.throw] paragraph 7,</P>

<BLOCKQUOTE>

If the exception handling mechanism, after completing evaluation of
the expression to be thrown but before the exception is caught, calls
a function that exits via an exception, <TT>std::terminate</TT> is
called (15.5.1 [except.terminate]).

</BLOCKQUOTE>

<P>This wording was overlooked in the resolution for <A HREF="
     cwg_defects.html#475">issue 475</A> and should be changed, along with the
following example, to indicate that <TT>std::terminate</TT> will be
called for an uncaught exception only after initialization of the
exception object is complete.</P>

<P><B>Proposed resolution (August, 2012):</B></P>

<P>Change 15.1 [except.throw] paragraph 7 as follows:</P>

<BLOCKQUOTE>

<P>If the exception handling mechanism, after completing <SPAN style="text-decoration:line-through;background-color:#FFA0A0">evaluation
of the expression to be thrown</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">the initialization of the
exception object</SPAN> but before the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">exception is caught</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">activation of a handler for the exception</SPAN>, calls a function
that exits via an exception, <TT>std::terminate</TT> is called
(15.5.1 [except.terminate]). [<I>Example:</I></P>

<PRE>
  struct C {
    C() { }
    C(const C&amp;) { <SPAN style="text-decoration:line-through;background-color:#FFA0A0">throw 0; }</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">      if (std::uncaught_exception()) {
        throw 0;    //<SPAN style="font-family:Times;font-style:italic"> throw during copy to handler's exception-declaration object (15.3 [except.handle])</SPAN>
      }
    }</SPAN>
  };

  int main() {
    try {
      throw C();   //<SPAN style="font-family:Times;font-style:italic"> calls </SPAN>std::terminate()<SPAN style="font-family:Times;font-style:italic"><SPAN style="font-weight:bold;background-color:#A0FFA0"> if construction of the handler's</SPAN></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">                   //<SPAN style="font-family:Times;font-style:italic"> exception-declaration object is not elided (12.8 [class.copy])</SPAN></SPAN>
    } catch(C) { }
  }
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="223"></A><H4>223.
  
The meaning of deprecation
</H4><B>Section: </B>D&#160; [depr]
 &#160;&#160;&#160;

 <B>Status: </B>DR
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>19 Apr 2000<BR>


<P>[Moved to DR at the April, 2013 meeting.]</P>

<P>During the discussion of issues <A HREF="
     cwg_closed.html#167">167</A> and
<A HREF="
     cwg_closed.html#174">174</A>, it became apparent that there was no
consensus on the meaning of deprecation.  Some thought that
deprecating a feature reflected an intent to remove it from
the language.  Others viewed it more as an encouragement to
programmers not to use certain constructs, even though they might be
supported in perpetuity.</P>

<P>There is a formal-sounding definition of deprecation in Annex
D [depr] paragraph 2:

<BLOCKQUOTE>

deprecated is defined as: Normative for the current edition of the
Standard, but not guaranteed to be part of the Standard in future
revisions.

</BLOCKQUOTE>

However, this definition would appear to say that any
non-deprecated feature <I>is</I> "guaranteed to be part of the
Standard in future revisions."  It's not clear that that implication
was intended, so this definition may need to be amended.
</P>

<P>This issue is intended to provide an avenue for discussing and
resolving those questions, after which the original issues may be
reopened if that is deemed desirable.</P>

<P><B>Proposed resolution (August, 2012):</B></P>

<P>Change D [depr] paragraph 2 as follows:</P>

<BLOCKQUOTE>

These are deprecated features, where <I>deprecated</I> is defined as:
Normative for the current edition of the Standard, but <SPAN style="text-decoration:line-through;background-color:#FFA0A0">not guaranteed
to be part of the Standard in</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">having been identified as a
candidate for removal from</SPAN> future revisions.

</BLOCKQUOTE>

<BR><BR><BR><BR><HR><A NAME="Accepted Status"></A><H3>Issues with "accepted" Status</H3>
<HR><A NAME="1464"></A><H4>1464.
  
Negative array bound in a <I>new-expression</I>
</H4><B>Section: </B>5.3.4&#160; [expr.new]
 &#160;&#160;&#160;

 <B>Status: </B>accepted
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>2012-02-12<BR>


<P>[Accepted at the April, 2013 meeting.]</P>



<P>Currently, 5.3.4 [expr.new] paragraph 7 requires that an
attempt to allocate an array with a negative length be diagnosed:</P>

<BLOCKQUOTE>

If the value of that <I>expression</I> is less than zero or such that
the size of the allocated object would exceed the
implementation-defined limit, or if the <I>new-initializer</I> is a
<I>braced-init-list</I> for which the number of
<I>initializer-clause</I>s exceeds the number of elements to
initialize, no storage is obtained and the <I>new-expression</I>
terminates by throwing an exception of a type that would match a
handler (15.3 [except.handle]) of type
<TT>std::bad_array_new_length</TT> (18.6.2.3 [new.badlength]).

</BLOCKQUOTE>

<P>Checking for a negative bound will be lost, however, upon the
adoption of paper N3323, as the <I>expression</I> will be converted to
<TT>std::size_t</TT>, an unsigned type.  Although the result of this
conversion will likely also cause the check to fail (and will always
do so when scaled by an element size larger than 1), it is not
inconceivable that an implementation could provide a heap that capable
of providing more than half the addressable range of
<TT>std::size_t</TT>, and a request for a character array (with an
element size of 1) with a negative bound close to <TT>LONG_MIN</TT>
(assuming <TT>std::size_t</TT> is <TT>unsigned long</TT>) might
actually succeed.</P>

<P>The wording of 5.3.4 [expr.new] paragraph 7 should be
changed so that the test for a negative bound is applied to the
value before conversion to <TT>std::size_t</TT>, or some other
mechanism should be invented to preserve the check for a negative
bound.</P>

<P><B>Additional note (August, 2012):</B></P>

<P>The goal for addressing this issue should be that an attempt to use
an invalid bound (negative, greater than the maximum allowed, or more
than the number implied by the initializer) will be ill-formed when
the bound is a compile-time constant and will result in an exception
otherwise. </P>

<P><B>Proposed resolution (October, 2012):</B></P>

<OL><LI><P>Change 3.9.2 [basic.compound] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

These methods of constructing types can be applied recursively;
restrictions are mentioned in 8.3.1 [dcl.ptr], 8.3.4 [dcl.array], 8.3.5 [dcl.fct], and 8.3.2 [dcl.ref]. <SPAN style="font-weight:bold;background-color:#A0FFA0">Constructing a type such that the number of bytes
in its object representation exceeds the maximum value representable
in the type <TT>std::size_t</TT> (18.2 [support.types]) is
ill-formed.</SPAN>

</BLOCKQUOTE>

<LI><P>Change 5.3.4 [expr.new] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">The <I>expression</I> in a <I>noptr-new-declarator</I> is
erroneous if:</SPAN></P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">the expression is of non-class type and its value
before converting to <TT>std::size_t</TT> is less than
zero;</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">the expression is of class type and its value before
application of the second standard conversion (13.3.3.1.2 [over.ics.user]) [<I>Footnote:</I> If the conversion function
returns a signed integer type, the second standard conversion converts
to the unsigned type <TT>std::size_t</TT> and thus thwarts any attempt
to detect a negative value afterwards. &#8212;<I>end footnote</I>] is
less than zero;</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">its value is such that the size of the allocated object
would exceed the implementation-defined limit (annex B [implimits]); or</SPAN></P></LI>

<LI>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">the <I>new-initializer</I> is a <I>braced-init-list</I> and
the number of array elements for which initializers are provided
(including the terminating <TT>'\0'</TT> in a string literal
(2.14.5 [lex.string])) exceeds the number of elements to
initialize.</SPAN>
</P></LI>

</UL><P><SPAN style="font-weight:bold;background-color:#A0FFA0">If the <I>expression</I>, after converting to
<TT>std::size_t</TT>, is a core constant expression and the expression
is erroneous, the program is ill-formed. Otherwise, a
<I>new-expression</I> with an erroneous expression does not call an
allocation function and terminates by throwing an exception of a type
that would match a handler (15.3 [except.handle]) of type
<TT>std::bad_array_new_length</TT> (18.6.2.3 [new.badlength]).</SPAN> When the value of the <I>expression</I>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">in a <I>noptr-new-declarator</I></SPAN> is zero, the allocation
function is called to allocate an array with no elements.  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">If the
value of that <I>expression</I> is less than zero or such that the
size of the allocated object would exceed the implementation-defined
limit, or if the <I>new-initializer</I> is a
<I>braced-init-list</I> for which the number of
<I>initializer-clause</I>s exceeds the number of elements to
initialize, no storage is obtained and the <I>new-expression</I>
terminates by throwing an exception of a type that would match a
handler (15.3 [except.handle]) of type
<TT>std::bad_array_new_length</TT> (18.6.2.3 [new.badlength]).</SPAN></P>

</BLOCKQUOTE>

</OL>

<P>(This resolution also resolves <A HREF="
     cwg_defects.html#1559">issue 1559</A>.)</P>

<BR><BR><HR><A NAME="1597"></A><H4>1597.
  
Misleading <TT>constexpr</TT> example
</H4><B>Section: </B>7.1.5&#160; [dcl.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>accepted
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>2012-12-21<BR>


<P>[Addressed by the adoption of paper N3652 at the April, 2013 meeting.]</P>

<P>One of the examples in 7.1.5 [dcl.constexpr] paragraph 3 reads,</P>

<PRE>
  constexpr int prev(int x)
    { return --x; }      //<SPAN style="font-family:Times;font-style:italic"> error: use of decrement</SPAN>
</PRE>

<P>According to paragraph 5, this ill-formed, no diagnostic required:</P>

<BLOCKQUOTE>

For a constexpr function, if no function argument values exist such
that the function invocation substitution would produce a constant
expression (5.19 [expr.const]), the program is ill-formed; no
diagnostic required.

</BLOCKQUOTE>

<P>However, the surrounding errors in the example have required
diagnostics, potentially leading the reader to the mistaken
conclusion that this error must be diagnosed as well.  The example
should be removed or the comment updated to reflect its true status.</P>

<P><B>Proposed resolution (June, 2013):</B></P>

<P>This issue is no longer relevant after the adoption of the changes
to <TT>constexpr</TT> in paper N3652.</P>

<BR><BR><BR><BR><HR><A NAME="DRWP Status"></A><H3>Issues with "DRWP" Status</H3>
<HR><A NAME="912"></A><H4>912.
  
Character literals and <I>universal-character-name</I>s
</H4><B>Section: </B>2.14.3&#160; [lex.ccon]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>7 June, 2009<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>

<P>According to 2.14.3 [lex.ccon] paragraph 1,</P>

<BLOCKQUOTE>

A character literal that does not begin with <TT>u</TT>, <TT>U</TT>,
or <TT>L</TT> is an ordinary character literal, also referred to as a
narrow-character literal.  An ordinary character literal that contains
a single <I>c-char</I> has type <TT>char</TT>, with value equal to the
numerical value of the encoding of the c-char in the execution
character set.

</BLOCKQUOTE>

<P>However, the definition of <I>c-char</I> includes as one
possibility a <I>universal-character-name</I>.  The value of a
<I>universal-character-name</I> cannot, in general, be represented
as a <TT>char</TT>, so this specification is impossible to
satisfy.</P>

<P>(See also <A HREF="
     cwg_active.html#411">issue 411</A> for related
questions.)</P>

<P><B>Additional note (February, 2012):</B></P>

<P>See the discussion in <A HREF="
     cwg_closed.html#1422">issue 1422</A> for a
possible interpretation of the existing text.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 2.14.3 [lex.ccon] paragraph 1 as follows:</P>

<BLOCKQUOTE>

...A character literal that does not begin with <TT>u</TT>,
<TT>U</TT>, or <TT>L</TT> is an ordinary character literal, also
referred to as a narrow-character literal.  An ordinary character
literal that contains a single <I>c-char</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">representable in
the execution character set</SPAN> has type <TT>char</TT>,
with value equal to the numerical value of the encoding of the
<I>c-char</I> in the execution character set. An ordinary character
literal that contains more than one <I>c-char</I> is a
<I>multicharacter literal</I>.  A multicharacter literal<SPAN style="font-weight:bold;background-color:#A0FFA0">, or an
ordinary character literal containing a single <I>c-char</I> not
representable in the execution character set, is
conditionally-supported,</SPAN> has type <TT>int</TT><SPAN style="font-weight:bold;background-color:#A0FFA0">,</SPAN> and
<SPAN style="font-weight:bold;background-color:#A0FFA0">has an</SPAN> implementation-defined value.

</BLOCKQUOTE>

<P>This resolution also resolves <A HREF="
     cwg_defects.html#1024">issue 1024</A>.</P>

<BR><BR><HR><A NAME="1024"></A><H4>1024.
  
Limits on multicharacter literals
</H4><B>Section: </B>2.14.3&#160; [lex.ccon]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>2010-01-31<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>

<P>There is no limit placed on the number of <I>c-char</I>s in a
multicharacter literal or a wide-character literal containing
multiple <I>c-char</I>s, either in 2.14.3 [lex.ccon]
paragraphs 1-2 or in Annex B [implimits].  Presumably
this means that an implementation must accept arbitrarily long
literals.</P>

<P>An alternative approach might be to state that these literals
are conditionally supported with implementation-defined semantics,
allowing an implementation to impose a documented limit that
makes sense for the particular architecture.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#912">issue 912</A>.</P>

<BR><BR><HR><A NAME="712"></A><H4>712.
  
Are integer constant operands of a <I>conditional-expression</I> &#8220;used?&#8221;
</H4><B>Section: </B>3.2&#160; [basic.def.odr]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>9 September, 2008<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>

<P>In describing static data members initialized inside the class
definition, 9.4.2 [class.static.data] paragraph 3 says,</P>

<BLOCKQUOTE>

The member shall still be defined in a namespace scope if it is
used in the program...

</BLOCKQUOTE>

<P>The definition of &#8220;used&#8221; is in 3.2 [basic.def.odr]
paragraph 1:</P>

<BLOCKQUOTE>

An object or non-overloaded function whose name appears as a
potentially-evaluated expression is <I>used</I> unless it is an
object that satisfies the requirements for appearing in a
constant expression (5.19 [expr.const]) and the
lvalue-to-rvalue conversion (4.1 [conv.lval]) is
immediately applied.

</BLOCKQUOTE>

<P>Now consider the following example:</P>

<PRE>
    struct S {
      static const int a = 1;
      static const int b = 2;
    };
    int f(bool x) {
      return x ? S::a : S::b;
    }
</PRE>

<P>According to the current wording of the Standard, this example
requires that <TT>S::a</TT> and <TT>S::b</TT> be defined in a
namespace scope.  The reason for this is that, according to
5.16 [expr.cond] paragraph 4, the result of this
<I>conditional-expression</I> is an lvalue and the
lvalue-to-rvalue conversion is applied to that, not directly
to the object, so this fails the &#8220;immediately applied&#8221;
requirement.  This is surprising and unfortunate, since only the
values and not the addresses of the static data members are used.
(This problem also applies to the proposed resolution of
<A HREF="
     cwg_defects.html#696">issue 696</A>.)</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Divide 3.2 [basic.def.odr] paragraph 2 into two paragraphs
and change as follows:</P>

<P>An expression is <I>potentially evaluated</I> unless it is an
unevaluated operand (Clause 5) or a subexpression thereof. <SPAN style="font-weight:bold;background-color:#A0FFA0">The
<I>set of potential results</I> of an expression <TT>e</TT> is defined
as:</SPAN></P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">if <TT>e</TT> is an <I>id-expression</I>
(5.1.1 [expr.prim.general]), the set whose sole member is
<TT>e</TT>,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">if <TT>e</TT> is a class member access
(5.2.5 [expr.ref]), the set of potential results of the
object expression,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">if <TT>e</TT> is a pointer-to-member expression
(5.5 [expr.mptr.oper]) whose second operand is a constant
expression, the set of potential results of the object
expression,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">if <TT>e</TT> has the form <TT>(e1)</TT>, the set of
potential results of <TT>e1</TT>,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">if <TT>e</TT> is a glvalue conditional expression
(5.16 [expr.cond]), the union of the sets of potential
results of the second and third operands,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">if <TT>e</TT> is a comma expression
(5.18 [expr.comma]), the set of potential results of the
right operand,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">otherwise, the empty set.</SPAN></P></LI>

</UL>

<P>A variable <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>x</TT></SPAN> whose name appears as a
potentially-evaluated expression <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>ex</TT></SPAN> is
<I>odr-used</I> unless <SPAN style="text-decoration:line-through;background-color:#FFA0A0">it</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>x</TT></SPAN> is an
object that satisfies the requirements for appearing in a constant
expression (5.19 [expr.const]) and <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>ex</TT> is an
element of the set of potential results of an expression <TT>e</TT>,
where either</SPAN> the lvalue-to-rvalue conversion (4.1 [conv.lval]) is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">immediately</SPAN> applied <SPAN style="font-weight:bold;background-color:#A0FFA0">to <TT>e</TT>, or
<TT>e</TT> is a discarded-value expression (Clause 5 [expr])</SPAN>. <TT>this</TT> is odr-used...</P>

<I>[Drafting note: this wording requires <TT>S::a</TT> to be defined
if it is used in an expression like <TT>*&amp;S::a</TT>.]</I>

<BR><BR><HR><A NAME="1260"></A><H4>1260.
  
Incorrect use of term &#8220;overloaded&#8221; in description of odr-use
</H4><B>Section: </B>3.2&#160; [basic.def.odr]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Nikolay Ivchenkov
 &#160;&#160;&#160;

 <B>Date: </B>2011-03-11<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>The current wording of 3.2 [basic.def.odr] paragraph 2 uses
the term &#8220;overloaded&#8221; differently from its definition in
13 [over] paragraph 1.  For example, names found by
argument-dependent lookup are not &#8220;overloaded&#8221; if they are
not declared in the same scope.  The phrasing should be reconciled
between the two sections.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 3.2 [basic.def.odr] paragraph 2 as follows:</P>

<BLOCKQUOTE>

...A <SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-overloaded</SPAN> function whose name appears as a
potentially-evaluated expression <SPAN style="font-weight:bold;background-color:#A0FFA0">is odr-used if it is the unique
lookup result or it is the selected</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or a</SPAN> member of a
set of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">candidate</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">overloaded</SPAN> functions
<SPAN style="font-weight:bold;background-color:#A0FFA0">(3.4 [basic.lookup], 13.3 [over.match],
13.4 [over.over])</SPAN><SPAN style="text-decoration:line-through;background-color:#FFA0A0">, if selected by overload
resolution when referred to from a potentially-evaluated expression,
is odr-used</SPAN>, unless it is a pure virtual function and its name
is not explicitly qualified...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1362"></A><H4>1362.
  
Complete type required for implicit conversion to <TT>T&amp;</TT>
</H4><B>Section: </B>3.2&#160; [basic.def.odr]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-16<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>The requirement in 3.2 [basic.def.odr] paragraph 4 that a
type <TT>T</TT> must be complete if an expression is implicitly
converted to a pointer to <TT>T</TT> or reference to <TT>T</TT>
inadvertently applies to user-defined conversions, although it was
intended only to refer to built-in conversions.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change the indicated bullet of 3.2 [basic.def.odr] paragraph 4
as follows:</P>

<UL><LI><P>an expression that is not a null pointer constant, and has
type other than <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>cv</I></SPAN> <TT>void*</TT>, is converted to
the type pointer to <TT>T</TT> or reference to <TT>T</TT> using
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">an implicit</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">a standard</SPAN> conversion (Clause
4 [conv]), a <TT>dynamic_cast</TT> (5.2.7 [expr.dynamic.cast]) or a <TT>static_cast</TT> (5.2.9 [expr.static.cast]),
or</P></LI></UL>

<BR><BR><HR><A NAME="1352"></A><H4>1352.
  
Inconsistent class scope and completeness rules
</H4><B>Section: </B>3.3.7&#160; [basic.scope.class]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-16<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>The rules regarding class scope and when the class is considered to
be complete (normally implemented by deferred parsing of portions of
class member declarations) are inconsistent and need to be clarified.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<OL><LI><P>Change 3.3.7 [basic.scope.class] paragraph 1 as follows:</P></LI>

<OL><LI>The potential scope of a name declared in a class consists not
only of the declarative region following the name's point of
declaration, but also of all function bodies, <SPAN style="font-weight:bold;background-color:#A0FFA0">default arguments, and</SPAN>
<I>brace-or-equal-initializer</I>s of non-static data members<SPAN style="text-decoration:line-through;background-color:#FFA0A0">,
and default arguments</SPAN> in that class (including such things in
nested classes).</LI></OL>

<LI><P>Change 3.4.1 [basic.lookup.unqual] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

A name used in the definition of a class X outside of a member
function body<SPAN style="font-weight:bold;background-color:#A0FFA0">, default argument,
<I>brace-or-equal-initializer</I> of a non-static data member,</SPAN>
or nested class definition<SUP>29</SUP> shall be declared in one of
the following ways:...

</BLOCKQUOTE>

<LI><P>Change 3.4.1 [basic.lookup.unqual] paragraph 8 as follows:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">For the members of a class <TT>X</TT>, a</SPAN> name
used <SPAN style="font-weight:bold;background-color:#A0FFA0">in a member function body, in a default argument, in the
<I>brace-or-equal-initializer</I> of a non-static data member
(9.2 [class.mem]), or</SPAN> in the definition of a
<SPAN style="font-weight:bold;background-color:#A0FFA0">class</SPAN> member <SPAN style="text-decoration:line-through;background-color:#FFA0A0">function (9.3 [class.mfct]) of
class <TT>X</TT></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">outside of the definition of
<TT>X</TT>,</SPAN> following the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">function's</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">member's</SPAN> <I>declarator-id</I> [<I>Footnote:</I> That is, an
unqualified name that occurs, for instance, in a type <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or default
argument</SPAN> in the <I>parameter-declaration-clause</I> or in the
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">function
body</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>exception-specification</I></SPAN>. &#8212;<I>end
footnote</I>]<SPAN style="font-weight:bold;background-color:#A0FFA0">,</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or in the
<I>brace-or-equal-initializer</I> of a non-static data member
(9.2 [class.mem]) of class <TT>X</TT></SPAN> shall be declared
in one of the following ways:...

</BLOCKQUOTE>

</OL>

<I>[Drafting note: 9.2 [class.mem] paragraph 2 requires no
changes.  3.3.7 [basic.scope.class] paragraph 1 bullet 5 deals with
out-of-class definitions, and bullet 2 ensures that the lookup results
for argument types are the same for in-class and out-of-class
declarations, so no change is required.]</I>

<BR><BR><HR><A NAME="1415"></A><H4>1415.
  
Missing prohibition of block-scope definition of <TT>extern</TT> object
</H4><B>Section: </B>3.5&#160; [basic.link]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2011-11-13<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>There does not appear to be wording that prohibits a block-scope
<TT>extern</TT> object declaration from being a definition.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Add the following as a new paragraph following 8.5 [dcl.init]
paragraph 4:</P>

<BLOCKQUOTE>

<P>[<I>Note:</I> Default arguments are more restricted; see
8.3.6 [dcl.fct.default].</P>

<P>The order of initialization of variables with static storage
duration is described in 3.6 [basic.start] and
6.7 [stmt.dcl]. &#8212;<I>end note</I>]</P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">A declaration of a block-scope variable with external or
internal linkage that has an <I>initializer</I> is
ill-formed.</SPAN></P>

<P>To <I>zero-initialize</I> an object...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1003"></A><H4>1003.
  
Acceptable definitions of <TT>main</TT>
</H4><B>Section: </B>3.6.1&#160; [basic.start.main]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2009-11-17<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>The specification of the forms of the definition of <TT>main</TT>
that an impliementation is required to accept is clear in C99 that
the parameter names and the exact syntactic form of the types can
vary.  Although it is reasonable to assume that a C++ implementation
would accept a definition like</P>

<PRE>
    int main(int foo, char** bar) { /* ... */ }
</PRE>

<P>instead of the canonical</P>

<PRE>
    int main(int argc, char* argv[]) { /* ... */ }
</PRE>

<P>it might be a good idea to clarify the intent using wording
similar to C99's.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 3.6.1 [basic.start.main] paragraph 2 as follows:</P>

<BLOCKQUOTE>

<P>...All implementations shall
allow both <SPAN style="text-decoration:line-through;background-color:#FFA0A0">of the following definitions of <TT>main</TT>:</SPAN></P>

<PRE>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">  int main() { /* ... */ }</SPAN>
</PRE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">and</SPAN></P>

<PRE>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">  int main(int argc, char* argv[]) { /* ... */ }</SPAN>
</PRE>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">function of <TT>()</TT> returning <TT>int</TT>
and</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">function of <TT>(int,</TT> pointer to pointer to
<TT>char)</TT> returning <TT>int</TT></SPAN></P></LI>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">as the type of <TT>main</TT> (8.3.5 [dcl.fct].</SPAN> In the latter form<SPAN style="font-weight:bold;background-color:#A0FFA0">, for purposes of
exposition, the first function parameter is called <TT>argc</TT> and
the second function parameter is called <TT>argv</TT>, where</SPAN>
<TT>argc</TT> shall be the number of arguments...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1438"></A><H4>1438.
  
Non-dereference use of invalid pointers
</H4><B>Section: </B>3.7.4.3&#160; [basic.stc.dynamic.safety]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Anthony Williams
 &#160;&#160;&#160;

 <B>Date: </B>2012-01-03<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>The current Standard says that any use of an invalid pointer value
produces undefined behavior (3.7.4.2 [basic.stc.dynamic.deallocation] paragraph 4).
This includes not only dereferencing the pointer but even just
fetching its value.  The reason for this draconian restriction is that
some architectures in the past used dedicated address registers for
pointer loads and stores and they could fault if, for example, a
segment number in a pointer was not currently mapped.</P>

<P>It is not clear whether such restrictions are necessary with
architectures currently in use or reasonably foreseen.  This should
be investigated to see if the restriction can be loosened to apply
only to dereferencing the pointer.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 3.7.4.2 [basic.stc.dynamic.deallocation] paragraph 4 as follows:</P>

<BLOCKQUOTE>

If the argument given to a deallocation function in the standard
library is a pointer that is not the null pointer value (4.10 [conv.ptr]), the deallocation function shall deallocate the storage
referenced by the pointer, rendering invalid all pointers referring to
any part of the <I>deallocated storage</I>.  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The effect of using
an invalid pointer value (including passing it to a deallocation
function) is undefined</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Indirection through an invalid
pointer value and passing an invalid pointer value to a deallocation
function have undefined behavior. Any other use of an invalid pointer
value has implementation-defined behavior</SPAN>. [<I>Footnote:</I>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">On some</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Some</SPAN> implementations<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, it</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">might define that copying an invalid pointer value</SPAN> causes a
system-generated runtime fault.  &#8212;<I>end footnote</I>]

</BLOCKQUOTE>

<BR><BR><HR><A NAME="597"></A><H4>597.
  
Conversions applied to out-of-lifetime non-POD lvalues
</H4><B>Section: </B>3.8&#160; [basic.life]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>27 September 2006<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>

<P>An lvalue referring to an out-of-lifetime non-POD class objects can
be used in limited ways, subject to the restrictions in
3.8 [basic.life] paragraph 6:</P>

<BLOCKQUOTE>

if the original object will be or was of a non-POD class type, the
program has undefined behavior if:

<UL>
<LI><P>the lvalue is used to access a non-static data member or call a
non-static member function of the object, or</P></LI>

<LI><P>the lvalue is implicitly converted (4.10 [conv.ptr])
to a reference to a base class type, or</P></LI>

<LI><P>the lvalue is used as the operand of a <TT>static_cast</TT>
(5.2.9 [expr.static.cast]) except when the conversion is
ultimately to <I>cv</I> <TT>char&amp;</TT> or <I>cv</I> <TT>unsigned
char&amp;</TT> ), or</P></LI>

<LI><P>the lvalue is used as the operand of a <TT>dynamic_cast</TT>
(5.2.7 [expr.dynamic.cast]) or as the operand
of <TT>typeid</TT>.</P></LI>
</UL>

</BLOCKQUOTE>

<P>There are at least a couple of questionable things in this list.
First, there is no &#8220;implicit conversion to a reference to a
base class,&#8221; as assumed by the second bullet.  Presumably
this is intended to say that the lvalue is bound to a reference to
a base class, and the cross-reference should be to
8.5.3 [dcl.init.ref], not to 4.10 [conv.ptr]
(which deals with pointer conversions).  However, even given that
adjustment, it is not clear why it is forbidden to bind a reference
to a non-virtual base class of an out-of-lifetime object, as that is
just an address offset calculation.  (Binding to a virtual base, of
course, would require access to the value of the object and thus
cannot be done outside the object's lifetime.)</P>

<P>The third bullet also appears questionable.  It's not clear why
<TT>static_cast</TT> is discussed at all here, as the only
permissible <TT>static_cast</TT> conversions involving reference types
and non-POD classes are to references to base or derived classes and
to the same type, modulo cv-qualification; if implicit
&#8220;conversion&#8221; to a base class reference is forbidden in the
second bullet, why would an explicit conversion be permitted in the
third?  Was this intended to refer to
<TT>reinterpret_cast</TT>?  Also, is there a reason to allow char
types but disallow array-of-char types (which are more likely to be
useful than a single char)?</P>

<P><B>Proposed resolution (March, 2008):</B></P>

<OL>
<LI><P>Change 3.8 [basic.life] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

<P>...If the object will be or was of a non-trivial class type,
the program has undefined behavior if:</P>

<UL>
<LI><P>the pointer is used to access a non-static data member or
call a non-static member function of the object, or</P></LI>

<LI><P>the pointer is implicitly converted (<secion_ref ref="4.10">4.10 [conv.ptr]</secion_ref>) to a pointer to a <SPAN style="font-weight:bold;background-color:#A0FFA0">virtual</SPAN> base class
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">type</SPAN>, or</P></LI>

<LI><P>the pointer is used as the operand of a <TT>static_cast</TT>
(5.2.9 [expr.static.cast]) <SPAN style="text-decoration:line-through;background-color:#FFA0A0">(</SPAN>except when the conversion is
to <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>void*</TT>, or to <TT>void*</TT> and subsequently to
<TT>char*</TT>, or <TT>unsigned char*</TT>).</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">pointer to
<I>cv</I> <TT>void</TT>, or to pointer to <I>cv</I> <TT>void</TT> and
subsequently to pointer to <I>cv</I> <TT>char</TT> or pointer to
<I>cv</I> <TT>unsigned char</TT>, or</SPAN></P></LI>

<LI><P>the pointer is used as the operand of a <TT>dynamic_cast</TT>
(5.2.7 [expr.dynamic.cast])...</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 3.8 [basic.life] paragraph 6 as follows:
</P></LI>

<BLOCKQUOTE>

<P>...if the original object will be or was of a non-trivial
class type, the program has undefined behavior if:</P>

<UL>
<LI><P>the lvalue is used to access a non-static data member or
call a non-static member function of the object, or</P></LI>

<LI><P>the lvalue is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">implicitly converted (4.10 [conv.ptr])</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">bound</SPAN> to a reference to a <SPAN style="font-weight:bold;background-color:#A0FFA0">virtual</SPAN>
base class <SPAN style="text-decoration:line-through;background-color:#FFA0A0">type</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">(8.5.3 [dcl.init.ref])</SPAN>,
or</P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">the lvalue is used as the operand of a
<TT>static_cast</TT> (5.2.9 [expr.static.cast]) except when the
conversion is ultimately to <I>cv</I> <TT>char&amp;</TT> or
<I>cv</I> <TT>unsigned char&amp;</TT>, or</SPAN></P></LI>

<LI><P>the lvalue is used as the operand of a
<TT>dynamic_cast</TT> (5.2.7 [expr.dynamic.cast]) or as the
operand of <TT>typeid</TT>.</P></LI>

</UL>

</BLOCKQUOTE>

</OL>

<P><I>[Drafting notes: Paragraph 5 was changed to track the
changes to paragraph 6.  See also the resolution for <A HREF="
     cwg_defects.html#658">issue 658</A>.]</I></P>

<BR><BR><HR><A NAME="1453"></A><H4>1453.
  
Volatile members in literal classes?
</H4><B>Section: </B>3.9&#160; [basic.types]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2012-01-02<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>Can a literal class have a volatile member?  For example,</P>

<PRE>
   struct S {
     constexpr S() : n(0) { }
     volatile int n;
   };

   constexpr S s;   // causes volatile write to S::n
</PRE>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 3.9 [basic.types] paragraph 10 as follows:</P>

<BLOCKQUOTE>

<P>A type is a <I>literal type</I> if it is:</P>

<UL><LI><P>...</P></LI>

<LI><P>a class type (Clause 9 [class]) that has all the
following properties:</P></LI>

<UL><LI><P>...</P></LI>

<LI><P>all of its non-static data members and base classes are of
<SPAN style="font-weight:bold;background-color:#A0FFA0">non-volatile</SPAN> literal types.</P></LI>

</UL>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="483"></A><H4>483.
  
Normative requirements on integral ranges
</H4><B>Section: </B>3.9.1&#160; [basic.fundamental]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>21 Oct 2004<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>

<P>There is no normative requirement on the ranges of the integral
types, although the footnote in 3.9.1 [basic.fundamental]
paragraph 2 indicates the intent (for <TT>int</TT>, at least)
that they match the values given in the <TT>&lt;climits&gt;</TT>
header.  Should there be an explicit requirement of some sort?</P>

<P>(See also paper N1693.)</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 3.9.1 [basic.fundamental] paragraph 3 as follows:</P>

<BLOCKQUOTE>

...collectively called the <I>extended integer types</I>.  <SPAN style="font-weight:bold;background-color:#A0FFA0">The
signed and unsigned integral types shall satisfy the constraints given
in ISO C 5.2.4.2.1.</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1302"></A><H4>1302.
  
<TT>noexcept</TT> applied to expression of type <TT>void</TT>
</H4><B>Section: </B>3.9.1&#160; [basic.fundamental]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Nikolay Ivchenkov
 &#160;&#160;&#160;

 <B>Date: </B>2011-04-22<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>The list of acceptable uses of an expression of type <TT>void</TT>
in 3.9.1 [basic.fundamental] paragraph 9 does not, but should, include
an operand of the <TT>noexcept</TT> operator.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 3.9.1 [basic.fundamental] paragraph 9 as follows:</P>

<BLOCKQUOTE>

An expression of type <TT>void</TT> shall be used only as an
expression statement (6.2 [stmt.expr]), as an operand of a
comma expression (5.18 [expr.comma]), as a second or third
operand of <TT>?:</TT> (5.16 [expr.cond]), as the operand of
<TT>typeid</TT><SPAN style="font-weight:bold;background-color:#A0FFA0">, <TT>noexcept</TT>,</SPAN> or <TT>decltype</TT>,
as the expression in a return statement (6.6.3 [stmt.return])
for a function with the return type <TT>void</TT>, or as the operand
of an explicit conversion to type <I>cv</I> <TT>void</TT>.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1059"></A><H4>1059.
  
Cv-qualified array types (with rvalues)
</H4><B>Section: </B>3.9.3&#160; [basic.type.qualifier]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Nikolay Ivchenkov
 &#160;&#160;&#160;

 <B>Date: </B>2010-03-20<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>

<P>In spite of the resolution of <A HREF="
     cwg_defects.html#112">issue 112</A>,
the exact relationship between cv-qualifiers and array types is not
clear.  There does not appear to be a definitive normative statement
answering the question of whether an array with a const-qualified
element type is itself const-qualified; the statement in
3.9.3 [basic.type.qualifier] paragraph 5,</P>

<BLOCKQUOTE>

Cv-qualifiers applied to an array type attach to the underlying
element type, so the notation &#8220;<I>cv</I> <TT>T</TT>,&#8221;
where <TT>T</TT> is an array type, refers to an array whose
elements are so-qualified.  Such array types can be said to be
more (or less) cv-qualified than other types based on the
cv-qualification of the underlying element types.

</BLOCKQUOTE>

<P>hints at an answer but is hardly decisive.  For example, is
the following example well-formed?</P>

<PRE>
    template &lt;class T&gt; struct is_const {
        static const bool value = false;
    };
    template &lt;class T&gt; struct is_const&lt;const T&gt; {
        static const bool value = true;
    };

    template &lt;class T&gt; void f(T &amp;) {
        char checker[is_const&lt;T&gt;::value];
    }

    int const arr[1] = {};

    int main() {
        f(arr);
    }
</PRE>

<P>Also, when 3.10 [basic.lval] paragraph 4 says,</P>

<BLOCKQUOTE>

Class prvalues can have cv-qualified types; non-class prvalues
always have cv-unqualified types.

</BLOCKQUOTE>

<P>does this apply to array rvalues, as it appears?  That is,
given</P>

<PRE>
    struct S {
        const int arr[10];
    };
</PRE>

<P>is the array rvalue <TT>S().arr</TT> an array of <TT>int</TT>
or an array of <TT>const int</TT>?</P>

<P>(The more general question is, when the Standard refers to
non-class types, should it be considered to include array types?
Or perhaps only arrays of non-class types?)</P>

<P><B>Proposed resolution (December, 2011):</B></P>

<OL><LI><P>Change 3.9.3 [basic.type.qualifier] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

...Cv-qualifiers applied to an array type attach to the underlying
element type, so the notation &#8220;<I>cv</I> <TT>T</TT>,&#8221;
where <TT>T</TT> is an array type, refers to an array whose elements are
so-qualified.  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">Such array types can be said to be more (or less)
cv-qualified than other types based on the cv-qualification of the
underlying element types.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">An array type whose elements are
cv-qualified is also considered to have the same cv-qualification as
its elements. [<I>Example:</I></SPAN>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  typedef char CA[5];
  typedef const char CC;
  CC arr1[5] = { 0 };
  const CA arr2 = { 0 };</SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">The type of both <TT>arr1</TT> and <TT>arr2</TT> is
&#8220;array of 5 <TT>const char</TT>,&#8221; and the array type is
considered to be <TT>const</TT>-qualified. &#8212;<I>end
example</I>]</SPAN></P>

</BLOCKQUOTE>

<LI><P>Change 3.10 [basic.lval] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

Class <SPAN style="font-weight:bold;background-color:#A0FFA0">and array</SPAN> prvalues can have cv-qualified types;
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-class</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">other</SPAN> prvalues always have
cv-unqualified types.  Unless otherwise indicated...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1428"></A><H4>1428.
  
Dynamic const objects
</H4><B>Section: </B>3.9.3&#160; [basic.type.qualifier]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2011-12-08<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>The definition of &#8220;const object&#8221; in 3.9.3 [basic.type.qualifier]
paragraph 1 is:</P>

<BLOCKQUOTE>

The presence of a <TT>const</TT> specifier in a <I>decl-specifier-seq</I>
declares an object of <I>const-qualified object type</I>; such object is
called a <I>const object</I>.

</BLOCKQUOTE>

<P>Because the type of an object created by a <I>new-expression</I> is
given by a <I>type-id</I> or <I>new-type-id</I> rather than with a
<I>decl-specifier-seq</I>, this definition gives the false impression
that objects of dynamic storage duration cannot be const objects.  The
wording should be adjusted to make it clear that they can.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<OL><LI><P>Change 3.9.3 [basic.type.qualifier] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<P>The term object type (1.8 [intro.object]) includes the
cv-qualifiers specified <SPAN style="font-weight:bold;background-color:#A0FFA0">in the <I>decl-specifier-seq</I>
(7.1 [dcl.spec]), <I>declarator</I> (Clause
8 [dcl.decl]), <I>type-id</I> (8.1 [dcl.name]), or
<I>new-type-id</I> (5.3.4 [expr.new])</SPAN> when the object
is created. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The presence of a <TT>const</TT> specifier in a
<I>decl-specifier-seq</I> declares an object of
<I>const-qualified object type</I>; such object is called a <I>const
object</I>.  The presence of a <TT>volatile</TT> specifier in a
<I>decl-specifier-seq</I> declares an object of <I>volatile-qualified object
type</I>; such object is called a <I>volatile object</I>.  The presence of both
<I>cv-qualifiers</I> in a <I>decl-specifier-seq</I> declares an object of
<I>const-volatile-qualified object type</I>; such object is called a <I>const
volatile object</I>.</SPAN></P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">A <I>const object</I> is an object of type <TT>const T</TT>
or a non-mutable subobject of such an object.</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">A <I>volatile object</I> is an object of type
<TT>volatile T</TT>, a subobject of such an object, or a mutable
subobject of a const volatile object.</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">A <I>const volatile object</I> is an object of type
<TT>const volatile T</TT>, a non-mutable subobject of such an
object, a const subobject of a volatile object, or a non-mutable
volatile subobject of a const object.</SPAN></P></LI>

</UL>

<P>The cv-qualified or cv-unqualified versions of a type are distinct
types; however, they shall have the same representation and alignment
requirements (3.9 [basic.types]).<SUP>51</SUP></P>

</BLOCKQUOTE>

<LI><P>Change 3.9.3 [basic.type.qualifier] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Each non-static, non-mutable, non-reference data member of a
const-qualified class object is const-qualified, each non-static,
non-reference data member of a volatile-qualified class object is
volatile-qualified and similarly for members of a const-volatile
class.</SPAN> See 8.3.5 [dcl.fct] and 9.3.2 [class.this] regarding function types...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1423"></A><H4>1423.
  
Convertibility of <TT>nullptr</TT> to <TT>bool</TT>
</H4><B>Section: </B>4.12&#160; [conv.bool]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Dave Abrahams
 &#160;&#160;&#160;

 <B>Date: </B>2011-12-04<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>The resolution of <A HREF="
     cwg_defects.html#654">issue 654</A> (found
in paper N2656) enabled conversion of rvalues of type
<TT>std::nullptr_t</TT> to <TT>bool</TT>. It appears that the use
cases for this conversion are primarily or exclusively the
&#8220;contextually converted to <TT>bool</TT>&#8221; cases, with
some possibility for inadvertent misuse in other contexts.  Paper
N2656 mentioned the idea of limiting the conversions to the
direct initialization contexts; that possibility should be
reexamined.
</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 4.12 [conv.bool] paragraph 1 as follows:</P>

<BLOCKQUOTE>

...any other value is converted to <TT>true</TT>.  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">A</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">For direct-initialization (8.5 [dcl.init]), a</SPAN>
prvalue of type <TT>std::nullptr_t</TT> can be converted to a prvalue
of type <TT>bool</TT>; the resulting value is <TT>false</TT>.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1261"></A><H4>1261.
  
Explicit handling of cv-qualification with non-class prvalues
</H4><B>Section: </B>5&#160; [expr]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Nikolay Ivchenkov
 &#160;&#160;&#160;

 <B>Date: </B>2011-03-12<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P><B>Proposed resolution (December, 2011):</B></P>

<OL><LI><P>Change 3.10 [basic.lval] paragraph 4 as
follows (supersedes the corresponding change in the resolution of
<A HREF="
     cwg_defects.html#1059">issue 1059</A>):</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Class prvalues can have cv-qualified types; non-class
prvalues always have cv-unqualified types.</SPAN> Unless otherwise
indicated (5.2.2 [expr.call]), prvalues shall always
have complete types or the <TT>void</TT> type; in addition to
these types, glvalues can also have incomplete types.
<SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> class and array prvalues can have cv-qualified
types; other prvalues always have cv-unqualified types.  See
Clause 5 [expr].  &#8212;<I>end note</I>]</SPAN>

</BLOCKQUOTE>

<LI><P>Add a new paragraph following 5 [expr]
paragraph 5:</P></LI>

<BLOCKQUOTE>

<P>If an expression initially has the type &#8220;reference to
<TT>T</TT>&#8221;...</P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">If a prvalue initially has the type &#8220;<I>cv</I>
<TT>T</TT>,&#8221; where <TT>T</TT> is a cv-unqualified
non-class, non-array type, the type of the expression is adjusted
to <TT>T</TT> prior to any further analysis.</SPAN></P>

</BLOCKQUOTE>

<LI><P>Change 5.2.2 [expr.call] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

If the <I>postfix-expression</I> designates a destructor
(12.4 [class.dtor]), the type of the function call
expression is <TT>void</TT>; otherwise, the type of the function
call expression is the return type of the statically chosen
function (i.e., ignoring the <TT>virtual</TT> keyword), even if
the type of the function actually called is different. This
<SPAN style="font-weight:bold;background-color:#A0FFA0">return</SPAN> type shall be an object type, a reference type
or <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the type</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>cv</I></SPAN> <TT>void</TT>.

</BLOCKQUOTE>

<LI><P>Change 5.2.3 [expr.type.conv] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

...[<I>Note:</I> if <TT>T</TT> is a non-class type that is cv-qualified, the
<I>cv-qualifier</I>s are <SPAN style="text-decoration:line-through;background-color:#FFA0A0">ignored</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">discarded</SPAN>
when determining the type of the resulting prvalue
(<SPAN style="text-decoration:line-through;background-color:#FFA0A0">3.10 [basic.lval]</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Clause
5 [expr]</SPAN>). &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Change 5.4 [expr.cast] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...[<I>Note:</I> if <TT>T</TT> is a non-class type that is
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>cv-qualified</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">cv-qualified</SPAN>, the
<I>cv-qualifier</I>s are <SPAN style="text-decoration:line-through;background-color:#FFA0A0">ignored</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">discarded</SPAN>
when determining the type of the resulting prvalue; see
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">3.10 [basic.lval]</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Clause
5 [expr]</SPAN>. &#8212;<I>end note</I>]

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1383"></A><H4>1383.
  
Clarifying discarded-value expressions
</H4><B>Section: </B>5&#160; [expr]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Lawrence Crowl
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-30<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>

<P>There are some points in the description discarded-value expressions
that need clarification:</P>

<UL><LI><P>Does this require the lvalue-to-rvalue conversion in
the listed cases or only prohibit it in all other cases
(&#8220;only if&#8221; vs &#8220;if and only if&#8221;)?</P></LI>

<LI><P>Does this apply only to built-in operations or to overloaded
operators?</P></LI>

<LI><P>Does this apply to non-POD types?</P></LI>

</UL>

<P><U>Suggested resolution:</U></P>

<BLOCKQUOTE>

<P>In some contexts, an expression only appears for its side
effects. Such an expression is called a <I>discarded-value
expression</I>. The expression is evaluated and its value is
discarded. The array-to-pointer (4.2 [conv.array]) and
function-to-pointer (4.3 [conv.func]) standard
conversions are not applied.  The lvalue-to-rvalue conversion
(4.1 [conv.lval]) is applied <SPAN style="font-weight:bold;background-color:#A0FFA0">if and</SPAN> only if
the expression is an lvalue of volatile-qualified type and it has
one of the following forms:</P>

<UL><LI><P><I>id-expression</I> (5.1.1 [expr.prim.general]),</P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">subscripting</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">subscript operation</SPAN>
(5.2.1 [expr.sub]),</P></LI>

<LI><P>class member access (5.2.5 [expr.ref]),</P></LI>

<LI><P>indirection <SPAN style="font-weight:bold;background-color:#A0FFA0">operation</SPAN> (5.3.1 [expr.unary.op]),</P></LI>

<LI><P>pointer-to-member operation (5.5 [expr.mptr.oper]),</P></LI>

<LI><P>conditional <SPAN style="text-decoration:line-through;background-color:#FFA0A0">expression</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">operation</SPAN>
(5.16 [expr.cond]) where both the second and the third
operands are one of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the above</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">these forms</SPAN>,
or</P></LI>

<LI><P>comma <SPAN style="text-decoration:line-through;background-color:#FFA0A0">expression</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">operation</SPAN>
(5.18 [expr.comma]) where the right operand is one of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the
above</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">these forms</SPAN>.</P></LI>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> Expressions invoking user-defined operators
are not the operations above. Discarded-value expressions apply
to class types, which will be ill-formed if there is no volatile
copy constructor with which to initialize the
temporary. &#8212;<I>end note</I>]</SPAN></P>

</BLOCKQUOTE>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 5 [expr] paragraph 10 as follows:</P>

<BLOCKQUOTE>

<P>...The lvalue-to-rvalue conversion (4.1 [conv.lval]) is
applied <SPAN style="font-weight:bold;background-color:#A0FFA0">if and</SPAN> only if the expression is an lvalue of
volatile-qualified type and it <SPAN style="text-decoration:line-through;background-color:#FFA0A0">has</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">is</SPAN> one of the
following <SPAN style="text-decoration:line-through;background-color:#FFA0A0">forms</SPAN>:</P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>(</TT> <I>expression</I> <TT>)</TT>, where
<I>expression</I> is one of these expressions,</SPAN></P></LI>

<LI><P><I>id-expression</I> (5.1.1 [expr.prim.general]),</P></LI>

<LI><P>...</P></LI>

<LI><P>conditional expression (5.16 [expr.cond]) where both
the second and the third operands are one of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the above</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">these expressions</SPAN>, or</P></LI>

<LI><P>comma expression (5.18 [expr.comma]) where the right
operand is one of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the above</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">these
expressions</SPAN>.</P></LI>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> Using an overloaded operator causes a function
call; the above covers only operators with built-in meaning. If the
lvalue is of class type, it must have a volatile copy constructor to
initialize the temporary that is the result of the lvalue-to-rvalue
conversion. &#8212;<I>end note</I>]</SPAN></P>

</BLOCKQUOTE>

<P><B>Additional note (February, 2012):</B></P>

<P>A problem was discovered that was not addressed by the proposed
resolution that was reviewed at the February, 2012 meeting, so the
issue has been moved back to "review" status with revised wording.</P>

<BR><BR><HR><A NAME="1440"></A><H4>1440.
  
Acceptable <I>decltype-specifier</I>s used as <I>nested-name-specifier</I>s
</H4><B>Section: </B>5.1.1&#160; [expr.prim.general]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>2012-01-05<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>

<P>The current wording of the Standard does not describe what happens
when a <I>decltype-specifier</I> is used as a
<I>nested-name-specifier</I> and the type denoted by the
<I>decltype-specifier</I> is neither a class type nor an
enumeration type. Such <I>nested-name-specifier</I>s should be
prohibited, presumably somewhere around paragraphs 8-10 of
5.1.1 [expr.prim.general].  (The corresponding prohibition for
named types is handled as part of lookup in 3.4.3 [basic.lookup.qual] paragraph 1.)</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Add the following immediately after the grammar in
5.1.1 [expr.prim.general] paragraph 8 and move the text following
that point into a new paragraph:</P>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">The type denoted by a <I>decltype-specifier</I> in a
<I>nested-name-specifier</I> shall be a class or enumeration
type.</SPAN></P>

<P>A <I>nested-name-specifier</I> that denotes a class...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1269"></A><H4>1269.
  
<TT>dynamic_cast</TT> of an xvalue operand
</H4><B>Section: </B>5.2.7&#160; [expr.dynamic.cast]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Michael Wong
 &#160;&#160;&#160;

 <B>Date: </B>2011-03-21<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>

<P>5.2.7 [expr.dynamic.cast] paragraph 2 allows an expression of any value
category when the target type is an rvalue reference.  However, paragraph
6 requires that the operand be an lvalue if the runtime check is to be
applied.  This requirement should presumably be relaxed to require only a
glvalue when the target type is an rvalue reference.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 5.2.7 [expr.dynamic.cast] paragraph 6 as follows:</P>

<BLOCKQUOTE>

Otherwise, <TT>v</TT> shall be a pointer to or <SPAN style="text-decoration:line-through;background-color:#FFA0A0">an lvalue</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">a glvalue</SPAN> of a polymorphic type (10.3 [class.virtual]).

</BLOCKQUOTE>

<P><B>Additional note, January, 2012:</B></P>

<P>An objection has been raised
 to the proposed resolution on the
basis that it unnecessarily weakens the distinction between rvalues
and lvalues, making it easier to create dangling references.  Its
status has therefore been changed back to "review" to allow further
discussion.</P>

<BR><BR><HR><A NAME="1416"></A><H4>1416.
  
Function cv-qualifiers and <TT>typeid</TT>
</H4><B>Section: </B>5.2.8&#160; [expr.typeid]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2011-11-17<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>The requirement in 5.2.8 [expr.typeid] paragraph 5 that</P>

<BLOCKQUOTE>

The top-level cv-qualifiers of the glvalue expression or the
<I>type-id</I> that is the operand of <TT>typeid</TT> are always
ignored

</BLOCKQUOTE>

<P>could be misinterpreted as referring to cv-qualifiers in a
function type, even though it is clear that a function type is never
cv-qualified.  A note emphasizing the fact that that is not the
case would be helpful.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 5.2.8 [expr.typeid] paragraph 5 as follows:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The top-level cv-qualifiers of the glvalue expression or the
<I>type-id</I> that is the operand of <TT>typeid</TT> are always
ignored.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">If the type of the expression or <I>type-id</I> is
a cv-qualified type, the result of the <TT>typeid</TT> expression
refers to a <TT>std::type_info</TT> object representing the
cv-unqualified type.</SPAN> [<I>Example:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1447"></A><H4>1447.
  
<TT>static_cast</TT> of bit-field lvalue to rvalue reference
</H4><B>Section: </B>5.2.9&#160; [expr.static.cast]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2012-01-16<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>According to 5.2.9 [expr.static.cast] paragraph 3,</P>

<BLOCKQUOTE>

A glvalue of type &#8220;<I>cv1</I> <TT>T1</TT>&#8221; can be cast to
type &#8220;rvalue reference to <I>cv2</I> <TT>T2,</TT>&#8221; if
&#8220;<I>cv2</I> <TT>T2</TT>&#8221; is reference-compatible with
&#8220;<I>cv1</I> <TT>T1</TT>&#8221; (8.5.3 [dcl.init.ref]).
The result refers to the object or the specified base class subobject
thereof.

</BLOCKQUOTE>

<P>This specification fails to allow for a bit-field lvalue operand,
since the reference cannot refer to a bit-field.  Presumably a
temporary should be formed and the reference be bound to it.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 5.2.9 [expr.static.cast] paragraphs 3-4 as follows:</P>

<BLOCKQUOTE>

<P>A glvalue of type &#8220;<I>cv1</I> <TT>T1</TT>&#8221; can be cast
to type &#8220;rvalue reference to <I>cv2</I> <TT>T2</TT>&#8221; if
&#8220;<I>cv2</I> <TT>T2</TT>&#8221; is reference-compatible with
&#8220;<I>cv1</I> <TT>T1</TT>&#8221; (8.5.3 [dcl.init.ref]).
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">If the glvalue is not a bit-field, the</SPAN>
result refers to the object or the specified base class subobject
thereof<SPAN style="font-weight:bold;background-color:#A0FFA0">; otherwise, the lvalue-to-rvalue conversion (4.1 [conv.lval]) is applied to the bit-field and the resulting prvalue is
used as the <I>expression</I> of the <TT>static_cast</TT> for the
remainder of this section</SPAN>.  If <TT>T2</TT> is an inaccessible
(Clause 11 [class.access]) or ambiguous (10.2 [class.member.lookup]) base class of <TT>T1</TT>, a program that necessitates
such a cast is ill-formed.</P>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">Otherwise, an</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">An</SPAN> expression <TT>e</TT> can be
explicitly converted...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1268"></A><H4>1268.
  
<TT>reinterpret_cast</TT> of an xvalue operand
</H4><B>Section: </B>5.2.10&#160; [expr.reinterpret.cast]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Michael Wong
 &#160;&#160;&#160;

 <B>Date: </B>2011-03-21<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>

<P>5.2.10 [expr.reinterpret.cast] paragraph 11, dealing with casting to
reference types, only allows an lvalue operand.  Presumably it should
allow a glvalue operand when the target is an rvalue reference type.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 5.2.10 [expr.reinterpret.cast] paragraph 11:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">An lvalue</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">A glvalue</SPAN> expression of type
<TT>T1</TT> can be cast to the type &#8220;reference to
<TT>T2</TT>&#8221; if an expression of type &#8220;pointer to
<TT>T1</TT>&#8221; can be explicitly converted to the type
&#8220;pointer to <TT>T2</TT>&#8221; using a
<TT>reinterpret_cast</TT>. <SPAN style="font-weight:bold;background-color:#A0FFA0">The result refers to the same object
as the source glvalue, but with the specified
type. [<I>Note:</I></SPAN> That is, <SPAN style="font-weight:bold;background-color:#A0FFA0">for lvalues,</SPAN> a reference
cast <TT>reinterpret_cast&lt;T&amp;&gt;(x)</TT> has the same effect as
the conversion <TT>*reinterpret_cast&lt;T*&gt;(&amp;x)</TT> with the
built-in &amp; and * operators (and similarly for
<TT>reinterpret_cast&lt;T&amp;&amp;&gt;(x)</TT>). <SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end
note</I>]</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The result refers to the same object as the source
lvalue, but with a different type. The result is an lvalue for an
lvalue reference type or an rvalue reference to function type and an
xvalue for an rvalue reference to object type.</SPAN> No temporary is
created,...

</BLOCKQUOTE>

<P><B>Additional note, January, 2012:</B></P>

<P>An objection has been raised
 to the proposed resolution on the
basis that it unnecessarily weakens the distinction between rvalues
and lvalues, making it easier to create dangling references.  Its
status has therefore been changed back to "review" to allow further
discussion.</P>

<BR><BR><HR><A NAME="342"></A><H4>342.
  
Terminology: "indirection" versus "dereference"
</H4><B>Section: </B>5.3&#160; [expr.unary]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>7 Oct 2001<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>Split off from <A HREF="
     cwg_closed.html#315">issue 315</A>.</P>

<P>Incidentally, another thing that ought to be cleaned up is the inconsistent
use of "indirection" and "dereference".  We should pick one.</P>

<P><B>Proposed resolution (December, 2006):</B></P>

<OL>

<LI><P>Change 5.3.1 [expr.unary.op] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

The unary <TT>*</TT>
operator <SPAN style="text-decoration:line-through;background-color:#FFA0A0">performs <I>indirection</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">dereferences a pointer
value</SPAN>: the expression to which it is applied shall be a pointer...

</BLOCKQUOTE>

<LI><P>Change 8.3.4 [dcl.array] paragraph 8 as follows:</P></LI>

<BLOCKQUOTE>

The <SPAN style="text-decoration:line-through;background-color:#FFA0A0">results are added and indirection applied</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">values are
added and the result is dereferenced</SPAN> to yield an array (of five
integers), which in turn is converted to a pointer to the first of the
integers.

</BLOCKQUOTE>

<LI><P>Change 8.3.5 [dcl.fct] paragraph 9 as follows:</P></LI>

<BLOCKQUOTE>

The binding of <TT>*fpi(int)</TT> is <TT>*(fpi(int))</TT>, so the
declaration suggests, and the same construction in an expression
requires, the calling of a function <TT>fpi</TT>, and then <SPAN style="text-decoration:line-through;background-color:#FFA0A0">using
indirection through</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">dereferencing</SPAN> the (pointer) result
to yield an integer. In the declarator <TT>(*pif)(const char*, const
char*)</TT>, the extra parentheses are necessary to indicate that
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">indirection through</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">dereferencing</SPAN> a pointer to a
function yields a function, which is then called.

</BLOCKQUOTE>

<LI><P>Change the index for <TT>*</TT> and &#8220;dereferencing&#8221;
no longer to refer to &#8220;indirection.&#8221;</P></LI>

</OL>

<P>[<I>Drafting note:</I> 26.6.9 [template.indirect.array]
requires no change.  Many more places in the current wording use
&#8220;dereferencing&#8221; than &#8220;indirection.&#8221;]</P>

<P><B>Notes from the August, 2011 meeting:</B></P>

<P>CWG prefers use of the term &#8220;indirection&#8221; instead of
&#8220;dereferencing.&#8221; This would be consistent with the usage
in the C Standard and would avoid entanglement with the C++ concept
of a reference type.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<OL><LI><P>Change 3.7.4.1 [basic.stc.dynamic.allocation] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

...The effect of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">dereferencing</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">indirecting
through</SPAN> a pointer returned as a request for zero size is
undefined.

</BLOCKQUOTE>

<LI><P>Change 3.7.4.3 [basic.stc.dynamic.safety] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

<UL><LI><P>the value returned by a call to the C ++ standard library
implementation of <TT>::operator new(std:: size_t)</TT>;
[<I>Footnote:</I> This section does not impose restrictions on
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">dereferencing</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">indirection through</SPAN> pointers to
memory not allocated by <TT>::operator new</TT>.  This maintains the
ability of many C++ implementations to use binary libraries and
components written in other languages.  In particular, this applies to
C binaries, because <SPAN style="text-decoration:line-through;background-color:#FFA0A0">dereferencing</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">indirection
through</SPAN> pointers to memory allocated by
<TT><SPAN style="font-weight:bold;background-color:#A0FFA0">std::</SPAN>malloc</TT> is not restricted. &#8212;<I>end
footnote</I>]</P></LI>

<LI><P>the result of taking the address of an object (or one of its
subobjects) designated by an lvalue resulting from
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">dereferencing</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">indirection through</SPAN> a
safely-derived pointer value;</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 3.8 [basic.life] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Such</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Indirection through such</SPAN> a pointer
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">may be dereferenced</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">is permitted</SPAN> but the
resulting lvalue may only be used in limited ways...

</BLOCKQUOTE>

<LI><P>Change 4.11 [conv.mem] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

...Since the result has type &#8220;pointer to member of <TT>D</TT> of
type <I>cv</I> <TT>T</TT>&#8221;, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">it can be dereferenced</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">indirection through it</SPAN> with a <TT>D</TT> object <SPAN style="font-weight:bold;background-color:#A0FFA0">is
valid</SPAN>.  The result is the same as if <SPAN style="font-weight:bold;background-color:#A0FFA0">indirecting
through</SPAN> the pointer to member of <TT>B</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">were
dereferenced</SPAN> with the <TT>B</TT> subobject of <TT>D</TT>. The
null member pointer value...

</BLOCKQUOTE>

<LI><P>Change 5.2.9 [expr.static.cast] paragraph 12 as follows:</P></LI>

<BLOCKQUOTE>

...[<I>Note:</I> although class <TT>B</TT> need not contain the
original member, the dynamic type of the object <SPAN style="text-decoration:line-through;background-color:#FFA0A0">on</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">with</SPAN> which <SPAN style="font-weight:bold;background-color:#A0FFA0">indirection through</SPAN> the pointer to
member is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">dereferenced</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">performed</SPAN> must contain
the original member; see 5.5 [expr.mptr.oper]. &#8212;<I>end
note</I>]

</BLOCKQUOTE>

<LI><P>Change 5.3.1 [expr.unary.op] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...[<I>Note:</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">indirection through</SPAN> a pointer to an
incomplete type (other than <I>cv</I> <TT>void</TT>) <SPAN style="text-decoration:line-through;background-color:#FFA0A0">can be
dereferenced</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">is valid</SPAN>. The lvalue thus obtained...

</BLOCKQUOTE>

<LI><P>Change 5.10 [expr.eq] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

...Otherwise they compare equal if and only if they would refer to the
same member of the same most derived object (1.8 [intro.object])
or the same subobject if <SPAN style="text-decoration:line-through;background-color:#FFA0A0">they were dereferenced</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">indirection</SPAN> with a hypothetical object of the associated
class type <SPAN style="font-weight:bold;background-color:#A0FFA0">were performed</SPAN>. [<I>Example:</I>...

</BLOCKQUOTE>

<LI><P>Change 7.5 [dcl.link] paragraph 8:</P></LI>

<BLOCKQUOTE>

[<I>Note:</I> Because the language linkage is part of a function type,
when <SPAN style="font-weight:bold;background-color:#A0FFA0">indirecting through</SPAN> a pointer to C function <SPAN style="text-decoration:line-through;background-color:#FFA0A0">(for
example) is dereferenced</SPAN>, the function to which <SPAN style="text-decoration:line-through;background-color:#FFA0A0">it</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">the resulting lvalue</SPAN> refers is considered a C
function. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Change 8.3.2 [dcl.ref] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

...[<I>Note:</I> in particular, a null reference cannot exist in a
well-defined program, because the only way to create such a reference
would be to bind it to the &#8220;object&#8221; obtained by
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">dereferencing</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">indirection through</SPAN> a null
pointer, which causes undefined behavior.  As described...

</BLOCKQUOTE>

<LI><P>Change 17.6.3.5 [allocator.requirements] table 27:</P></LI>

<BLOCKQUOTE>

<TABLE border="2" frame="border" rules="rows"><TR><TD align="center"><B>Variable</B></TD>
<TD align="center"><B>Definition</B></TD></TR>

<TR><TD colspan="2">...</TD></TR>

<TR><TD><B>c</B></TD><TD>a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">dereferenceable</SPAN> pointer of type <TT>C*</TT> <SPAN style="font-weight:bold;background-color:#A0FFA0">through which indirection is valid</SPAN></TD></TR>

<TR><TD colspan="2">...</TD></TR>

</TABLE>

</BLOCKQUOTE>

<LI><P>Change 20.8.3.2 [pointer.traits.functions] as follows:</P></LI>

<BLOCKQUOTE>

<I>Returns:</I> The first member function returns a
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">dereferenceable</SPAN> pointer to <TT>r</TT> obtained by calling
<TT>Ptr::pointer_to(r)</TT> <SPAN style="font-weight:bold;background-color:#A0FFA0">through which indirection is
valid</SPAN>; an instantiation of this function is ill-formed...

</BLOCKQUOTE>

<LI><P>Change 20.8.4 [util.dynamic.safety] paragraph 10 as follows:</P></LI>

<BLOCKQUOTE>

<I>Effects:</I> The <TT>n</TT> bytes starting at <TT>p</TT> no longer
contain traceable pointer locations, independent of their type.  Hence
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">pointers</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">indirection through a pointer</SPAN> located
there <SPAN style="text-decoration:line-through;background-color:#FFA0A0">may not be dereferenced</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">is undefined</SPAN> if
the object <SPAN style="text-decoration:line-through;background-color:#FFA0A0">they point</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">it points</SPAN> to was created
by global <TT>operator new</TT> and not previously declared
reachable...

</BLOCKQUOTE>

<LI><P>Change 20.8.12 [specialized.algorithms] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...is required to have the property that no exceptions are thrown from
increment, assignment, comparison, or <SPAN style="text-decoration:line-through;background-color:#FFA0A0">dereference of</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">indirection through</SPAN> valid iterators...

</BLOCKQUOTE>

<LI><P>Change 22.4.5.1.2 [locale.time.get.virtuals] paragraph 11 as follows:</P></LI>

<BLOCKQUOTE>

<I>Requires:</I> <TT>t</TT> shall <SPAN style="text-decoration:line-through;background-color:#FFA0A0">be dereferenceable</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">point to an object</SPAN>.

</BLOCKQUOTE>

<LI><P>Change 23.4.4.2 [map.cons] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

<I>Requires:</I> If the iterator's <SPAN style="text-decoration:line-through;background-color:#FFA0A0">dereference</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">indirection</SPAN> operator returns an lvalue or a const rvalue
<TT>pair&lt;key_type, mapped_type&gt;</TT>, then both
<TT>key_type</TT> and <TT>mapped_type</TT> shall be
<TT>CopyConstructible</TT>.

</BLOCKQUOTE>

<LI><P>Change 23.4.5.2 [multimap.cons] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

<I>Requires:</I> If the iterator's <SPAN style="text-decoration:line-through;background-color:#FFA0A0">dereference</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">indirection</SPAN> operator returns an lvalue or a const rvalue
<TT>pair&lt;key_type, mapped_type&gt;</TT>, then both <TT>key_type</TT> and
<TT>mapped_type</TT> shall be <TT>CopyConstructible</TT>.

</BLOCKQUOTE>

<LI><P>Change 23.4.6.2 [set.cons] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

<I>Requires:</I> If the iterator's <SPAN style="text-decoration:line-through;background-color:#FFA0A0">dereference</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">indirection</SPAN> operator returns an lvalue or a non-const
rvalue, then <TT>Key</TT> shall be <TT>CopyConstructible</TT>.

</BLOCKQUOTE>

<LI><P>Change 23.4.7.2 [multiset.cons] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

<I>Requires:</I> If the iterator's <SPAN style="text-decoration:line-through;background-color:#FFA0A0">dereference</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">indirection</SPAN> operator returns an lvalue or a const rvalue,
then <TT>Key</TT> shall be <TT>CopyConstructible</TT>.

</BLOCKQUOTE>

<LI><P>Change 24.5.3 [move.iterators] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

Class template <TT>move_iterator</TT> is an iterator adaptor with the
same behavior as the underlying iterator except that its
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">dereference</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">indirection</SPAN> operator implicitly
converts the value returned by the underlying iterator's
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">dereference</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">indirection</SPAN> operator to an rvalue
reference...

</BLOCKQUOTE>

<LI><P>Change the title of 28.12.1.3 [re.regiter.deref] as follows:</P></LI>

<BLOCKQUOTE>

<B><TT>regex_iterator</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">dereference</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">indirection</SPAN></B>

</BLOCKQUOTE>

<LI><P>Change the title of 28.12.2.3 [re.tokiter.deref] as follows:</P></LI>

<BLOCKQUOTE>

<B><TT>regex_token_iterator</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">dereference</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">indirection</SPAN></B>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1458"></A><H4>1458.
  
Address of incomplete type vs <TT>operator&amp;()</TT>
</H4><B>Section: </B>5.3.1&#160; [expr.unary.op]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2012-02-07<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>

<P>According to 5.3.1 [expr.unary.op] paragraph 5,</P>

<BLOCKQUOTE>

The address of an object of incomplete type can be taken, but if the
complete type of that object is a class type that declares
<TT>operator&amp;()</TT> as a member function, then the behavior is
undefined (and no diagnostic is required).

</BLOCKQUOTE>

<P>This should actually be &#8220;ill-formed, no diagnostic
required&#8221; instead of undefined behavior, since the problem
could be detected by whole-program analysis.  Also, it's not clear
what this means for constant expressions.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 5.3.1 [expr.unary.op] paragraph 5 as follows:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The address of an object of incomplete type can be taken, but if
the complete type of that object is a class type that declares
<TT>operator&amp;()</TT> as a member function, then the behavior is
undefined (and no diagnostic is required).</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">If
<TT>&amp;</TT> is applied to an lvalue of incomplete class type and
the complete type declares <TT>operator&amp;()</TT>, it is unspecified
whether the operator has the built-in meaning or the operator function
is called.</SPAN> The operand of <TT>&amp;</TT> shall not be a
bit-field.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="292"></A><H4>292.
  
Deallocation on exception in <TT>new</TT> before arguments evaluated
</H4><B>Section: </B>5.3.4&#160; [expr.new]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Andrei Iltchenko
 &#160;&#160;&#160;

 <B>Date: </B>26 Jun 2001<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>

<P>According to the C++ Standard section 5.3.4 [expr.new]
paragraph 21 it is unspecified whether the allocation function is called before
evaluating the constructor arguments or after evaluating the
constructor arguments but before entering the constructor.</P>

<P>On top of that paragraph 17 of the same section insists that</P>
<BLOCKQUOTE>
If any
part of the object initialization described above [Footnote: This may
include evaluating a new-initializer and/or calling a constructor.]
terminates by throwing an exception and a suitable deallocation
function is found, the deallocation function is called to free the
memory in which the object was being constructed... If no unambiguous
matching deallocation function can be found, propagating the exception
does not cause the object's memory to be freed...
</BLOCKQUOTE>

<P>Now suppose we have:</P>
<OL>
<LI>
An implementation that always evaluates the constructor arguments
first (for a new-expression that creates an object of a class type and
has a new-initializer) and calls the allocation function afterwards.
</LI>
<LI>
A class like this:
<PRE>
    struct  copy_throw  {
       copy_throw(const copy_throw&amp;)
       {   throw  std::logic_error("Cannot copy!");   }
       copy_throw(long, copy_throw)
       {   }
       copy_throw()
       {   }
    };
</PRE>
</LI>
<LI>
And a piece of code that looks like the one below:
<PRE>
    int  main()
    try  {
       copy_throw   an_object,     /* undefined behaviour */
          * a_pointer = ::new copy_throw(0, an_object);
       return  0;
    }
    catch(const std::logic_error&amp;)
    {   }
</PRE>
</LI>
</OL>
<P>Here the new-expression '<TT>::new copy_throw(0, an_object)</TT>' throws an
exception when evaluating the constructor's arguments and before the
allocation function is called. However, 5.3.4 [expr.new]
paragraph 17
prescribes that in such a case the implementation shall call the
deallocation function to free the memory in which the object was being
constructed, given that a matching deallocation function can be found.</P>

<P>So a call to the Standard library deallocation function '<TT>::operator
delete(void*)</TT>' shall be issued, but what argument is an implementation
supposed to supply to the deallocation function? As per
5.3.4 [expr.new] paragraph 17 - the argument is the address
of the memory in
which the object was being constructed. Given that no memory has yet
been allocated for the object, this will qualify as using an invalid
pointer value, which is undefined behaviour by virtue of
3.7.4.2 [basic.stc.dynamic.deallocation] paragraph 4.</P>

<P><B>Suggested resolution:</B></P>

<P>Change the first sentence of 5.3.4 [expr.new] paragraph 17
to read:</P>
<BLOCKQUOTE>
If the memory for the object being created has already been
successfully allocated and any part of the object initialization
described above...
</BLOCKQUOTE>

<P><B>Proposed resolution (March, 2008):</B></P>

<P>Change 5.3.4 [expr.new] paragraph 18 as follows:</P>

<BLOCKQUOTE>

If any part of the object initialization described above
[<I>Footnote:</I> ...]  terminates by throwing an exception<SPAN style="font-weight:bold;background-color:#A0FFA0">,
storage has been obtained for the object,</SPAN> and a suitable
deallocation function can be found, the deallocation function is
called...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1305"></A><H4>1305.
  
<TT>alignof</TT> applied to array of unknown size
</H4><B>Section: </B>5.3.6&#160; [expr.alignof]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Nikolay Ivchenkov
 &#160;&#160;&#160;

 <B>Date: </B>2011-04-26<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>According to 5.3.6 [expr.alignof] paragraph 1,</P>

<BLOCKQUOTE>

An <TT>alignof</TT> expression yields the alignment requirement of its
operand type. The operand shall be a <I>type-id</I> representing a
complete object type or an array thereof or a reference to a complete
object type.

</BLOCKQUOTE>

<P>This (presumably unintentionally) excludes a reference to an array
with an unknown bound but a complete element type; the bound is not
needed to determine the alignment of the array.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 5.3.6 [expr.alignof] paragraph 1 as follows:</P>

<BLOCKQUOTE>

An <TT>alignof</TT> expression yields the alignment requirement of its
operand type. The operand shall be a <I>type-id</I> representing a
complete object type or an array thereof or a reference to <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a complete
object type</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">one of those types</SPAN>.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1354"></A><H4>1354.
  
Destructor exceptions for temporaries in noexcept expressions
</H4><B>Section: </B>5.3.7&#160; [expr.unary.noexcept]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Sebastian Redl
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-16<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>The result of the <TT>noexcept</TT> operator does not consider possible
exceptions thrown by the destructors for temporaries created in the
operand expression.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<OL><LI><P>Change 1.9 [intro.execution] paragraph 10 as follows:</P></LI>

<BLOCKQUOTE>

A <I>full-expression</I> is an expression that is not a subexpression
of another expression. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> in some contexts such as
unevaluated operands, a syntactic subexpression is considered a
full-expression (Clause 5 [expr]). &#8212;<I>end
note</I>]</SPAN> If a language construct...

</BLOCKQUOTE>

<LI><P>Change 5 [expr] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

...An unevaluated operand is not evaluated. <SPAN style="font-weight:bold;background-color:#A0FFA0">An unevaluated
operand is considered a full-expression.</SPAN> [<I>Note:</I>...

</BLOCKQUOTE>

</OL>

<P><I>[Drafting note: This uniformly handles <TT>sizeof(A())</TT>,
<TT>noexcept(A())</TT>, <TT>typeid(A())</TT>, and
<TT>decltype(A())</TT> with regard to the semantic requirements on
<TT>~A</TT> (accessible and not deleted), which might be checked via
SFINAE. A programmer can use <TT>decltype(new A)</TT> to avoid
considering the destructor. If this is undesired, an alternative
change just addresses the noexecept issue:]</I></P>

<P><I>[Editing note: all the occurrences of &#8220;potentially
evaluated&#8221; in 5.3.7 [expr.unary.noexcept] paragraph 3 should
be hyphenated.]</I></P>

<BR><BR><HR><A NAME="1340"></A><H4>1340.
  
Complete type in member pointer expressions
</H4><B>Section: </B>5.5&#160; [expr.mptr.oper]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-10<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>Both the <TT>.*</TT> and <TT>-&gt;*</TT> operators
(5.5 [expr.mptr.oper]) require that the class of the second
operand be a complete object type.  Current implementations do not
enforce this requirement, and it is not clear that there is a need
for it.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<OL><LI><P>Change 5.5 [expr.mptr.oper] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

The binary operator <TT>.*</TT> binds its second operand, which shall
be of type &#8220;pointer to member of <TT>T</TT>&#8221; <SPAN style="text-decoration:line-through;background-color:#FFA0A0">(where
<TT>T</TT> is a completely-defined class type)</SPAN> to its first
operand...

</BLOCKQUOTE>

<LI><P>Change 5.5 [expr.mptr.oper] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

The binary operator <TT>-&gt;*</TT> binds its second operand, which
shall be of type &#8220;pointer to member of <TT>T</TT>&#8221;
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">(where <TT>T</TT> is a completely-defined class type)</SPAN> to
its first operand...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1450"></A><H4>1450.
  
<TT>INT_MIN % -1</TT>
</H4><B>Section: </B>5.6&#160; [expr.mul]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2012-01-31<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P><A HREF="
     cwg_defects.html#614">Issue 614</A> adopted the corresponding C99
wording for 5.6 [expr.mul] paragraph 4,</P>

<BLOCKQUOTE>

...if the quotient <TT>a/b</TT> is representable in the type of the result,
<TT>(a/b)*b + a%b</TT> is equal to <TT>a</TT>.

</BLOCKQUOTE>

<P>in an attempt to ensure that <TT>INT_MAX % -1</TT> produces
undefined behavior (because the result is not specified by the
Standard).  However, the new C draft makes the undefined behavior
explicit:</P>

<BLOCKQUOTE>

If the quotient <TT>a/b</TT> is representable, the expression
<TT>(a/b) * b + a%b</TT> shall equal <TT>a</TT>; otherwise, the
behavior of both <TT>a/b</TT> and <TT>a%b</TT> is undefined.

</BLOCKQUOTE>

<P>Should C++ adopt similar wording?</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 5.6 [expr.mul] paragraph 4 as follows:</P>

<BLOCKQUOTE>

...If the second operand of <TT>/</TT> or <TT>%</TT> is zero the
behavior is undefined. For integral operands the <TT>/</TT> operator
yields the algebraic quotient with any fractional part
discarded;<SUP>81</SUP> if the quotient <TT>a/b</TT> is representable
in the type of the result, <TT>(a/b)*b&#160;+&#160;a%b</TT> is equal to
<TT>a</TT><SPAN style="font-weight:bold;background-color:#A0FFA0">; otherwise, the behavior of both <TT>a/b</TT> and
<TT>a%b</TT> is undefined</SPAN>.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1457"></A><H4>1457.
  
Undefined behavior in left-shift
</H4><B>Section: </B>5.8&#160; [expr.shift]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Howard Hinnant
 &#160;&#160;&#160;

 <B>Date: </B>2012-02-04<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>

<P>The current wording of 5.8 [expr.shift] paragraph 2 makes it
undefined behavior to create the most-negative integer of a given type
by left-shifting a (signed) <TT>1</TT> into the sign bit, even though
this is not uncommonly done and works correctly on the majority of
(twos-complement) architectures:</P>

<BLOCKQUOTE>

...if <TT>E1</TT> has a signed type and non-negative value, and <TT>E1
&#10799; 2<SUP>E2</SUP></TT> is representable in the result type, then
that is the resulting value; otherwise, the behavior is undefined.

</BLOCKQUOTE>

<P>As a result, this technique cannot be used in a constant expression,
which will break a significant amount of code.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 5.8 [expr.shift] paragraph 2 as follows:</P>

<BLOCKQUOTE>

...if <TT>E1</TT> has a signed type and non-negative value, and <TT>E1
&#10799; 2<SUP>E2</SUP></TT> is representable in the <SPAN style="font-weight:bold;background-color:#A0FFA0">corresponding
unsigned type of the</SPAN> result type, then that <SPAN style="font-weight:bold;background-color:#A0FFA0">value,
converted to the result type,</SPAN> is the resulting value; otherwise,
the behavior is undefined.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1264"></A><H4>1264.
  
Use of <TT>this</TT> in <TT>constexpr</TT> constructor
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2011-03-18<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P><B>Proposed resolution (August, 2011):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#1369">issue 1369</A>.</P>

<BR><BR><HR><A NAME="1293"></A><H4>1293.
  
String literals in constant expressions
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2011-04-11<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>It is not clear whether a string literal can be used in a constant
expression.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 5.19 [expr.const] paragraph 2 as follows:</P>

<UL><LI><P>an lvalue-to-rvalue conversion (4.1 [conv.lval])
unless it is applied to</P></LI>

<UL><LI><P>a glvalue of integral or enumeration type that refers to a
non-volatile const object with a preceding initialization, initialized
with a constant expression <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> a string literal
(2.14.5 [lex.string]) corresponds to an array of such
objects. &#8212;<I>end note</I>]</SPAN>, or</P></LI>

<LI><P>...</P></LI>

</UL>

</UL>

<BR><BR><HR><A NAME="1311"></A><H4>1311.
  
Volatile lvalues in constant expressions
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Nikolay Ivchenkov
 &#160;&#160;&#160;

 <B>Date: </B>2011-05-06<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>The current wording of 5.19 [expr.const] paragraph 2 does
not, but should, prohibit use of volatile glvalues in constant
expressions.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 5.19 [expr.const] paragraph 2 as follows:</P>

<UL><LI><P>an lvalue-to-rvalue conversion (4.1 [conv.lval])
unless it is applied to</P></LI>

<UL><LI><P>a <SPAN style="font-weight:bold;background-color:#A0FFA0">non-volatile</SPAN> glvalue of integral or
enumeration type that refers to a non-volatile const object with a
preceding initialization, initialized with a constant expression,
or</P></LI>

<LI><P>a <SPAN style="font-weight:bold;background-color:#A0FFA0">non-volatile</SPAN> glvalue of literal type that refers
to a non-volatile object defined with <TT>constexpr</TT>, or that
refers to a sub-object of such an object, or</P></LI>

<LI><P>a <SPAN style="font-weight:bold;background-color:#A0FFA0">non-volatile</SPAN> glvalue of literal type that refers
to a non-volatile temporary object whose lifetime has not ended,
initialized with a constant expression;</P></LI>

</UL>
</UL>

<BR><BR><HR><A NAME="1312"></A><H4>1312.
  
Simulated <TT>reinterpret_cast</TT> in constant expressions
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Nikolay Ivchenkov
 &#160;&#160;&#160;

 <B>Date: </B>2011-05-06<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>Although a <TT>reinterpret_cast</TT> is prohibited in a constant
expression, casting to and from <TT>void*</TT> can achieve the same
effect.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 5.19 [expr.const] paragraph 2 as follows:</P>

<UL><LI><P>an lvalue-to-rvalue conversion (4.1 [conv.lval])
unless it is applied to...</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">an lvalue-to-rvalue conversion (4.1 [conv.lval])
that is applied to a glvalue of type <I>cv1</I> <TT>T</TT> that refers
to an object of type <I>cv2</I> <TT>U</TT>, where <TT>T</TT> and
<TT>U</TT> are neither the same type nor similar types (4.4 [conv.qual]);</SPAN></P></LI>

<LI><P>an lvalue-to-rvalue conversion (4.1 [conv.lval]) that
is applied to a glvalue that refers to a non-active member...</P></LI>

</UL>

<P><B>Note, January, 2012:</B></P>

<P>Additional discussion  has occurred, so this issue has been returned to
"review" status to allow further consideration.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 5.19 [expr.const] paragraph 2 as follows:</P>

<UL><LI><P>...</P></LI>

<LI><P>an <I>id-expression</I> that refers to a variable or data
member of reference type unless...</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">a conversion from type <I>cv</I> <TT>void *</TT> to a
pointer-to-object type;</SPAN></P></LI>

<LI><P>a dynamic cast (5.2.7 [expr.dynamic.cast]);</P></LI>

<LI><P>...</P></LI>

</UL>

<BR><BR><HR><A NAME="1313"></A><H4>1313.
  
Undefined pointer arithmetic in constant expressions
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Jens Maurer
 &#160;&#160;&#160;

 <B>Date: </B>2011-05-07<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>The requirements for constant expressions do not currently,
but should, exclude expressions that have undefined behavior, such as
pointer arithmetic when the pointers do not point to elements of the
same array.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 5.19 [expr.const] paragraph 2 as follows:</P>

<UL><LI><P>...</P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">a result that is not mathematically defined or not in the
range of representable values for its type;</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">an operation that would have undefined behavior
[<I>Note:</I> including, for example, signed integer overflow (Clause
5 [expr]), certain pointer arithmetic (5.7 [expr.add]), division by zero (5.6 [expr.mul]), or certain
shift operations (5.8 [expr.shift]) &#8212;<I>end
note</I>];</SPAN></P></LI>

<LI><P>...</P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">a subtraction (5.7 [expr.add]) where both
operands are pointers;</SPAN></P></LI>

<LI><P>...</P></LI>

</UL>

<BR><BR><HR><A NAME="1364"></A><H4>1364.
  
<TT>constexpr</TT> function parameters
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Sean Hunt
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-17<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>Use of a parameter in a <TT>constexpr</TT> function appears to be
ill-formed, because the lvalue-to-rvalue conversion on the parameter
is not one of those permitted in a constant expression.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<OL><LI><P>Change the indicated bullet of 5.19 [expr.const]
paragraph 2 as follows:</P></LI>

<UL><LI><P>an invocation of a <TT>constexpr</TT> constructor with
arguments that, when substituted by function invocation substitution
(7.1.5 [dcl.constexpr]), do not produce all constant expressions
for the constructor calls and full-expressions in the
<I>mem-initializer</I>s <SPAN style="font-weight:bold;background-color:#A0FFA0">(including conversions)</SPAN>;
[<I>Example:</I>...</P></LI></UL>

<LI><P>Delete the final bullet of 7.1.5 [dcl.constexpr]
paragraph 3 and move the deleted "." to the preceding
sub-bullet:</P></LI>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">every constructor call and implicit conversion used in
initializing the return value (6.6.3 [stmt.return],
8.5 [dcl.init]) shall be one of those allowed in a constant
expression (5.19 [expr.const]).</SPAN></P></LI></UL>

<LI><P>Delete the final bullet of 7.1.5 [dcl.constexpr]
paragraph 4 and change the preceding bullet as follows:</P></LI>

<UL><LI><P>every <I>assignment-expression</I> that is an
<I>initializer-clause</I> appearing directly or indirectly within a
<I>brace-or-equal-initializer</I> for a non-static data member that is not
named by a <I>mem-initializer-id</I> shall be a constant expression<SPAN style="text-decoration:line-through;background-color:#FFA0A0">;
and</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">.</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">every implicit conversion used in converting a constructor
argument to the corresponding parameter type and converting a
full-expression to the corresponding member type shall be one of those
allowed in a constant expression.</SPAN></P></LI>

</UL>

</OL>

<BR><BR><HR><A NAME="1365"></A><H4>1365.
  
Calling undefined <TT>constexpr</TT> functions
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Sean Hunt
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-17<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>The current wording appears to allow calling a <TT>constexpr</TT>
function that is never defined within the body of a <TT>constexpr</TT>
function. (The wording was intended to allow mutually-recursive
<TT>constexpr</TT> functions but require that the not-yet-defined
function be defined before it would be needed in an actual constant
expression.)</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change the indicated bullet of 5.19 [expr.const] paragraph 2
as follows:</P>

<UL><LI><P>an invocation of an undefined <TT>constexpr</TT> function
or an undefined <TT>constexpr</TT> constructor <SPAN style="text-decoration:line-through;background-color:#FFA0A0">outside the definition
of a <TT>constexpr</TT> function or a <TT>constexpr</TT>
constructor</SPAN>;</P></LI></UL>

<BR><BR><HR><A NAME="1367"></A><H4>1367.
  
Use of <TT>this</TT> in a constant expression
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-17<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>The provisions allowing the use of <TT>this</TT> in a constant
expression appear to be unnecessary, as any uses of <TT>this</TT> in
a constant expression that are valid will be replaced by function
invocation substitution.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#1369">issue 1369</A>.</P>

<BR><BR><HR><A NAME="1454"></A><H4>1454.
  
Passing constants through <TT>constexpr</TT> functions via references
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2011-12-27<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>The current wording incorrectly appears to make the following
example ill-formed:</P>

<PRE>
   constexpr const int &amp;f(const int &amp;n) { return n; }
   constexpr int k = f(0);   // ill-formed
</PRE>

<P><B>Proposed resolution (February, 2012):</B></P>

<OL><LI><P>Change 5.19 [expr.const] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

<P>A <I>conditional-expression</I> is a <I>core constant
expression</I> unless it involves one of the following...</P>

<UL><LI><P>...</P></LI>

<LI><P>an invocation of a <TT>constexpr</TT> function with arguments
that, when substituted by function invocation substitution
(7.1.5 [dcl.constexpr]), do not produce a <SPAN style="font-weight:bold;background-color:#A0FFA0">core</SPAN>
constant expression; [<I>Example:</I>...</P></LI>

<LI><P>an invocation of a <TT>constexpr</TT> constructor with
arguments that, when substituted by function invocation substitution
(7.1.5 [dcl.constexpr]), do not produce all <SPAN style="font-weight:bold;background-color:#A0FFA0">core</SPAN>
constant expressions for the constructor calls and full-expressions in
the <I>mem-initializer</I>s; [<I>Example:</I>...</P></LI>

<LI><P>...</P></LI>

<LI><P>an lvalue-to-rvalue conversion (4.1 [conv.lval])
unless it is applied to</P></LI>

<UL><LI><P>...</P></LI>

<LI><P>a glvalue of literal type that refers to a non-volatile
temporary object whose lifetime has not ended, initialized with a
<SPAN style="font-weight:bold;background-color:#A0FFA0">core</SPAN> constant expression;</P></LI>

</UL>

<LI><P>...</P></LI>

<LI><P>an <I>id-expression</I> that refers to a variable or data
member of reference type unless the reference has a preceding
initialization<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, initialized with a constant expression;</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">and either</SPAN></P></LI>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">it is initialized with a constant expression or</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">it is a non-static data member of a temporary object whose
lifetime has not ended and is initialized with a core constant
expression;</SPAN></P></LI>

</UL>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 5.19 [expr.const] paragraph 3 as follows,
dividing it into two paragraphs:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">A <I>literal constant expression</I> is a prvalue core
constant expression of literal type, but not pointer type.</SPAN> An
<I>integral constant expression</I> is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a literal constant</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">an</SPAN> expression of integral or unscoped enumeration
type<SPAN style="font-weight:bold;background-color:#A0FFA0">, implicitly converted to a prvalue, where the converted
expression is a core constant expression</SPAN>. [<I>Note:</I> Such
expressions may be used as array bounds (8.3.4 [dcl.array],
5.3.4 [expr.new]), as bit-field lengths (9.6 [class.bit]), as enumerator initializers if the underlying type is not
fixed (7.2 [dcl.enum]), as null pointer constants
(4.10 [conv.ptr]), and as alignments (7.6.2 [dcl.align]).  &#8212;<I>end note</I>] A <I>converted constant
expression</I> of type <TT>T</TT> is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a literal constant</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">an</SPAN> expression, implicitly converted to <SPAN style="font-weight:bold;background-color:#A0FFA0">a prvalue
of</SPAN> type <TT>T</TT>, where the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">implicit conversion (if any)
is permitted in a literal</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">converted expression is a
core</SPAN> constant expression and the implicit conversion sequence
contains only user-defined conversions, lvalue-to-rvalue conversions
(4.1 [conv.lval]), integral promotions (4.5 [conv.prom]), and integral conversions (4.7 [conv.integral])
other than narrowing conversions (8.5.4 [dcl.init.list]). [<I>Note:</I> such expressions may be used as case
expressions (6.4.2 [stmt.switch]), as enumerator initializers
if the underlying type is fixed (7.2 [dcl.enum]), and as
integral or enumeration non-type template arguments (14.3 [temp.arg]). &#8212;<I>end note</I>]</P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">A <I>literal constant expression</I> is a prvalue core
constant expression of literal type, but not pointer type (after
conversions as required by the context).  For a literal constant
expression of array or class type, each subobject of its value shall
have been initialized by a constant expression.</SPAN> A <I>reference
constant expression</I> is an lvalue core constant expression that
designates an object with static storage duration or a function.  An
<I>address constant expression</I> is a prvalue core constant
expression <SPAN style="font-weight:bold;background-color:#A0FFA0">(after conversions as required by the context) of type
<TT>std::nullptr_t</TT> or</SPAN> of pointer type that evaluates to the
address of an object with static storage duration, to the address of a
function, or to a null pointer value<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, or a prvalue core constant
expression of type <TT>std::nullptr_t</TT></SPAN>.  Collectively,
literal constant expressions, reference constant expressions, and
address constant expressions are called
<I>constant expressions</I>.</P>

</BLOCKQUOTE>

<LI><P>Change the second example 7.1.5 [dcl.constexpr] paragraph
5 as follows:</P></LI>

<PRE>
  constexpr int f(bool b)
    { return b ? throw 0 : 0; }                  //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
  constexpr int f() { <SPAN style="text-decoration:line-through;background-color:#FFA0A0">throw 0</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">return f(true)</SPAN>; }  //<SPAN style="font-family:Times;font-style:italic"> ill-formed, no diagnostic required</SPAN>
  ...
</PRE>

</OL>

<P>This resolution also resolves <A HREF="
     cwg_defects.html#1455">issue 1455</A>.</P>

<BR><BR><HR><A NAME="1455"></A><H4>1455.
  
Lvalue converted constant expressions
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2012-01-14<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>A "converted constant expression" must be a literal constant
expression, which is a prvalue, and thus can't be an lvalue. This is
unintended; the lvalue-to-rvalue conversion should be applied as
necessary.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#1454">issue 1454</A>.</P>

<BR><BR><HR><A NAME="631"></A><H4>631.
  
Jumping into a &#8220;then&#8221; clause
</H4><B>Section: </B>6.4.1&#160; [stmt.if]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>James Kanze
 &#160;&#160;&#160;

 <B>Date: </B>24 April 2007<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>

<P>6.4.1 [stmt.if] is silent about whether the <TT>else</TT>
clause of an <TT>if</TT> statement is executed if the condition is not
evaluated.  (This could occur via a <TT>goto</TT> or a <TT>longjmp</TT>.)
C99 covers the <TT>goto</TT> case with the following provision:</P>

<BLOCKQUOTE>

If the first substatement is reached via a label, the second
substatement is not executed.

</BLOCKQUOTE>

<P>It should probably also be stated that the condition is not
evaluated when the &#8220;then&#8221; clause is entered directly.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 6.4.1 [stmt.if] paragraph 1 as follows:</P>

<BLOCKQUOTE>

If the condition (6.4 [stmt.select]) yields <TT>true</TT> the
first substatement is executed.  If the <TT>else</TT> part of the
selection statement is present and the condition yields
<TT>false</TT>, the second substatement is executed. <SPAN style="font-weight:bold;background-color:#A0FFA0">If the first
substatement is reached via a label, the condition is not evaluated
and the second substatement is not executed.</SPAN> In the second
form...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1359"></A><H4>1359.
  
<TT>constexpr</TT> union constructors
</H4><B>Section: </B>7.1.5&#160; [dcl.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-16<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>A <TT>constexpr</TT> constructor is required to initialize all
non-static data members (7.1.5 [dcl.constexpr] paragraph 4),
which conflicts with the requirement that a constructor for a union
is permitted to initialize only a single non-static data member
(12.6.2 [class.base.init] paragraph 8).</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 7.1.5 [dcl.constexpr] paragraph 4 as follows:</P>

<P>In a definition of a <TT>constexpr</TT> constructor, each of the
parameter types shall be a literal type. In addition, either its
<I>function-body</I> shall be <TT>= delete</TT> or <TT>= default</TT>
or it shall satisfy the following constraints:</P>

<UL><LI><P>...</P></LI>

<LI><P>every <SPAN style="font-weight:bold;background-color:#A0FFA0">non-variant</SPAN> non-static data member and base class
sub-object shall be initialized (12.6.2 [class.base.init]);</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">if the class is a non-empty union, or for each non-empty
anonymous union member of a non-union class, exactly one non-static
data member shall be initialized;</SPAN></P></LI>

<LI><P>...</P></LI>

</UL>

<BR><BR><HR><A NAME="1366"></A><H4>1366.
  
Deleted <TT>constexpr</TT> constructors and virtual base classes
</H4><B>Section: </B>7.1.5&#160; [dcl.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Sean Hunt
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-17<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>The requirement that a class with a <TT>constexpr</TT> constructor
cannot have a virtual base only applies to constructors with
non-deleted and non-defaulted <I>function-body</I>s.  This seems like
an oversight.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 7.1.5 [dcl.constexpr] paragraph 4 as follows:</P>

<BLOCKQUOTE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">In a</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">The</SPAN> definition of a <TT>constexpr</TT>
constructor<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, each of the parameter types shall be a literal type. In
addition, either its
<I>function-body</I> shall be <TT>= delete</TT> or <TT>= default</TT>
or it</SPAN> shall satisfy the following constraints:</P>

<UL><LI><P>the class shall not have any virtual base classes;</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">each of the parameter types shall be a literal type;</SPAN></P></LI>

<LI><P>its <I>function-body</I> shall not be a
<I>function-try-block</I>;</P></LI>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">In addition, either its <I>function-body</I> shall be
<TT>= delete</TT> or it shall satisfy the following constraints:</SPAN></P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">either its <I>function-body</I> shall be <TT>= default
or</TT></SPAN> the compound-statement of its function-body shall
contain only...</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1369"></A><H4>1369.
  
Function invocation substitution of <TT>this</TT>
</H4><B>Section: </B>7.1.5&#160; [dcl.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Jens Maurer
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-18<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>

<P>Function invocation substitution (7.1.5 [dcl.constexpr] paragraph 5)
seems underspecified with respect to <TT>this</TT>.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<OL><LI><P>Change the indicated bullet of 5.19 [expr.const]
paragraph 2 as follows:</P></LI>

<UL><LI><P><TT>this</TT> (<SPAN style="text-decoration:line-through;background-color:#FFA0A0">5.1 [expr.prim]</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">5.1.1 [expr.prim.general]</SPAN>) <SPAN style="text-decoration:line-through;background-color:#FFA0A0">unless it appears as the
<I>postfix-expression</I> in a class member access expression,
including the result of the implicit transformation in the body of a
non-static member function (9.3.1 [class.mfct.non-static])</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> when evaluating a constant expression, function
invocation substitution (7.1.5 [dcl.constexpr]) replaces each
occurrence of <TT>this</TT> in a <TT>constexpr</TT> member function
with a pointer to the class object. &#8212;<I>end
note</I>]</SPAN>;</P></LI></UL>

<LI><P>Change 7.1.5 [dcl.constexpr] paragraph 5 as follows
(converting the running text into a bulleted list):</P></LI>

<BLOCKQUOTE>

<P><I>Function invocation substitution</I> for a call of a
<I>constexpr</I> function or of a <I>constexpr</I> constructor
means<SPAN style="font-weight:bold;background-color:#A0FFA0">:</SPAN></P>

<UL><LI><P>implicitly converting each argument to the corresponding
parameter type as if by copy-initialization,<SUP>91</SUP></P></LI>

<LI><P>substituting that converted expression for each use of the
corresponding parameter in the <I>function-body</I>,</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">in a member function, substituting for each use of
<TT>this</TT> (9.3.2 [class.this]) a prvalue pointer
whose value is the address of the object for which the member
function is called,</SPAN> and</P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">for</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">in a</SPAN> <TT>constexpr</TT>
function<SPAN style="text-decoration:line-through;background-color:#FFA0A0">s</SPAN>, implicitly converting the resulting returned
expression or <I>braced-init-list</I> to the return type of the
function as if by copy-initialization.</P></LI>

</UL>

<P>Such substitution...</P>

</BLOCKQUOTE>

</OL>

<P>This resolution also resolves issues <A HREF="
     cwg_defects.html#1264">1264</A>
and <A HREF="
     cwg_defects.html#1367">1367</A>.</P>

<BR><BR><HR><A NAME="539"></A><H4>539.
  
Constraints on <I>type-specifier-seq</I>
</H4><B>Section: </B>7.1.6&#160; [dcl.type]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>5 October 2005<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>

<P>The constraints on <I>type-specifier</I>s given in
7.1.6 [dcl.type] paragraphs 2 and 3 (at most one
<I>type-specifier</I> except as specified, at least one
<I>type-specifier</I>, no redundant cv-qualifiers) are couched in
terms of <I>decl-specifier-seq</I>s and <I>declaration</I>s.  However,
they should also apply to constructs that are not syntactically
<I>declaration</I>s and that are defined to use
<I>type-specifier-seq</I>s, including 5.3.4 [expr.new],
6.6 [stmt.jump], 8.1 [dcl.name], and
12.3.2 [class.conv.fct].</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 7.1.6 [dcl.type] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">At</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Except in a declaration of a constructor,
destructor, or conversion function, at</SPAN> least one
<I>type-specifier</I> that is not a <I>cv-qualifier</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">is
required in a declaration unless it declares a constructor, destructor
or conversion function</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">shall appear in a complete
<I>type-specifier-seq</I> or a complete
<I>decl-specifier-seq</I></SPAN>.<SUP>92</SUP> A
<I>type-specifier-seq</I> shall not define...

</BLOCKQUOTE>

<P><I>(Note: paper N2546, voted into the Working Draft in February,
2008, addresses part of this issue.)</I></P>

<BR><BR><HR><A NAME="1265"></A><H4>1265.
  
Mixed use of the <TT>auto</TT> specifier
</H4><B>Section: </B>7.1.6.4&#160; [dcl.spec.auto]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Michael Wong
 &#160;&#160;&#160;

 <B>Date: </B>2011-03-20<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>

<P>The current wording of 7.1.6.4 [dcl.spec.auto] does not appear
to forbid using the <TT>auto</TT> specifier for both a function
declaration with a trailing return type and a variable definition in
the same declaration, e.g.,</P>

<PRE>
    auto f() -&gt; int, i = 0;
</PRE>

<P>(See also <A HREF="
     cwg_defects.html#1347">issue 1347</A>.)</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 7.1.6.4 [dcl.spec.auto] paragraph 7 as follows:</P>

<BLOCKQUOTE>

If the list of declarators contains more than one declarator,
<SPAN style="font-weight:bold;background-color:#A0FFA0">they shall all form declarations of variables. The</SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">the</SPAN> type of each declared variable is determined as
described above<SPAN style="text-decoration:line-through;background-color:#FFA0A0">. If</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">, and if</SPAN> the type deduced for
the template parameter <TT>U</TT> is not the same in each deduction,
the program is ill-formed. [<I>Example:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1346"></A><H4>1346.
  
<I>expression-list</I> initializers and the <TT>auto</TT> specifier
</H4><B>Section: </B>7.1.6.4&#160; [dcl.spec.auto]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-16<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>7.1.6.4 [dcl.spec.auto] does not address the case when the
initializer for an <TT>auto</TT> variable is a parenthesized
<I>expression-list</I>.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 7.1.6.4 [dcl.spec.auto] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<P>...<TT>auto</TT> shall appear as one of the <I>decl-specifier</I>s in
the <I>decl-specifier-seq</I> and the <I>decl-specifier-seq</I> shall
be followed by one or more <I>init-declarator</I>s, each of which
shall have a non-empty initializer. <SPAN style="font-weight:bold;background-color:#A0FFA0">In an <I>initializer</I> of
the form</SPAN></P>

<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>(</TT> <I>expression-list</I> <TT>)</TT></SPAN></UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">the <I>expression-list</I> shall be a single
<I>assignment-expression</I>.</SPAN> [<I>Example:</I>...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1347"></A><H4>1347.
  
Consistency of <TT>auto</TT> in multiple-declarator declarations
</H4><B>Section: </B>7.1.6.4&#160; [dcl.spec.auto]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-16<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>The intent of 7.1.6.4 [dcl.spec.auto] paragraph 7 appears to
have been that the type represented by <TT>auto</TT> should be the
same for each declarator in the declaration.  However, the current
wording does not achieve that goal.  For example, in</P>

<PRE>
    auto a = 0, b = { 1, 2, 2 };
</PRE>

<P>the <TT>auto</TT> specifier represents <TT>int</TT> in the
first declarator and <TT>std::initializer_list&lt;int&gt;</TT>
in the second.  (See also <A HREF="
     cwg_defects.html#1265">issue 1265</A>.)</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Move the example in 7.1.6.4 [dcl.spec.auto] paragraph 7 into
that of paragraph 6 and change paragraph 7 as follows:</P>

<BLOCKQUOTE>

<P>...[<I>Example:</I></P>

<PRE>
  auto x1 = { 1, 2 };   //<SPAN style="font-family:Times;font-style:italic"> </SPAN>decltype(x1)<SPAN style="font-family:Times;font-style:italic"> is </SPAN>std::initializer_list&lt;int&gt;
  auto x2 = { 1, 2.0 }; //<SPAN style="font-family:Times;font-style:italic"> error: cannot deduce element type</SPAN>

<SPAN style="font-weight:bold;background-color:#A0FFA0">  const auto &amp;i = expr;</SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">The type of <TT>i</TT> is the deduced type of the parameter
<TT>u</TT> in the call <TT>f(expr)</TT> of the following invented
function template:</SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  template &lt;class U&gt; void f(const U&amp; u);</SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

<P>If the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">list of declarators</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><i>init-declarator-list</i></SPAN> contains more than one
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">declarator</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>init-declarator</I></SPAN>, the type of
each declared variable is determined as described above. If the type
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">deduced for the template parameter <TT>U</TT></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">that
replaces the occurrence of <TT>auto</TT></SPAN> is not the same in each
deduction, the program is ill-formed.</P>

<P>[<I>Example:</I></P>

<PRE>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">  const auto &amp;i = expr;</SPAN>
</PRE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">The type of <TT>i</TT> is the deduced type of the parameter
<TT>u</TT> in the call <TT>f(expr)</TT> of the following invented
function template:</SPAN></P>

<PRE>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">  template &lt;class U&gt; void f(const U&amp; u);</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  auto x = 5, *y = &amp;x;       //<SPAN style="font-family:Times;font-style:italic"> OK: </SPAN>auto<SPAN style="font-family:Times;font-style:italic"> is </SPAN>int
  auto a = 5, b = { 1, 2 };  //<SPAN style="font-family:Times;font-style:italic"> error: different types for </SPAN>auto</SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1439"></A><H4>1439.
  
Lookup and friend template declarations
</H4><B>Section: </B>7.3.1.2&#160; [namespace.memdef]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2012-01-04<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>According to 7.3.1.2 [namespace.memdef] paragraph 3,</P>

<BLOCKQUOTE>

If a <TT>friend</TT> declaration in a non-local class first
declares a class or function<SUP>95</SUP> the friend class or
function is a member of the innermost enclosing namespace. The
name of the friend is not found by unqualified lookup
(3.4.1 [basic.lookup.unqual]) or by qualified lookup (3.4.3 [basic.lookup.qual]) until a matching declaration is provided in that
namespace scope (either before or after the class definition
granting friendship).

</BLOCKQUOTE>

<P>This wording does not, but probably should, apply to friend
declarations of function templates and class templates as well.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<OL><LI><P>Change 3.4.2 [basic.lookup.argdep] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...in those namespaces, namespace-scope friend function <SPAN style="font-weight:bold;background-color:#A0FFA0">or
function template</SPAN> declarations (11.3) not otherwise visible may
be found...

</BLOCKQUOTE>

<LI><P>Change 7.3.1.2 [namespace.memdef] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

Every name first declared in a namespace is a member of that
namespace. If a <TT>friend</TT> declaration in a non-local class first
declares a class<SPAN style="font-weight:bold;background-color:#A0FFA0">,</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN> function<SPAN style="font-weight:bold;background-color:#A0FFA0">, class
template, or function template</SPAN><SUP>95</SUP> the friend
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">class or function</SPAN> is a member of the innermost enclosing
namespace. The name of the friend is not found by unqualified lookup
(3.4.1 [basic.lookup.unqual]) or by qualified lookup (3.4.3 [basic.lookup.qual]) until a matching declaration is provided in that
namespace scope (either before or after the class definition granting
friendship). If a friend function <SPAN style="font-weight:bold;background-color:#A0FFA0">or function template</SPAN> is
called, its name may be found by the name lookup that considers
functions from namespaces and classes associated with the types of the
function arguments (3.4.2 [basic.lookup.argdep]).  If the name in a
<TT>friend</TT> declaration...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="565"></A><H4>565.
  
Conflict rules for <I>using-declaration</I>s naming function templates
</H4><B>Section: </B>7.3.3&#160; [namespace.udecl]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Paolo Carlini
 &#160;&#160;&#160;

 <B>Date: </B>9 March 2006<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>The Standard does not appear to specify what happens for code like the
following:</P>

<PRE>
    namespace one {
      template&lt;typename T&gt; void fun(T);
    }

    using one::fun;

    template&lt;typename T&gt; void fun(T);
</PRE>

<P>7.3.3 [namespace.udecl] paragraph 13 does not appear to apply
because it deals only with functions, not function templates:</P>

<BLOCKQUOTE>

If a function declaration in namespace scope or block scope has the
same name and the same parameter types as a function introduced by a
<I>using-declaration</I>, and the declarations do not declare the same
function, the program is ill-formed.

</BLOCKQUOTE>

<P><U>John Spicer</U>: For function templates I believe the rule
should be that if they have the same function type (parameter types
and return type) and have identical template parameter lists, the
program is ill-formed.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 7.3.3 [namespace.udecl] paragraph 14 as follows:</P>

<BLOCKQUOTE>

If a function declaration in namespace scope or block scope has the
same name and the same <SPAN style="text-decoration:line-through;background-color:#FFA0A0">parameter types</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">parameter-type-list (8.3.5 [dcl.fct])</SPAN> as a
function introduced by a <I>using-declaration</I>, and the
declarations do not declare the same function, the program is
ill-formed. <SPAN style="font-weight:bold;background-color:#A0FFA0">If a function template declaration in namespace
scope has the same name, parameter-type-list, return type, and
template parameter list as a function template introduced by a
<I>using-declaration</I>, the program is ill-formed.</SPAN>
[<I>Note:</I> Two <I>using-declaration</I>s may introduce functions
with the same name and the same <SPAN style="text-decoration:line-through;background-color:#FFA0A0">parameter types</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">parameter-type-list</SPAN>. If, for a call to an unqualified
function name, function overload resolution selects the functions
introduced by such <I>using-declaration</I>s, the function call is
ill-formed. [<I>Example:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1297"></A><H4>1297.
  
Misplaced function <I>attribute-specifier</I>
</H4><B>Section: </B>8&#160; [dcl.decl]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Nikolay Ivchenkov
 &#160;&#160;&#160;

 <B>Date: </B>2011-04-14<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>There is a contradiction between the grammar of 8 [dcl.decl]
paragraph 4 and that of 8.3.5 [dcl.fct] paragraphs 1 and 2 and
8.4.1 [dcl.fct.def.general] paragraph 2 regarding the placement of the
optional <I>exception-specification</I>: in the former, it immediately
follows the <I>parameter-declaration-clause</I>, while in the latter it
follows the <I>exception-specification</I>.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<OL><LI><P>Change the grammar in 8 [dcl.decl] paragraph 4
as follows:</P></LI>

<UL><I>parameters-and-qualifiers:</I>
<UL><TT>(</TT> <I>parameter-declaration-clause</I> <TT>)</TT> <I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">attribute-specifier-seq<SUB>opt</SUB></SPAN> cv-qualifier-seq<SUB>opt</SUB></I>
<UL><I>ref-qualifier<SUB>opt</SUB> exception-specification<SUB>opt</SUB> <SPAN style="font-weight:bold;background-color:#A0FFA0">attribute-specifier-seq<SUB>opt</SUB></SPAN></I></UL>
</UL>
</UL>

<LI><P>Change the grammar snippet in 13.3.1.1.2 [over.call.object]
paragraph 2 as follows:</P></LI>

<UL><TT>operator</TT> <I>conversion-type-id</I> <TT>( )</TT> <I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">attribute-specifier-seq<SUB>opt</SUB></SPAN> cv-qualifier <SPAN style="font-weight:bold;background-color:#A0FFA0">attribute-specifier-seq<SUB>opt</SUB></SPAN></I> <TT>;</TT></UL>

</OL>

<BR><BR><HR><A NAME="1382"></A><H4>1382.
  
Dead code for constructor names
</H4><B>Section: </B>8&#160; [dcl.decl]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Johannes Schaub
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-27<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P><A HREF="
     cwg_defects.html#147">Issue 147</A> changed the name lookup rules
so that a lookup that would have found the injected-class-name of a
class will refer to the constructor.  However, there still appear to
be vestiges of the earlier specification that were not removed by
the resolution.  For example, the grammar in 8 [dcl.decl]
paragraph 4 contains,</P>

<UL><I>declarator-id:</I>
<UL><TT>...</TT><I><SUB>opt</SUB> id-expression</I><BR>
<I>nested-name-specifier<SUB>opt</SUB> class-name</I>
</UL>
</UL>

<P>It would seem that there is no longer any need for the second
line, since a lookup for a <I>declarator-id</I> will not produce
a <I>class-name</I>.  Similarly, 5.1.1 [expr.prim.general]
paragraph 8 still contains the sentence,</P>

<BLOCKQUOTE>

Where <I>class-name</I> <TT>::</TT> <I>class-name</I> is used,
and the two <I>class-name</I>s refer to the same class, this
notation names the constructor (12.1 [class.ctor]).

</BLOCKQUOTE>

<P><B>Proposed resolution (February, 2012):</B></P>

<OL><LI><P>Change 8 [dcl.decl] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

<UL>...<BR>
<I>declarator-id:</I>
<UL><TT>...</TT><I><SUB>opt</SUB> id-expression</I><BR>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>nested-name-specifier<SUB>opt</SUB> class-name</I></SPAN>

</UL>

</UL>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">A <I>class-name</I> has special meaning in a declaration of the
class of that name and when qualified by that name using the scope
resolution operator <TT>::</TT> (,
12.1 [class.ctor], 12.4 [class.dtor]).</SPAN></P>

</BLOCKQUOTE>

<LI><P>Change 5.1.1 [expr.prim.general] paragraph 8 as follows:</P></LI>

<BLOCKQUOTE>

...[<I>Note:</I> a class member can be referred to using a
<I>qualified-id</I> at any point in its potential scope (3.3.7 [basic.scope.class]). &#8212;<I>end note</I>] <SPAN style="text-decoration:line-through;background-color:#FFA0A0">Where <I>class-name</I>
<TT>::</TT> <I>class-name</I> is used, and the two <I>class-name</I>s
refer to the same class, this notation names the constructor
(12.1 [class.ctor]).</SPAN> Where <I>class-name</I>
<TT>::~</TT>
<I>class-name</I> is used...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="482"></A><H4>482.
  
Qualified declarators in redeclarations
</H4><B>Section: </B>8.3&#160; [dcl.meaning]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>03 Nov 2004<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>

<P>According to 8.3 [dcl.meaning] paragraph 1,</P>

<BLOCKQUOTE>

A <I>declarator-id</I> shall not be qualified except for the
definition of a member function (9.3 [class.mfct]) or
static data member (9.4 [class.static]) outside of its
class, the definition or explicit instantiation of a function or
variable member of a namespace outside of its namespace, or the
definition of a previously declared explicit specialization
outside of its namespace, or the declaration of a friend function
that is a member of another class or namespace (11.3 [class.friend]). When the <I>declarator-id</I> is qualified, the
declaration shall refer to a previously declared member of the
class or namespace to which the qualifier refers...

</BLOCKQUOTE>

<P>This restriction prohibits examples like the following:</P>

<PRE>
    void f();
    void ::f();        // error: qualified declarator

    namespace N {
      void f();
      void N::f() { }  // error: qualified declarator
    }
</PRE>

<P>There doesn't seem to be any good reason for disallowing such
declarations, and a number of implementations accept them in
spite of the Standard's prohibition.  Should the Standard be
changed to allow them?</P>

<P><B>Notes from the April, 2006 meeting:</B></P>

<P>In discussing <A HREF="
     cwg_closed.html#548">issue 548</A>, the CWG agreed
that the prohibition of qualified declarators inside their namespace
should be removed.</P>

<P><B>Proposed resolution (October, 2006):</B></P>

<P>Remove the indicated words from 8.3 [dcl.meaning]
paragraph 1:</P>

<BLOCKQUOTE>

...An <I>unqualified-id</I> occurring in a <I>declarator-id</I> shall
be a simple <I>identifier</I> except for the declaration of some
special functions (12.3 [class.conv], 12.4 [class.dtor], 13.5 [over.oper]) and for the declaration of
template specializations or partial specializations (). <SPAN style="text-decoration:line-through;background-color:#FFA0A0">A <I>declarator-id</I> shall not be qualified
except for the definition of a member function (9.3 [class.mfct]) or static data member (9.4 [class.static])
outside of its class, the definition or explicit instantiation of a
function or variable member of a namespace outside of its namespace,
or the definition of a previously declared explicit specialization
outside of its namespace, or the declaration of a friend function that
is a member of another class or namespace (11.3 [class.friend]).</SPAN> When the <I>declarator-id</I> is qualified, the
declaration shall refer to a previously declared member of the class
or namespace to which the qualifier refers, and the member shall not
have been introduced by a <I>using-declaration</I> in the scope of the
class or namespace nominated by the <I>nested-name-specifier</I> of
the <I>declarator-id</I>...

</BLOCKQUOTE>

<P>[<I>Drafting note:</I> The omission of &#8220;outside of its
class&#8221; here does not give permission for redeclaration of
class members; that is still prohibited by 9.2 [class.mem]
paragraph 1.  The removal of the enumeration of the kinds of
declarations in which a <I>qualified-id</I> can appear does allow
a <TT>typedef</TT> declaration to use a <I>qualified-id</I>, which
was not permitted before; if that is undesirable, the prohibition can
be reinstated here.]</P>

<BR><BR><HR><A NAME="332"></A><H4>332.
  
cv-qualified <TT>void</TT> parameter types
</H4><B>Section: </B>8.3.5&#160; [dcl.fct]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Michiel Salters
 &#160;&#160;&#160;

 <B>Date: </B>9 Jan 2002<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>

<P>8.3.5 [dcl.fct]/2 restricts the use of void
as parameter type, but does not
mention CV qualified versions. Since <TT>void f(volatile void)</TT>
isn't a callable
function anyway, 8.3.5 [dcl.fct]
should also ban cv-qualified versions.
(BTW, this follows C)</P>

<P><B>Suggested resolution:</B></P>

<P>A possible resolution would be to add (cv-qualified) before void in</P>
<BLOCKQUOTE>
The parameter list <TT>(void)</TT> is equivalent to the empty
parameter list. Except
for this special case, <SPAN style="font-weight:bold;background-color:#A0FFA0">(cv-qualified)</SPAN> <TT>void</TT> shall
not be a parameter type (though types derived from <TT>void</TT>, such as
<TT>void*</TT>, can).
</BLOCKQUOTE>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#577">issue 577</A>.</P>

<BR><BR><HR><A NAME="577"></A><H4>577.
  
<TT>void</TT> in an empty parameter list
</H4><B>Section: </B>8.3.5&#160; [dcl.fct]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Ben Hutchings
 &#160;&#160;&#160;

 <B>Date: </B>22 April 2006<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>

<P>8.3.5 [dcl.fct] paragraph 2 says,</P>

<BLOCKQUOTE>

The parameter list <TT>(void)</TT> is equivalent to the empty
parameter list.

</BLOCKQUOTE>

<P>This special case is intended for C compatibility, but C99 describes
it differently (6.7.5.3 paragraph 10):</P>

<BLOCKQUOTE>

The special case of an unnamed parameter of type <TT>void</TT> as the
only item in the list specifies that the function has no parameters.

</BLOCKQUOTE>

<P>The C99 formulation allows typedefs for <TT>void</TT>, while C++
(and C90) accept only the keyword itself in this role.  Should the
C99 approach be adopted?</P>

<P><B>Notes from the October, 2006 meeting:</B></P>

<P>The CWG did not take a formal position on this issue; however,
there was some concern expressed over the treatment of function
templates and member functions of class templates if the C++ rule
were changed: for a template parameter <TT>T</TT>, would a function
taking a single parameter of type <TT>T</TT> become a no-parameter
function if it were instantiated with <TT>T = void</TT>?</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 8.3.5 [dcl.fct] paragraph 4 as follows:</P>

<BLOCKQUOTE>

...If the <I>parameter-declaration-clause</I> is empty, the function
takes no arguments.  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The parameter list <TT>(void)</TT></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">A parameter list consisting of a single unnamed parameter of
non-dependent type <TT>void</TT></SPAN> is equivalent to <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">an</SPAN> empty parameter list.  Except for this special case,
<SPAN style="font-weight:bold;background-color:#A0FFA0">a parameter shall not have type <I>cv</I></SPAN> <TT>void</TT>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">shall not be a parameter type (though types derived from
<TT>void</TT>, such as <TT>void*</TT>, can)</SPAN>.  If the
<I>parameter-declaration-clause</I> terminates...

</BLOCKQUOTE>

<P>This resolution also resolves <A HREF="
     cwg_defects.html#332">issue 332</A>.</P>

<BR><BR><HR><A NAME="1380"></A><H4>1380.
  
Type definitions in <I>template-parameter</I> <I>parameter-declaration</I>s
</H4><B>Section: </B>8.3.5&#160; [dcl.fct]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-22<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>Although 8.3.5 [dcl.fct] paragraph 9 forbids defining a
type in a parameter declaration, and a template parameter declaration is
syntactically a <I>parameter-declaration</I>, the context in
8.3.5 [dcl.fct] function declarators.  It's therefore not
completely clear that that prohibition applies to template parameter
declarations as well.  This should be clarified.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 14.1 [temp.param] paragraph 2 as follows:</P>

<BLOCKQUOTE>

...A storage class shall not be specified in a
<I>template-parameter</I> declaration. <SPAN style="font-weight:bold;background-color:#A0FFA0">Types shall not be defined
in a <I>template-parameter</I> declaration.</SPAN> [<I>Note:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1394"></A><H4>1394.
  
Incomplete types as parameters of deleted functions
</H4><B>Section: </B>8.3.5&#160; [dcl.fct]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Johannes Schaub
 &#160;&#160;&#160;

 <B>Date: </B>2011-09-11<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>Currently, 8.3.5 [dcl.fct] paragraph 9 requires that</P>

<BLOCKQUOTE>

The type of a parameter or the return type for a function
definition shall not be an incomplete class type (possibly
cv-qualified) unless the function definition is nested within the
member-specification for that class (including definitions in
nested classes defined within the class).

</BLOCKQUOTE>

<P>There is no reason for this requirement for a function with a
deleted definition, and it would be useful to relax this prohibition
in such cases.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 8.3.5 [dcl.fct] paragraph 9 as follows:</P>

<BLOCKQUOTE>

Types shall not be defined in return or parameter types.  The type of
a parameter or the return type for a function definition shall not be
an incomplete class type (possibly cv-qualified) unless the function
<SPAN style="font-weight:bold;background-color:#A0FFA0">is deleted (8.4.3 [dcl.fct.def.delete]) or the</SPAN> definition
is nested within the <I>member-specification</I> for that class
(including definitions in nested classes defined within the class).

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1226"></A><H4>1226.
  
Converting a <I>braced-init-list</I> default argument
</H4><B>Section: </B>8.3.6&#160; [dcl.fct.default]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>2010-11-19<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>

<P>According to the new wording of 8.3.6 [dcl.fct.default]
paragraph 5,</P>

<BLOCKQUOTE>

A default argument is implicitly converted (Clause 4 [conv]) to the parameter type.

</BLOCKQUOTE>

<P>This is incorrect when the default argument is a
<I>braced-init-list</I>.  That sentence doesn't seem to be necessary,
but if it is kept, it should be recast in terms of initialization
rather than conversion.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Delete the first sentence of 8.3.6 [dcl.fct.default]
paragraph 5:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A default argument is implicitly converted (Clause 4 [conv]) to the parameter type.</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1327"></A><H4>1327.
  
<I>virt-specifier</I> in a defaulted definition
</H4><B>Section: </B>8.4.2&#160; [dcl.fct.def.default]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Ryou Ezoe
 &#160;&#160;&#160;

 <B>Date: </B>2011-05-29<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>The grammar for defaulted and deleted functions in
8.4.2 [dcl.fct.def.default] and 8.4.3 [dcl.fct.def.delete] does not
provide for <I>virt-specifier</I>s.  Is there a reason for this
omission, or was it inadvertent?</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<OL><LI><P>Change 8.4.2 [dcl.fct.def.default] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<P>A function definition of the form:</P>

<UL><I>attribute-specifier-seq<SUB>opt</SUB> decl-specifier-seq<SUB>opt</SUB> declarator <SPAN style="font-weight:bold;background-color:#A0FFA0">virt-specifier-seq<SUB>opt</SUB></SPAN></I> <TT>= default ;</TT></UL>

<P>is called an <I>explicitly-defaulted</I> definition...</P>

</BLOCKQUOTE>

<LI><P>Change 8.4.3 [dcl.fct.def.delete] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<P>A function definition of the form:</P>

<UL><I>attribute-specifier-seq<SUB>opt</SUB> decl-specifier-seq<SUB>opt</SUB> declarator <SPAN style="font-weight:bold;background-color:#A0FFA0">virt-specifier-seq<SUB>opt</SUB></SPAN></I> <TT>= delete ;</TT></UL>

<P>is called a <I>deleted definition</I>...</P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1333"></A><H4>1333.
  
Omission of <TT>const</TT> in a defaulted copy constructor
</H4><B>Section: </B>8.4.2&#160; [dcl.fct.def.default]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2011-06-21<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>Paragraph 1 of 8.4.2 [dcl.fct.def.default] allows an explicitly-defaulted
copy constructor or copy assignment operator to have a parameter type
that is a reference to non-const, even if the corresponding
implicitly-declared function would have a reference to const.  However,
paragraph 2 says that a copy constructor or copy assignment operator that
is defaulted on its first declaration, the parameter type must be exactly
the same.  Is there a good reason for the stricter rule for a function
that is defaulted on its first declaration?</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<OL><LI><P>Change 8.4.2 [dcl.fct.def.default] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

<P>...If a function is explicitly defaulted on its first declaration,</P>

<UL><LI><P>...</P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">in the case of a copy constructor, move constructor, copy
assignment operator, or move assignment operator, it shall have the
same parameter type as if it had been implicitly
declared.</SPAN></P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraph 12 as follows:</P></LI>

<BLOCKQUOTE>

A copy/move constructor for class <TT>X</TT> is trivial if it is not
user-provided<SPAN style="font-weight:bold;background-color:#A0FFA0">, its declared parameter type is the same as if it
had been implicitly declared,</SPAN> and if...

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraph 25 as follows:</P></LI>

<BLOCKQUOTE>

A copy/move assignment operator for class X is trivial if it is not
user-provided<SPAN style="font-weight:bold;background-color:#A0FFA0">, its declared parameter type is the same as if it
had been implicitly declared,</SPAN> and if...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1355"></A><H4>1355.
  
Aggregates and &#8220;user-provided&#8221; constructors
</H4><B>Section: </B>8.4.2&#160; [dcl.fct.def.default]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Sean Hunt
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-16<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>The definition of &#8220;user-provided&#8221; given in
8.4.2 [dcl.fct.def.default] paragraph 4 applies only to special
member functions, while the definition of an aggregate in
8.5.1 [dcl.init.aggr] paragraph 1 relies on that term in
identifying constructors that make a class a non-aggregate.  As
a result, a class with a non-special constructor is considered
an aggregate.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 8.4.2 [dcl.fct.def.default] paragraph 4 as follows:</P>

<BLOCKQUOTE>

A <SPAN style="text-decoration:line-through;background-color:#FFA0A0">special member</SPAN> function is user-provided if it is
user-declared and not explicitly defaulted or deleted on its first
declaration...

</BLOCKQUOTE>

<P><I>[Drafting note: This makes a class with only a deleted
initializer-list constructor an aggregate.]</I></P>

<BR><BR><HR><A NAME="1093"></A><H4>1093.
  
Value-initializing non-objects
</H4><B>Section: </B>8.5&#160; [dcl.init]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2010-07-17<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>

<P>8.5 [dcl.init] paragraph 7 only describes how to
initialize objects:</P>

<BLOCKQUOTE>

To <I>value-initialize</I> an object of type <TT>T</TT> means:

</BLOCKQUOTE>

<P>However, 5.2.3 [expr.type.conv] paragraph 2 calls for
value-initializing prvalues, which in the case of scalar types
are not objects:</P>

<BLOCKQUOTE>

The expression <TT>T()</TT>, where <TT>T</TT> is a
<I>simple-type-specifier</I> or <I>typename-specifier</I>
for a non-array complete object type or the (possibly
cv-qualified) <TT>void</TT> type, creates a prvalue of the
specified type, which is value-initialized (8.5 [dcl.init]; no initialization is done for the
<TT>void()</TT> case).

</BLOCKQUOTE>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 5.2.3 [expr.type.conv] paragraph 2 as follows:</P>

<BLOCKQUOTE>

The expression <TT>T()</TT>, where <TT>T</TT> is a
<I>simple-type-specifier</I> or <I>typename-specifier</I> for a
non-array complete object type or the (possibly cv-qualified)
<TT>void</TT> type, creates a prvalue of the specified <SPAN style="text-decoration:line-through;background-color:#FFA0A0">type,which
is value-initialized (8.5 [dcl.init]</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">type, whose
value is that produced by value-initializing (8.5 [dcl.init]) an object of type <TT>T</TT></SPAN>; no initialization is
done for the <TT>void()</TT> case<SPAN style="text-decoration:line-through;background-color:#FFA0A0">)</SPAN>. [<I>Note:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1301"></A><H4>1301.
  
Value initialization of union
</H4><B>Section: </B>8.5&#160; [dcl.init]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2011-04-18<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>According to 8.5 [dcl.init] paragraph 7,</P>

<BLOCKQUOTE>

<P>To <I>value-initialize</I> an object of type <TT>T</TT> means:</P>

<UL><LI><P>if <TT>T</TT> is a (possibly cv-qualified) class type
(Clause 9 [class]) with a user-provided constructor
(12.1 [class.ctor]), then the default constructor for
<TT>T</TT> is called (and the initialization is ill-formed if
<TT>T</TT> has no accessible default constructor);
</P></LI>

<LI><P>if <TT>T</TT> is a (possibly cv-qualified) non-union class type
without a user-provided constructor, then the object is
zero-initialized and, if <TT>T</TT>'s implicitly-declared default
constructor is non-trivial, that constructor is called.
</P></LI>

<LI><P>if <TT>T</TT> is an array type, then each element is
value-initialized;
</P></LI>

<LI><P>otherwise, the object is zero-initialized.
</P></LI>

</UL>

</BLOCKQUOTE>

<P>This suggests that for</P>

<PRE>
  struct A { A() = delete; };
  union B { A a };
  int main()
  {
    B();
  }
</PRE>

<P>a <TT>B</TT> temporary is created and zero-initialized, even though
its default constructor is deleted.  We should strike "non-union" and
also the "if...non-trivial" condition, since we can have a trivial
deleted constructor.
</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<OL><LI><P>Change 8.5 [dcl.init] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

<P>To <I>value-initialize</I> an object of type <TT>T</TT> means:</P>

<UL><LI><P>if <TT>T</TT> is a (possibly cv-qualified) class type
(Clause 9 [class]) with <SPAN style="font-weight:bold;background-color:#A0FFA0">either no default
constructor (12.1 [class.ctor]) or</SPAN> a <SPAN style="font-weight:bold;background-color:#A0FFA0">default
constructor that is</SPAN> user-provided <SPAN style="font-weight:bold;background-color:#A0FFA0">or deleted</SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">constructor (12.1 [class.ctor])</SPAN>, then the
<SPAN style="font-weight:bold;background-color:#A0FFA0">object is default-initialized</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">default constructor for
<TT>T</TT> is called (and the initialization is ill-formed if
<TT>T</TT> has no accessible default constructor)</SPAN>;</P></LI>

<LI><P>if <TT>T</TT> is a (possibly cv-qualified) non-union class type
without a user-provided <SPAN style="font-weight:bold;background-color:#A0FFA0">or deleted default</SPAN> constructor,
then the object is zero-initialized and, if <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>T</TT>'s
implicitly-declared default constructor is</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>T</TT> has
a</SPAN> non-trivial <SPAN style="font-weight:bold;background-color:#A0FFA0">default constructor</SPAN>, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">that
constructor is called.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">default-initialized;</SPAN></P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 8.5.4 [dcl.init.list] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

<P>List-initialization of an object or reference of type <TT>T</TT> is
defined as follows:</P>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">If the initializer list has no elements and <TT>T</TT>
is a class type with a default constructor, the object is
value-initialized.</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">Otherwise, if</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">If</SPAN> <TT>T</TT> is an
aggregate, aggregate initialization is performed (8.5.1 [dcl.init.aggr]). [<I>Example:</I>...</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">Otherwise, if the initializer list has no elements and
<TT>T</TT> is a class type with a default constructor, the object is
value-initialized.</SPAN></P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

</OL>

<P>This resolution also resolves issues <A HREF="
     cwg_defects.html#1324">1324</A>
and <A HREF="
     cwg_defects.html#1368">1368</A>.</P>

<BR><BR><HR><A NAME="1324"></A><H4>1324.
  
Value initialization and defaulted constructors
</H4><B>Section: </B>8.5&#160; [dcl.init]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2011-05-22<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>One would expect that an example like</P>

<PRE>
  struct B {
   B(const B&amp;) = default;
  };

  B b{};
</PRE>

<P>would invoke value-initialization, but (because it does not have a
default constructor), the logic ladder of 8.5.4 [dcl.init.list]
paragraph 3 makes it aggregate initialization instead:</P>

<UL><LI><P>If the initializer list has no elements and <TT>T</TT> is a
class type with a default constructor, the object is
value-initialized.
</P></LI>

<LI><P>Otherwise, if <TT>T</TT> is an aggregate, aggregate
initialization is performed (8.5.1 [dcl.init.aggr]).
</P></LI>

</UL>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#1301">issue 1301</A>.</P>

<BR><BR><HR><A NAME="1368"></A><H4>1368.
  
Value initialization and defaulted constructors (part 2)
</H4><B>Section: </B>8.5&#160; [dcl.init]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2011-06-28<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>According to the current rules of 8.5 [dcl.init], given
a class like</P>

<PRE>
  struct A {
    int i;
    A() = default;
    A(int i): i(i) { }
  };
</PRE>

<P>value-initialization leaves <TT>A::i</TT> uninitialized.  This seems
like an oversight.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#1301">issue 1301</A>.</P>

<BR><BR><HR><A NAME="1295"></A><H4>1295.
  
Binding a reference to an rvalue bit-field
</H4><B>Section: </B>8.5.3&#160; [dcl.init.ref]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Nikolay Ivchenkov
 &#160;&#160;&#160;

 <B>Date: </B>2011-04-14<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>Consider the following example:</P>

<PRE>
  struct X {
    unsigned bitfield : 4;
  };
  int main() {
    X x = { 1 };
    unsigned const &amp;ref = static_cast&lt;X &amp;&amp;&gt;(x).bitfield;
  }
</PRE>

<P>According to 8.5.3 [dcl.init.ref] paragraph 5, <TT>ref</TT>
is bound to the bit-field xvalue.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change the indicated sub-bullet of 8.5.3 [dcl.init.ref]
paragraph 5 as follows:</P>

<UL><LI><P>is an xvalue <SPAN style="font-weight:bold;background-color:#A0FFA0">(but is not a bit-field)</SPAN>, class
prvalue, array prvalue or function lvalue and &#8220;<I>cv1</I>
<TT>T1</TT>&#8221; is reference-compatible with &#8220;<I>cv2</I>
<TT>T2</TT>&#8221;, or</P></LI></UL>

<BR><BR><HR><A NAME="1401"></A><H4>1401.
  
Similar types and reference compatibility
</H4><B>Section: </B>8.5.3&#160; [dcl.init.ref]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2011-10-03<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>The definition of reference-compatible types in
8.5.3 [dcl.init.ref] paragraph 4 allows the types to differ
in top-level cv-qualification, but it does not encompass the deeper
added cv-qualification permitted for &#8220;similar types&#8221;
(4.4 [conv.qual]).  This seems surprising and could lead
to errors resulting from the fact that the reference will be bound
to a temporary and not to the original object in the initializer.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<OL><LI><P>Change 8.5.3 [dcl.init.ref] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

Given types &#8220;<I>cv1</I> <TT>T1</TT>&#8221; and &#8220;<I>cv2</I>
<TT>T2</TT>,&#8221; &#8220;<I>cv1</I> <TT>T1</TT>&#8221; is
reference-related to &#8220;<I>cv2</I> <TT>T2</TT>&#8221; if
<TT>T1</TT> is the same type as <TT>T2</TT>, or <TT>T1</TT> is a base
class of <TT>T2</TT>. &#8220;<I>cv1</I> <TT>T1</TT>&#8221; is
reference-compatible with &#8220;<I>cv2</I> <TT>T2</TT>&#8221; if
<TT>T1</TT> is reference-related to <TT>T2</TT> and <I>cv1</I> is the
same cv-qualification as, or greater cv-qualification than,
<I>cv2</I>.  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">For purposes of overload resolution, cases for which
<I>cv1</I> is greater cv-qualification than <I>cv2</I> are identified
as <I>reference-compatible with added qualification</I> (see
13.3.3.2 [over.ics.rank]).</SPAN>  In all cases...

</BLOCKQUOTE>

<LI><P>Delete 13.3.3.1.4 [over.ics.ref] paragraph 5:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The binding of a reference to an expression that is
<I>reference-compatible with added qualification</I> influences the
rank of a standard conversion; see 13.3.3.2 [over.ics.rank] and
8.5.3 [dcl.init.ref].</SPAN>

</BLOCKQUOTE>

<P><I>[Drafting note: CWG decided not to make a substantive change for
this issue, but the investigation discovered that the term defined by
these two citations is not actually used and could be
removed.]</I></P>

</OL>

<BR><BR><HR><A NAME="1270"></A><H4>1270.
  
Brace elision in array temporary initialization
</H4><B>Section: </B>8.5.4&#160; [dcl.init.list]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2011-03-23<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>

<P><A HREF="
     cwg_defects.html#1232">Issue 1232</A> extended the language to allow
creation of array temporaries using initializer lists.  However, such
initializer lists must be &#8220;completely braced;&#8221; the elision
of braces described in 8.5.1 [dcl.init.aggr] paragraph 11 applies
only</P>

<BLOCKQUOTE>

<P>In a declaration of the form</P>

<PRE>
  T x = { a };
</PRE>

</BLOCKQUOTE>

<P>This restriction prevents plausible uses like</P>

<PRE>
    array&lt;int, 3&gt; f() {
      return { 1, 2, 3 };
    }
</PRE>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 8.5.1 [dcl.init.aggr] paragraph 11 as follows:</P>

<BLOCKQUOTE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">In a declaration of the form</SPAN></P>

<UL><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>T x = { a };</TT></SPAN></UL>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">braces</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Braces</SPAN> can be elided in an
<I>initializer-list</I> as follows.  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">[<I>Footnote:</I> Braces
cannot be elided in other uses of list-initialization. &#8212;<I>end
footnote</I>]</SPAN></P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1288"></A><H4>1288.
  
Reference list initialization
</H4><B>Section: </B>8.5.4&#160; [dcl.init.list]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2011-04-06<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>One might expect that in an example like</P>

<PRE>
  int i;
  int &amp; ir{i};
</PRE>

<P><TT>ir</TT> would bind directly to <TT>i</TT>.  However, according
to 8.5.4 [dcl.init.list] paragraph 3, this example creates a
temporary of type <TT>int</TT> and binds the reference to that
temporary:</P>

<BLOCKQUOTE>

<UL><LI><P>...</P></LI>

<LI><P>Otherwise, if <TT>T</TT> is a reference type, a prvalue
temporary of the type referenced by <TT>T</TT> is list-initialized,
and the reference is bound to that temporary...
</P></LI>

<LI><P>Otherwise, if the initializer list has a single element, the
object or reference is initialized from that element...
</P></LI>

</UL>

</BLOCKQUOTE>

<P>Also, the &#8220;or reference&#8221; in the last bullet is dead
code, as a reference initialization is always handled by the preceding
bullet.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 8.5.4 [dcl.init.list] paragraph 3 as follows:</P>

<UL><LI><P>...</P></LI>

<LI><P>Otherwise, if <TT>T</TT> is a class type, constructors are
considered...</P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">Otherwise, if <TT>T</TT> is a reference type, a prvalue
temporary of the type referenced by <TT>T</TT> is list-initialized,
and the reference is bound to that temporary. [<I>Note:</I> As usual,
the binding will fail and the program is ill-formed if the reference
type is an lvalue reference to a non-const type. &#8212;<I>end
note</I>] [<I>Example:</I> ... &#8212;<I>end
example</I>]</SPAN></P></LI>

<LI><P>Otherwise, if the initializer list has a single element <SPAN style="font-weight:bold;background-color:#A0FFA0">of
type <TT>E</TT> and either <TT>T</TT> is not a reference type or its
referenced type is reference-related to <TT>E</TT></SPAN>, the object
or reference is initialized from that element; if a narrowing
conversion (see below) is required to convert the element to
<TT>T</TT>, the program is ill-formed. [<I>Example:</I>...</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">Otherwise, if <TT>T</TT> is a reference type, a prvalue
temporary of the type referenced by <TT>T</TT> is list-initialized,
and the reference is bound to that temporary. [<I>Note:</I> As usual,
the binding will fail and the program is ill-formed if the reference
type is an lvalue reference to a non-const type. &#8212;<I>end
note</I>] [<I>Example:</I> ... &#8212;<I>end
example</I>]</SPAN></P></LI>

<LI><P>Otherwise, if the initializer list has no elements...</P></LI>

<LI><P>...</P></LI>

</UL>

<BR><BR><HR><A NAME="1290"></A><H4>1290.
  
Lifetime of the underlying array of an <TT>initializer_list</TT> member
</H4><B>Section: </B>8.5.4&#160; [dcl.init.list]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>James Dennett
 &#160;&#160;&#160;

 <B>Date: </B>2011-04-08<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>A question has arisen over expected behavior when an
<TT>initializer_list</TT> is a non-static data member of a class.
Initialization of an <TT>initializer_list</TT> is defined in terms of
construction from an implicitly allocated array whose lifetime "is the
same as that of the <TT>initializer_list</TT> object".  That would
mean that the array needs to live as long as the
<TT>initializer_list</TT> does, which would on the face of it appear
to require the array to be stored in something like a
<TT>std::unique_ptr&lt;T[]&gt;</TT> within the same class (if the
member is initialized in this manner).
</P>

<P>It would be surprising if that was the intent, but it would make
<TT>initializer_list</TT> usable in this context.
</P>

<P>It would also be reasonable if this behaved similarly to binding
temporaries to reference members (i.e., "temporary bound to a
reference member in a constructor's <I>ctor-initializer</I>
(12.6.2 [class.base.init]) persists until the constructor exits."),
though this approach would probably prevent use of an
<TT>initializer_list</TT> member in that context.
</P>



<P><B>Proposed resolution (February, 2012):</B></P>

<OL><LI><P>Change 8.5.4 [dcl.init.list] paragraphs 5-6 as
follows:</P></LI>

<BLOCKQUOTE>

<P>An object of type <TT>std::initializer_list&lt;E&gt;</TT> is
constructed from an initializer list as if the implementation
allocated <SPAN style="text-decoration:line-through;background-color:#FFA0A0">an</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">a temporary</SPAN> array of <I>N</I>
elements of type <TT>E</TT>, where...</P>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">The lifetime of the array is the same as that of the
<TT>initializer_list</TT> object.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">The array has the same
lifetime as any other temporary object (12.2 [class.temporary]),
except that initializing an <TT>initializer_list</TT> object from the
array extends the lifetime of the array exactly like binding a
reference to a temporary.</SPAN> [<I>Example:</I></P>

<PRE>
  typedef std::complex&lt;double&gt; cmplx;
  std::vector&lt;cmplx&gt; v1 = { 1, 2, 3 };

  void f() {
    std::vector&lt;cmplx&gt; v2{ 1, 2, 3 };
    std::initializer_list&lt;int&gt; i3 = { 1, 2, 3 };
  }

<SPAN style="font-weight:bold;background-color:#A0FFA0">  struct A {
    std::initializer_list&lt;int&gt; i4;
    A(): i4{1,2,3} { }  //<SPAN style="font-family:Times;font-style:italic"> creates an </SPAN>A<SPAN style="font-family:Times;font-style:italic"> with a dangling reference</SPAN>
  };</SPAN>
</PRE>

<P>For <TT>v1</TT> and <TT>v2</TT>, the <TT>initializer_list</TT> object
<SPAN style="font-weight:bold;background-color:#A0FFA0">is a parameter in a function call, so the</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">and</SPAN>
array created for <TT>{ 1, 2, 3 }</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">have</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">has</SPAN>
full-expression lifetime. For <TT>i3</TT>, the
<TT>initializer_list</TT> object <SPAN style="font-weight:bold;background-color:#A0FFA0">is a variable, so the</SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">and</SPAN> array <SPAN style="text-decoration:line-through;background-color:#FFA0A0">have automatic</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">persists for
the</SPAN> lifetime <SPAN style="font-weight:bold;background-color:#A0FFA0">of the variable.  For <TT>i4</TT>, the
<TT>initializer_list</TT> object is initialized in a constructor's
<I>ctor-initializer</I>, so the array persists only until the
constructor exits, and so any use of the elements of <TT>i4</TT> after
the constructor exits produces undefined behavior</SPAN>. &#8212;<I>end
example</I>] [<I>Note:</I> The implementation is free to allocate the
array in read-only memory if an explicit array with the same
initializer could be so allocated. &#8212;<I>end note</I>]</P>

</BLOCKQUOTE>

<LI><P>Change 12.2 [class.temporary] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

The second context is when a reference is bound to a temporary.
<SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Footnote:</I> The same rules apply to initialization of an
<TT>initializer_list</TT> object (8.5.4 [dcl.init.list]) with its
underlying temporary array. &#8212;<I>end footnote</I>]</SPAN> The
temporary to which...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1418"></A><H4>1418.
  
Type of <TT>initializer_list</TT> backing array </H4><B>Section: </B>8.5.4&#160; [dcl.init.list]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Johannes Schaub
 &#160;&#160;&#160;

 <B>Date: </B>2011-11-19<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>According to 8.5.4 [dcl.init.list] paragraph 5, the
elements of the backing array for an object of type
<TT>std::initializer_list&lt;E&gt;</TT> are of type
<TT>E</TT>.  This is contradicted by the wording of
18.9 [support.initlist] paragraph 2.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 8.5.4 [dcl.init.list] paragraph 5 as follows:</P>

<BLOCKQUOTE>

<P>An object of type <TT>std::initializer_list&lt;E&gt;</TT> is
constructed from an initializer list as if the implementation
allocated an array of <I>N</I> elements of type <TT><SPAN style="font-weight:bold;background-color:#A0FFA0">const</SPAN>
E</TT>, where <I>N</I> is the number of elements in the initializer
list.  Each element of that array is copy-initialized with the
corresponding element of the initializer list, and the
<TT>std::initializer_list&lt;E&gt;</TT> object is constructed to refer
to that array.  If a narrowing conversion is required to initialize
any of the elements, the program is ill-formed. [<I>Example:</I></P>

<PRE>
  struct X {
    X(std::initializer_list&lt;double&gt; v);
  };
  X x{ 1,2,3 };
</PRE>

<P>The initialization will be implemented in a way roughly equivalent
to this:</P>

<PRE>
  <SPAN style="font-weight:bold;background-color:#A0FFA0">const</SPAN> double __a[3] = {double{1}, double{2}, double{3}};
  X x(std::initializer_list&lt;double&gt;(__a, __a+3));
</PRE>

<P>assuming that the implementation can construct an initializer_list
object with a pair of pointers. &#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1449"></A><H4>1449.
  
Narrowing conversion of negative value to unsigned type
</H4><B>Section: </B>8.5.4&#160; [dcl.init.list]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2012-01-28<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>According to 8.5.4 [dcl.init.list] paragraph 7, an implicit
conversion</P>

<BLOCKQUOTE>

from an integer type or unscoped enumeration type to an integer type
that cannot represent all the values of the original type, except
where the source is a constant expression and the actual value after
conversion will fit into the target type and will produce the original
value when converted back to the original type.

</BLOCKQUOTE>

<P>As is made plain in the examples in that paragraph, a conversion of
a negative value to an unsigned type is intended to be a narrowing
conversion; however, the phrase &#8220;actual value after
conversion&#8221; makes this intent unclear, especially since the
round-trip conversion between signed and unsigned types might well
yield the original value.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 8.5.4 [dcl.init.list] paragraph 7 as follows:</P>

<BLOCKQUOTE>

<P>A <I>narrowing conversion</I> is an implicit conversion</P>

<UL><LI><P>...</P></LI>

<LI><P>from an integer type or unscoped enumeration type to an integer
type that cannot represent all the values of the original type, except
where the source is a constant expression <SPAN style="text-decoration:line-through;background-color:#FFA0A0">and the actual value
after conversion</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">whose value after integral
promotions</SPAN> will fit into the target type <SPAN style="text-decoration:line-through;background-color:#FFA0A0">and will produce the
original value when converted back to the original type</SPAN>.</P></LI>

</UL>

<P>[<I>Note:</I>...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1363"></A><H4>1363.
  
Triviality vs multiple default constructors
</H4><B>Section: </B>9&#160; [class]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Sean Hunt
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-16<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>The requirements for a trivial class include having &#8220;a trivial
default constructor&#8221; (9 [class] paragraph 6).
However, with an explicitly-defaulted default constructor and other
constructors with default arguments, it is possible to have multiple
default constructors.  Such a class cannot be default-initialized and
thus should probably be considered non-trivial.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 9 [class] paragraph 6 as follows:</P>

<BLOCKQUOTE>

...A <I>trivial class</I> is a class that has a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">trivial</SPAN>
default constructor (12.1 [class.ctor])<SPAN style="font-weight:bold;background-color:#A0FFA0">, has no
non-trivial default constructors,</SPAN> and is trivially
copyable...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1308"></A><H4>1308.
  
Completeness of class type within an <I>exception-specification</I>
</H4><B>Section: </B>9.2&#160; [class.mem]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Nikolay Ivchenkov
 &#160;&#160;&#160;

 <B>Date: </B>2011-05-03<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>According to 9.2 [class.mem] paragraph 2,</P>

<BLOCKQUOTE>

A class is considered a completely-defined object type (3.9 [basic.types]) (or complete type) at the closing <TT>}</TT> of the
<I>class-specifier</I>.  Within the class <I>member-specification</I>,
the class is regarded as complete within function bodies, default
arguments, <I>exception-specification</I>s, and
<I>brace-or-equal-initializer</I>s for non-static data members
(including such things in nested classes).  Otherwise it is regarded
as incomplete within its own class <I>member-specification</I>.

</BLOCKQUOTE>

<P>With the advent of the <TT>noexcept</TT> operator, treating the
class type as complete in <I>exception-specification</I>s is obviously
not possible, e.g.,</P>

<PRE>
  struct X {
    //<SPAN style="font-family:Times;font-style:italic"> should </SPAN>X<SPAN style="font-family:Times;font-style:italic"> be considered as complete here?</SPAN>
    static void create() noexcept(noexcept(X()));
    X() noexcept(!noexcept(X::create()));
  };
</PRE>

<P><B>Proposed resolution (August, 2011):</B></P>

<OL><LI><P>Change 9.2 [class.mem] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

A class is considered a completely-defined object type (3.9 [basic.types]) (or complete type) at the closing <TT>}</TT> of the
<I>class-specifier</I>.  Within the class <I>member-specification</I>,
the class is regarded as complete within function bodies, default
arguments, <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>exception-specification</I>s,</SPAN> and
<I>brace-or-equal-initializers</I> for non-static data members
(including such things in nested classes).  Otherwise it is regarded
as incomplete within its own class <I>member-specification</I>.

</BLOCKQUOTE>

<LI><P>Change 15.4 [except.spec] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

...A type denoted in an <I>exception-specification</I> shall not
denote an incomplete type <SPAN style="font-weight:bold;background-color:#A0FFA0">other than a class currently being
defined</SPAN>.  A type denoted in an
<I>exception-specification</I> shall not denote a pointer or reference
to an incomplete type, other than <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>cv</I></SPAN>
<TT>void*</TT><SPAN style="text-decoration:line-through;background-color:#FFA0A0">, <TT>const void*</TT>, <TT>volatile void*</TT>, or
<TT>const volatile void*</TT></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">or a pointer or reference to
a class currently being defined</SPAN>.  A type <I>cv</I> <TT>T</TT>,
&#8220;array of <TT>T</TT>&#8221;, or &#8220;function returning
<TT>T</TT>&#8221; denoted in an <I>exception-specification</I> is
adjusted to type <TT>T</TT>, &#8220;pointer to <TT>T</TT>&#8221;, or
&#8220;pointer to function returning <TT>T</TT>&#8221;, respectively.

</BLOCKQUOTE>

</OL>

<P><B>Note:</B></P>

<P>This change was subsequently removed by the resolution of
<A HREF="
     cwg_defects.html#1330">issue 1330</A>.</P>

<BR><BR><HR><A NAME="1357"></A><H4>1357.
  
<I>brace-or-equal-initializer</I>s for function and typedef members
</H4><B>Section: </B>9.2&#160; [class.mem]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-16<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>The grammar allows a <I>brace-or-equal-initializer</I> for any
class member with a <I>member-declarator</I>, including typedef
members and member function declarations, and there is no semantic
restriction forbidding those forms, either.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>In 9.2 [class.mem], delete paragraph 4 and change paragraph
5 as follows:</P>

<BLOCKQUOTE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">A member can be initialized using a constructor; see 12.1 [class.ctor].  [<I>Note:</I> See Clause 12 [special] for a
description of constructors and other special member functions.
&#8212;<I>end note</I>]</SPAN></P>

<P>A <SPAN style="text-decoration:line-through;background-color:#FFA0A0">member can be initialized using a</SPAN>
<I>brace-or-equal-initializer</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">shall appear only in the
declaration of a data member</SPAN>.  (For static data members, see
9.4.2 [class.static.data]; for non-static data members, see
12.6.2 [class.base.init]).</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1306"></A><H4>1306.
  
Modifying an object within a <TT>const</TT> member function
</H4><B>Section: </B>9.3.2&#160; [class.this]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>James Kanze
 &#160;&#160;&#160;

 <B>Date: </B>2011-04-26<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>

<P>According to 9.3.2 [class.this] paragraph 2,</P>

<BLOCKQUOTE>

In a <TT>const</TT> member function, the object for which the function
is called is accessed through a <TT>const</TT> access path; therefore,
a <TT>const</TT> member function shall not modify the object and its
non-static data members.

</BLOCKQUOTE>

<P>This is clearly overstating the case: <TT>mutable</TT> members can
be modified, a <TT>const_cast</TT> can be used, and class member
access expressions not involving <TT>this</TT> can also allow the
object to be modified.  The effect of the cv-qualification of a member
function on the type of <TT>*this</TT> is clear from the preceding
paragraph; this statement appears both unnecessary and incorrect.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Merge 9.3.2 [class.this] paragraphs 1 and 2 and change
the text as follows:</P>

<BLOCKQUOTE>

In the body of a non-static (9.3 [class.mfct]) member
function, the keyword <TT>this</TT> is a prvalue expression whose
value is the address of the object for which the function is called.
The type of <TT>this</TT> in a member function of a class <TT>X</TT>
is <TT>X*</TT>.  If the member function is declared <TT>const</TT>,
the type of <TT>this</TT> is <TT>const X*</TT>, if the member function
is declared <TT>volatile</TT>, the type of <TT>this</TT> is
<TT>volatile X*</TT>, and if the member function is declared <TT>const
volatile</TT>, the type of <TT>this</TT> is <TT>const volatile
X*</TT>. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">In</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> thus in</SPAN> a
<TT>const</TT> member function, the object for which the function is
called is accessed through a <TT>const</TT> access path<SPAN style="text-decoration:line-through;background-color:#FFA0A0">; therefore, a
<TT>const</TT> member function shall not modify the object and its
non-static data members</SPAN>. <SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end note</I>]</SPAN>
[<I>Example:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1375"></A><H4>1375.
  
Reference to anonymous union?
</H4><B>Section: </B>9.5&#160; [class.union]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-16<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>

<P>According to 9.5 [class.union] paragraph 7,</P>

<BLOCKQUOTE>

A union for which objects or pointers are declared is not an
anonymous union.

</BLOCKQUOTE>

<P>This should also apply to references, which are now possible
because <TT>decltype</TT> allows writing an initializer for an
unnamed union:</P>

<PRE>
    char buf[100];
    union {
      int i;
    } &amp;r = (decltype(r)) buf;
</PRE>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 9.5 [class.union] paragraph 7:</P>

<BLOCKQUOTE>

<P>A union for which objects<SPAN style="font-weight:bold;background-color:#A0FFA0">,</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN> pointers<SPAN style="font-weight:bold;background-color:#A0FFA0">,
or references</SPAN> are declared is not an anonymous
union. [<I>Example:</I></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  void f() {</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  </SPAN>  union { int aa; char* p; } obj, *ptr = &amp;obj;
<SPAN style="font-weight:bold;background-color:#A0FFA0">  </SPAN>  aa = 1;      //<SPAN style="font-family:Times;font-style:italic"> error</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  </SPAN>  ptr-&gt;aa = 1; //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  }</SPAN>
</PRE>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="675"></A><H4>675.
  
Signedness of bit-field with typedef or template parameter type
</H4><B>Section: </B>9.6&#160; [class.bit]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Corden
 &#160;&#160;&#160;

 <B>Date: </B>11 February, 2008<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>Is the signedness of <TT>x</TT> in the following example
implementation-defined?</P>

<PRE>
    template &lt;typename T&gt; struct A {
        T x : 7;
    };

    template struct A&lt;long&gt;;
</PRE>

<P>A similar example could be created with a typedef.</P>

<P><U>Lawrence Crowl</U>: According to 9.6 [class.bit]
paragraph 3,</P>

<BLOCKQUOTE>

It is implementation-defined whether a plain (neither explicitly
signed nor unsigned) <TT>char</TT>, <TT>short</TT>, <TT>int</TT>
or <TT>long</TT> bit-field is signed or unsigned.

</BLOCKQUOTE>

<P>This clause is conspicuously silent on typedefs and template
parameters.</P>

<P><U>Clark Nelson</U>: At least in C, the intention is that the
presence or absence of this redundant keyword is supposed to be
remembered through typedef declarations. I don't remember discussing
it in C++, but I would certainly hope that we don't want to do
something different. And presumably, we would want template type
parameters to work the same way.</P>

<P>So going back to the original example, in an instantiation of
<TT>A&lt;long&gt;</TT>, the signedness of the bit-field is
implementation-defined, but in an instantiation of <TT>A&lt;signed
long&gt;</TT>, the bit-field is definitely signed.</P>

<P><U>Peter Dimov</U>: How can this work?
Aren't <TT>A&lt;long&gt;</TT> and <TT>A&lt;signed long&gt;</TT> the
same type?</P>

(See also <A HREF="
     cwg_defects.html#739">issue 739</A>.)

<P><B>Proposed resolution (February, 2012):</B></P>

This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#739">issue 739</A>.

<BR><BR><HR><A NAME="739"></A><H4>739.
  
Signedness of plain bit-fields
</H4><B>Section: </B>9.6&#160; [class.bit]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>3 November, 2008<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>

<P>9.6 [class.bit] paragraph 3 says,</P>

<BLOCKQUOTE>

It is implementation-defined whether a plain (neither explicitly
signed nor unsigned) <TT>char</TT>, <TT>short</TT>, <TT>int</TT> or
<TT>long</TT> bit-field is signed or unsigned.

</BLOCKQUOTE>

<P>The implications of this permission for an implementation that
chooses to treat plain bit-fields as unsigned are not clear.  Does
this mean that the type of such a bit-field is adjusted to the
unsigned variant or simply that sign-extension is not performed when
the value is fetched?  C99 is explicit in specifying the former (6.7.2
paragraph 5: &#8220;for bit-fields, it is implementation-defined
whether the specifier <TT>int</TT> designates the same type as
<TT>signed int</TT> or the same type as <TT>unsigned
int</TT>&#8221;), while C90 takes the latter approach (6.5.2.1:
&#8220;Whether the high-order bit position of a (possibly qualified)
'plain' int bit-field is treated as a sign bit is
implementation-defined&#8221;).</P>

(See also <A HREF="
     cwg_defects.html#675">issue 675</A> and
<A HREF="
     cwg_defects.html#741">issue 741</A>.)

<P><B>Additional note, May, 2009:</B></P>

<P>As an example of the implications of this question, consider the
following declaration:</P>

<PRE>
    struct S {
      int i: 2;
      signed int si: 2;
      unsigned int ui: 2;
    } s;
</PRE>

<P>Is it implementation-defined which expression,
<TT>cond?s.i:s.si</TT> or <TT>cond?s.i:s.ui</TT>, is an lvalue (the
lvalueness of the result depends on the second and third operands
having the same type, per 5.16 [expr.cond] paragraph 4)?</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 9.6 [class.bit] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<P>A bit-field shall not be a static member.  A bit-field shall have
integral or enumeration type (3.9.1 [basic.fundamental]). <SPAN style="text-decoration:line-through;background-color:#FFA0A0">It is
implementation-defined whether a plain (neither explicitly signed nor
unsigned) <TT>char</TT>, <TT>short</TT>, <TT>int</TT>, <TT>long</TT>,
or <TT>long long</TT> bit-field is signed or unsigned.</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">For a bit-field with a non-dependent type (14.6.2.1 [temp.dep.type])
that is specified to be plain (neither explicitly signed nor unsigned)
<TT>short</TT>, <TT>int</TT>, <TT>long</TT>, or <TT>long long</TT> or a
<I>typename-name</I> that is so defined (possibly through multiple
levels of <TT>typedef</TT>s), it is implementation-defined whether the
type of the bit-field is the corresponding signed or unsigned
type. [<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  struct B {
    long x : 3;
    typedef signed int si;
    si y : 1;
    typedef int i;
    i z : 1;
  };

  template&lt;class T&gt;
  struct A {
    T x : 7;
  };</SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">It is implementation-defined whether <TT>B::x</TT> has type
<TT>signed long</TT> or <TT>unsigned long</TT>.  <TT>B::y</TT> has
type <TT>signed int</TT>.  It is implementation-defined whether
<TT>B::z</TT> has type <TT>signed int</TT> or <TT>unsigned int</TT>.
<TT>A&lt;int&gt;::x</TT> and <TT>A&lt;signed int&gt;::x</TT> designate
the same entity of type <TT>signed int</TT>.  <TT>A&lt;unsigned
int&gt;::x</TT> has type <TT>unsigned int</TT>. &#8212;<I>end
example</I>]</SPAN></P>

<P>A <TT>bool</TT> value...</P>

</BLOCKQUOTE>

<P>This resolution also resolves <A HREF="
     cwg_defects.html#675">issue 675</A>.</P>

<P><B>Note, January, 2012:</B></P>

<P>Additional questions have been raised about the proposed resolution,
so the status was returned to "review" to allow further discussion.

</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<OL><LI><P>Change 9.6 [class.bit] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

A bit-field shall not be a static member.  A bit-field shall have
integral or enumeration type (3.9.1 [basic.fundamental]).  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">It is
implementation-defined whether a plain (neither explicitly signed nor
unsigned) <TT>char</TT>, <TT>short</TT>, <TT>int</TT>, <TT>long</TT>,
or <TT>long long</TT> bit-field is signed or unsigned.</SPAN>  A
<TT>bool</TT> value can successfully be stored...

</BLOCKQUOTE>

<LI><P>Add the following as a new section in C.1.8 [diff.class]:</P></LI>

<BLOCKQUOTE>

<P><B>9.6 [class.bit]</B></P>

<P><B>Change:</B> Bit-fields of type plain <TT>int</TT> are signed.</P>

<P><B>Rationale:</B> Leaving the choice of signedness to implementations
could lead to inconsistent definitions of template specializations.  For
consistency, the implementation freedom was eliminated for non-dependent
types, too.</P>

<P><B>Effect on original feature:</B> The choice is implementation-defined
in C, but not so in C++.</P>

<P><B>Difficulty of converting:</B> Syntactic transformation.</P>

<P><B>How widely used:</B> Seldom.</P>

</BLOCKQUOTE>

</OL>

<P>This resolution also resolves <A HREF="
     cwg_defects.html#675">issue 675</A>.</P>

<BR><BR><HR><A NAME="1250"></A><H4>1250.
  
Cv-qualification of incomplete virtual function return types
</H4><B>Section: </B>10.3&#160; [class.virtual]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Jonathan Wakely
 &#160;&#160;&#160;

 <B>Date: </B>2011-03-03<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>

<P>According to 10.3 [class.virtual] paragraph 8,</P>

<BLOCKQUOTE>

If the return type of <TT>D::f</TT> differs from the return type of
<TT>B::f</TT>, the class type in the return type of <TT>D::f</TT>
shall be complete at the point of declaration of <TT>D::f</TT> or
shall be the class type <TT>D</TT>.

</BLOCKQUOTE>

<P>This provision was intended to deal with covariant return
types but inadvertently affects types that vary only in
cv-qualification:</P>

<PRE>
    struct A;
    struct B {
        virtual const A* f();
    };
    struct D : B {
        A* f();    // ill-formed
    };
</PRE>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 10.3 [class.virtual] paragraph 8 as follows:</P>

<BLOCKQUOTE>

If the <SPAN style="font-weight:bold;background-color:#A0FFA0">class type in the covariant</SPAN> return type of
<TT>D::f</TT> differs from <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the return type</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">that</SPAN>
of <TT>B::f</TT>, the class type in the return type of <TT>D::f</TT>
shall be complete at the point of declaration of <TT>D::f</TT> or
shall be the class type <TT>D</TT>. When the overriding function...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="462"></A><H4>462.
  
Lifetime of temporaries bound to comma expressions
</H4><B>Section: </B>12.2&#160; [class.temporary]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>April 2004<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>

<P>Split off from <A HREF="
     cwg_defects.html#86">issue 86</A>.</P>

<P>Should binding a reference to the result of a "," operation
whose second operand is a temporary extend the lifetime of the
temporary?</P>
<PRE>
  const SFileName &amp;C = ( f(), SFileName("abc") );
</PRE>

<P><B>Notes from the March 2004 meeting:</B></P>

<P>We think the temporary should be extended.</P>

<P><B>Proposed resolution (October, 2004):</B></P>

<P>Change 12.2 [class.temporary] paragraph 2 as
indicated:</P>

<BLOCKQUOTE>

... In all these cases, the temporaries created during the
evaluation of the expression initializing the reference, except
the temporary <SPAN style="font-weight:bold;background-color:#A0FFA0">that is the overall result of the expression
[<I>Footnote:</I> For example, if the expression is a comma
expression (5.18 [expr.comma]) and the value of its
second operand is a temporary, the reference is bound to that
temporary.] and</SPAN> to which the reference is bound, are destroyed at
the end of the full-expression in which they are created and in
the reverse order of the completion of their construction...

</BLOCKQUOTE>

<P><I>[Note: this wording partially resolves <A HREF="
     cwg_defects.html#86">issue 86</A>.  See also <A HREF="
     cwg_defects.html#446">issue 446</A>.]</I></P>

<P><B>Notes from the April, 2005 meeting:</B></P>

<P>The CWG suggested a different approach from the 10/2004 resolution,
leaving 12.2 [class.temporary] unchanged and adding normative
wording to 5.18 [expr.comma] specifying that, if the result
of the second operand is a temporary, that temporary is the result of
the comma expression as well.</P>

<P><B>Proposed Resolution (November, 2006):</B></P>

<P>Add the indicated wording to 5.18 [expr.comma] paragraph 1:</P>

<BLOCKQUOTE>

... The type and value of the result are the type and value of the
right operand; the result is of the same value category as its right
operand, and is a bit-field if its right operand is a glvalue and a
bit-field.  <SPAN style="font-weight:bold;background-color:#A0FFA0">If the value of the right operand is a temporary
(12.2 [class.temporary]), the result is that temporary.</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1336"></A><H4>1336.
  
Definition of &#8220;converting constructor&#8221;
</H4><B>Section: </B>12.3.1&#160; [class.conv.ctor]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Niels Dekker
 &#160;&#160;&#160;

 <B>Date: </B>2011-07-03<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>Although the normative wording of 12.3.1 [class.conv.ctor]
paragraph 1 defining a converting constructor says</P>

<BLOCKQUOTE>

A constructor declared without the <I>function-specifier</I>
<TT>explicit</TT> specifies a conversion from the types of its
parameters to the type of its class.

</BLOCKQUOTE>

<P>implying that a constructor with multiple parameters can be a
converting constructor, it would be helpful if the example contained
such a constructor.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<OL><LI><P>Change the example in 12.3.1 [class.conv.ctor] paragraph 1
as follows:</P></LI>

<PRE>
  struct X {
      X(int);
      X(const char*, int =0);
<SPAN style="font-weight:bold;background-color:#A0FFA0">      X(int, int);</SPAN>
  };

  void f(X arg) {
    X a = 1;          // a = X(1)
    X b = "Jessie";   // b = X("Jessie",0)
    a = 2;            // a = X(2)
    f(3);             // f(X(3))
<SPAN style="font-weight:bold;background-color:#A0FFA0">    f({1, 2});        // f(X(1,2))</SPAN>
  }
</PRE>

<LI><P>Change the example in 12.3.1 [class.conv.ctor] paragraph 2
as follows:</P></LI>

<PRE>
  struct Z {
    explicit Z();
    explicit Z(int);
<SPAN style="font-weight:bold;background-color:#A0FFA0">    explicit Z(int, int);</SPAN>
  };

  Z a;                       //<SPAN style="font-family:Times;font-style:italic"> OK: default-initialization performed</SPAN>
  Z a1 = 1;                  //<SPAN style="font-family:Times;font-style:italic"> error: no implicit conversion</SPAN>
  Z a3 = Z(1);               //<SPAN style="font-family:Times;font-style:italic"> OK: direct initialization syntax used</SPAN>
  Z a2(1);                   //<SPAN style="font-family:Times;font-style:italic"> OK: direct initialization syntax used</SPAN>
  Z* p = new Z(1);           //<SPAN style="font-family:Times;font-style:italic"> OK: direct initialization syntax used</SPAN>
  Z a4 = (Z)1;               //<SPAN style="font-family:Times;font-style:italic"> OK: explicit cast used</SPAN>
  Z a5 = static_cast&lt;Z&gt;(1);  //<SPAN style="font-family:Times;font-style:italic"> OK: explicit cast used</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  Z a6 = { 3, 4 };           //<SPAN style="font-family:Times;font-style:italic"> error: no implicit conversion</SPAN></SPAN>
</PRE>

</OL>

<BR><BR><HR><A NAME="1345"></A><H4>1345.
  
Initialization of anonymous union class members
</H4><B>Section: </B>12.6.2&#160; [class.base.init]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Sean Hunt
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-16<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>12.6.2 [class.base.init] paragraph 8 appears to indicate that
a class member that is an anonymous union is to be default initilized.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change the indicated bullet of 12.6.2 [class.base.init] paragraph 8
as follows:</P>

<UL><LI>otherwise, if the entity is <SPAN style="font-weight:bold;background-color:#A0FFA0">an anonymous union or</SPAN> a
variant member (9.5 [class.union]), no initialization is
performed;</LI></UL>

<BR><BR><HR><A NAME="535"></A><H4>535.
  
Copy construction without a copy constructor
</H4><B>Section: </B>12.8&#160; [class.copy]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>7 October 2005<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>

<P>Footnote 112 (12.8 [class.copy] paragraph 2) says,</P>

<BLOCKQUOTE>

Because a template constructor is never a copy constructor, the
presence of such a template does not suppress the implicit declaration
of a copy constructor. Template constructors participate in overload
resolution with other constructors, including copy constructors, and a
template constructor may be used to copy an object if it provides a
better match than other constructors.

</BLOCKQUOTE>

<P>However, many of the stipulations about copy construction are
phrased to refer only to &#8220;copy constructors.&#8221;  For
example, 12.8 [class.copy] paragraph 14 says,</P>

<BLOCKQUOTE>

A program is ill-formed if the copy constructor...
for an object is implicitly used and the special member
function is not accessible (clause 11 [class.access]).

</BLOCKQUOTE>

<P>Does that mean that using an inaccessible template constructor
to copy an object is permissible, because it is not a &#8220;copy
constructor?&#8221;  Obviously not, but each use of the term
&#8220;copy constructor&#8221; in the Standard should be examined
to determine if it applies strictly to copy constructors or to
any constructor used for copying.  (A similar issue applies to
&#8220;copy assignment operators,&#8221; which have the same
relationship to assignment operator function templates.)</P>

<P><B>Proposed Resolution (August, 2011):</B></P>

<OL><LI><P>Change 3.2 [basic.def.odr] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

...[<I>Note:</I> This covers calls to named functions (5.2.2 [expr.call]), operator overloading (Clause 13 [over]),
user-defined conversions (12.3.2 [class.conv.fct]), allocation
function for placement new (5.3.4 [expr.new]), as well as
non-default initialization (8.5 [dcl.init]).  A <SPAN style="text-decoration:line-through;background-color:#FFA0A0">copy
constructor or move</SPAN> constructor <SPAN style="font-weight:bold;background-color:#A0FFA0">selected to copy or move an
object of class type</SPAN> is odr-used even if the call is actually
elided by the implementation <SPAN style="font-weight:bold;background-color:#A0FFA0">(12.8 [class.copy])</SPAN>. &#8212;<I>end note</I>] ...  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">A
copy-assignment function for a class</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">An assignment operator
function in a class</SPAN> is odr-used by an implicitly-defined
copy-assignment <SPAN style="font-weight:bold;background-color:#A0FFA0">or move-assignment</SPAN> function for another
class as specified in 12.8 [class.copy]. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">A move-assignment
function for a class is odr-used by an implicitly-defined
move-assignment function for another class as specified in
12.8 [class.copy].</SPAN> A default constructor...

</BLOCKQUOTE>

<LI><P>Delete 12.1 [class.ctor] paragraph 9:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">A copy constructor (12.8 [class.copy]) is used to copy
objects of class type.  A move constructor (12.8 [class.copy])
is used to move the contents of objects of class type.</SPAN></P>

</BLOCKQUOTE>

<LI><P>Change 12.2 [class.temporary] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...[<I>Note:</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">even if there is no call to the destructor or
copy/move constructor, all the semantic restrictions, such as
accessibility (Clause 11 [class.access]) and whether the
function is deleted (8.4.3 [dcl.fct.def.delete]), shall be
satisfied.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">this includes accessibility (11 [class.access]) and whether it is deleted, for the constructor selected
and for the destructor.</SPAN> However, in the special case of a
function call...

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraph 13 as follows:</P></LI>

<BLOCKQUOTE>

A copy/move constructor that is defaulted and not defined as deleted
is implicitly defined if it is odr-used (3.2 [basic.def.odr])
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">to initialize an object of its class type from a copy of an
object of its class type or of a class type derived from its class
type [<I>Footnote:</I> See 8.5 [dcl.init] for more details
on direct and copy initialization. &#8212;<I>end footnote</I>]</SPAN>
or when it is explicitly defaulted...

</BLOCKQUOTE>

<P><LI>Change 12.8 [class.copy] paragraph 31 as follows:</LI></P>

<BLOCKQUOTE>

When certain criteria are met, an implementation is allowed to omit
the copy/move construction of a class object, even if the
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">copy/move</SPAN> constructor <SPAN style="font-weight:bold;background-color:#A0FFA0">selected for the copy/move
operation</SPAN> and/or <SPAN style="font-weight:bold;background-color:#A0FFA0">the</SPAN> destructor for the object have
side effects...

</BLOCKQUOTE>

<LI><P>Change 13.3.3.1.2 [over.ics.user] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

A conversion of an expression of class type to the same class type is
given Exact Match rank, and a conversion of an expression of class
type to a base class of that type is given Conversion rank, in spite
of the fact that a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">copy/move</SPAN> constructor (i.e., a
user-defined conversion function) is called for those cases.

</BLOCKQUOTE>

<LI><P>Change 15.1 [except.throw] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

A <I>throw-expression</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">copy-</SPAN>initializes
<SPAN style="font-weight:bold;background-color:#A0FFA0">(8.5 [dcl.init])</SPAN> a temporary object, called the
<I>exception object</I>...

</BLOCKQUOTE>

<LI><P>Change 15.1 [except.throw] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

When the thrown object is a class object, the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">copy/move</SPAN>
constructor <SPAN style="font-weight:bold;background-color:#A0FFA0">selected for the copy-initialization</SPAN> and the
destructor shall be accessible, even if the copy/move operation is
elided (12.8 [class.copy]).

</BLOCKQUOTE>

</OL>

<P><I>[Drafting note: 5.17 [expr.ass] paragraph 4,
9 [class] paragraph 4, 9.5 [class.union] paragraph
1, 12.2 [class.temporary] paragraph 2, 12.8 [class.copy]
paragraphs 1-2, and 15.4 [except.spec] paragraph 14 do not
require any changes.]</I></P>

<BR><BR><HR><A NAME="1350"></A><H4>1350.
  
Incorrect exception specification for inherited constructors
</H4><B>Section: </B>12.9&#160; [class.inhctor]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-16<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>According to 12.9 [class.inhctor] paragraph 3, the exception
specification for an inheriting constructor has the same exception
specification as the inherited constructor.  This ignores the
exception specifications of default constructors for base classes
and nonstatic data members and of functions called in
<I>brace-or-equals-initializer</I>s of nonstatic data members.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<OL><LI><P>Delete the indicated bullet of 12.9 [class.inhctor]
paragraph 2:</P></LI>

<UL><LI><SPAN style="text-decoration:line-through;background-color:#FFA0A0">the <I>exception-specification</I> (15.4 [except.spec]),</SPAN></LI></UL>

<LI><P>Change 12.9 [class.inhctor] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

...[<I>Note:</I> Default arguments are not inherited. <SPAN style="font-weight:bold;background-color:#A0FFA0">An
<I>exception-specification</I> is implied as specified in 15.4 [except.spec].</SPAN> &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Change 15.4 [except.spec] paragraph 14 as follows:</P></LI>

<BLOCKQUOTE>

An <SPAN style="font-weight:bold;background-color:#A0FFA0">inheriting constructor (12.9 [class.inhctor]) and
an</SPAN> implicitly declared special member function (Clause
12 [special]) shall have an <I>exception-specification</I>.
If <TT>f</TT> is <SPAN style="font-weight:bold;background-color:#A0FFA0">an inheriting constructor or</SPAN> an implicitly
declared default constructor, copy constructor, move constructor,
destructor, copy assignment operator, or move assignment operator, its
implicit <I>exception-specification</I> specifies the <I>type-id</I>
<TT>T</TT> if and only if <TT>T</TT> is allowed by the
<I>exception-specification</I> of a function directly invoked by
<TT>f</TT>'s implicit definition; <TT>f</TT> shall allow all
exceptions if any function it directly invokes allows all exceptions,
and <TT>f</TT> shall allow no exceptions if every function it directly
invokes allows no exceptions. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> an instantiation of
an inheriting constructor template has an implied
<I>exception-specification</I> as if it were a non-template inheriting
constructor. &#8212;<I>end note</I>]</SPAN> [<I>Example:</I>...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1385"></A><H4>1385.
  
Syntactic forms of conversion functions for surrogate call functions
</H4><B>Section: </B>13.3.1.2&#160; [over.match.oper]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-31<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>In 13.3.1.1.2 [over.call.object] paragraph 2, the non-explicit
conversion functions considered for producing surrogate call functions
are those of the form</P>

<UL><TT>operator</TT> <I>conversion-type-id</I> <TT>()</TT> <I>attribute-specifier-seq<SUB>opt</SUB> cv-qualifier</I> <TT>;</TT></UL>

<P>This (presumably inadvertently) excludes conversion functions
with a <I>ref-qualifier</I> and/or an <I>exception-specification</I>.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 13.3.1.1.2 [over.call.object] paragraph 2 as follows:</P>

<BLOCKQUOTE>

<P>In addition, for each non-explicit conversion function declared in
<TT>T</TT> of the form</P>

<UL><TT>operator</TT> <I>conversion-type-id</I> <TT>()</TT> <I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">attribute-specifier-seq<SUB>opt</SUB></SPAN> cv-qualifier</I>
<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><I>ref-qualifier<SUB>opt</SUB> exception-specification<SUB>opt</SUB> attribute-specifier-seq<SUB>opt</SUB></I></SPAN> <TT>;</TT></UL>

</UL>

<P>where <I>cv-qualifier</I> is the same...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1392"></A><H4>1392.
  
Explicit conversion functions for references and non-references
</H4><B>Section: </B>13.3.1.6&#160; [over.match.ref]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2011-09-08<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>In 13.3.1.5 [over.match.conv], dealing with non-reference
initialization, direct initialization considers as candidate functions
only those that</P>

<BLOCKQUOTE>

yield type <TT>T</TT> or a type that can be converted to type
<TT>T</TT> with a qualification conversion

</BLOCKQUOTE>

<P>By contrast, 13.3.1.6 [over.match.ref], dealing with reference
binding, requires only that the type returned be reference-compatible
with the target, permitting both qualification conversions and
derived-to-base conversions.  This discrepancy is presumably
unintentional.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 13.3.1.6 [over.match.ref] paragraph 1 as follows:</P>

<BLOCKUOTE>

<P>...the candidate functions are selected as follows:</P>

<UL><LI><P>The conversion functions of <TT>S</TT> and its base classes
are considered<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, except that for copy-initialization, only the
non-explicit conversion functions are considered</SPAN>. Those
<SPAN style="font-weight:bold;background-color:#A0FFA0">non-explicit conversion functions</SPAN> that are not hidden
within <TT>S</TT> and yield type &#8220;lvalue reference to
<I>cv2</I> <TT>T2</TT>&#8221; (when 8.5.3 [dcl.init.ref]
requires an lvalue result) or &#8220;<I>cv2</I> <TT>T2</TT>&#8221; or
&#8220;rvalue reference to <I>cv2</I> <TT>T2</TT>&#8221; (when
8.5.3 [dcl.init.ref] requires an rvalue result), where
&#8220;<I>cv1</I> <TT>T</TT>&#8221; is reference-compatible
(8.5.3 [dcl.init.ref]) with &#8220;<I>cv2</I>
<TT>T2</TT>&#8221;, are candidate functions. <SPAN style="font-weight:bold;background-color:#A0FFA0">For
direct-initialization, those explicit conversion functions that are not
hidden within <TT>S</TT> and yield type &#8220;lvalue reference to
<I>cv2</I> <TT>T2</TT>,&#8221; or &#8220;<I>cv2</I> <TT>T2</TT> or
&#8220;rvalue reference to <I>cv2</I> <TT>T2</TT>,&#8221;
respectively, where <TT>T2</TT> is the same type as <TT>T</TT> or can
be converted to type <TT>T</TT> with a qualification conversion
(4.4 [conv.qual]), are also candidate
functions.</SPAN></P></LI>

</UL>

</BLOCKUOTE>

<BR><BR><HR><A NAME="1409"></A><H4>1409.
  
What is the second standard conversion sequence of a list-initialization sequence?
</H4><B>Section: </B>13.3.3.1.5&#160; [over.ics.list]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Sebastian Redl
 &#160;&#160;&#160;

 <B>Date: </B>2011-10-24<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>Both paragraphs 3 and 4 (for non-aggregate and aggregate
types, respectively) of 13.3.3.1.5 [over.ics.list] say that
the implicit conversion sequence is a user-defined conversion
sequence, but neither specifies that the second standard
conversion sequence is the identity conversion, as is presumably
intended.  This makes ranking by 13.3.3.2 [over.ics.rank]
paragraph 3 bullet 2 unncessarily unclear.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 13.3.3.1.5 [over.ics.list] paragraphs 3-4 as follows:</P>

<BLOCKQUOTE>

<P>Otherwise, if the parameter is a non-aggregate class <TT>X</TT> and
overload resolution per 13.3.1.7 [over.match.list] chooses a single
best constructor of <TT>X</TT> to perform the initialization of an
object of type <TT>X</TT> from the argument initializer list, the
implicit conversion sequence is a user-defined conversion sequence
<SPAN style="font-weight:bold;background-color:#A0FFA0">with the second standard conversion sequence an identity
conversion</SPAN>.  If multiple constructors are viable but none is
better than the others, the implicit conversion sequence is the
ambiguous conversion sequence...</P>

<P>Otherwise, if the parameter has an aggregate type which can be
initialized from the initializer list according to the rules for
aggregate initialization (8.5.1 [dcl.init.aggr]), the implicit
conversion sequence is a user-defined conversion sequence <SPAN style="font-weight:bold;background-color:#A0FFA0">with
the second standard conversion sequence an identity
conversion</SPAN>. [<I>Example:</I>...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1298"></A><H4>1298.
  
Incorrect example in overload resolution
</H4><B>Section: </B>13.3.3.2&#160; [over.ics.rank]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Nikolay Ivchenkov
 &#160;&#160;&#160;

 <B>Date: </B>2011-04-15<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>The following example appears in 13.3.3.2 [over.ics.rank]
paragraph 3:</P>

<PRE>
  template&lt;class T&gt; int f(T&amp;);
  template&lt;class T&gt; int f(T&amp;&amp;);
  void g();
  int i1 = f(g); //<SPAN style="font-family:Times;font-style:italic"> calls </SPAN>f(T&amp;)<SPAN style="font-family:Times;font-style:italic"></SPAN>
</PRE>

<P>This is not correct.  Because of the special deduction rule for
rvalue reference parameters in 14.8.2.1 [temp.deduct.call] paragraph
3 and the reference-collapsing rules of 8.3.2 [dcl.ref]
paragraph 6, the parameter type for both will be <TT>void(&amp;)()</TT>.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change the example in 13.3.3.2 [over.ics.rank] paragraph 3
bullet 1 sub-bullet 5 as follows:</P>

<PRE>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">  template&lt;class T&gt; int f(T&amp;);
  template&lt;class T&gt; int f(T&amp;&amp;);</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  int f(void(&amp;)());     //<SPAN style="font-family:Times;font-style:italic"> #1</SPAN>
  int f(void(&amp;&amp;)());    //<SPAN style="font-family:Times;font-style:italic"> #2</SPAN></SPAN>
  void g();
  int i1 = f(g);        //<SPAN style="font-family:Times;font-style:italic"> calls </SPAN><SPAN style="text-decoration:line-through;background-color:#FFA0A0">f(T&amp;)</SPAN><SPAN style="font-family:Times;font-style:italic"> <SPAN style="font-weight:bold;background-color:#A0FFA0">#1</SPAN></SPAN>
</PRE>

<BR><BR><HR><A NAME="1408"></A><H4>1408.
  
What is &#8220;the same aggregate initialization?&#8221;
</H4><B>Section: </B>13.3.3.2&#160; [over.ics.rank]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Sebastian Redl
 &#160;&#160;&#160;

 <B>Date: </B>2011-10-24<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>Bullet 2 of 13.3.3.2 [over.ics.rank] paragraph 3 reads,</P>

<UL><LI><P>User-defined conversion sequence <TT>U1</TT> is a
better conversion sequence than another user-defined conversion
sequence <TT>U2</TT> if they contain the same user-defined
conversion function or constructor or aggregate initialization
and the second standard conversion sequence of <TT>U1</TT> is
better than the second standard conversion sequence of
<TT>U2</TT>.</P></LI></UL>

<P>It is not clear what &#8220;the same aggregate initialization&#8221;
means &#8212; does this require that the same aggregate type is the
target type?</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 13.3.3.2 [over.ics.rank] paragraph 3 bullet 2 as
follows:</P>

<UL><LI><P>Standard conversion sequence <TT>S1</TT> is a better
conversion sequence...</P></LI>

<LI><P>User-defined conversion sequence <TT>U1</TT> is a better
conversion sequence than another user-defined conversion sequence
<TT>U2</TT> if they contain the same user-defined conversion function
or constructor or <SPAN style="font-weight:bold;background-color:#A0FFA0">they initialize the same class in an</SPAN>
aggregate initialization and <SPAN style="font-weight:bold;background-color:#A0FFA0">in either case</SPAN> the second
standard conversion sequence of <TT>U1</TT> is better than the second
standard conversion sequence of
<TT>U2</TT>. [<I>Example:</I>...</P></LI>

</UL>

<BR><BR><HR><A NAME="1410"></A><H4>1410.
  
Reference overload tiebreakers should apply to rvalue references
</H4><B>Section: </B>13.3.3.2&#160; [over.ics.rank]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Michael Wong
 &#160;&#160;&#160;

 <B>Date: </B>2011-10-26<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>

<P>In bullet 3 of paragraph 4 of 13.3.3.2 [over.ics.rank] are
two sub-bullets dealing with overload tiebreakers:</P>

<UL><LI><P>binding of an expression of type <TT>C</TT> to a
reference of type <TT>B&amp;</TT> is better than binding an
expression of type <TT>C</TT> to a reference of type
<TT>A&amp;</TT>,</P></LI>

<LI><P>...</P></LI>

<LI><P>binding of an expression of type <TT>B</TT> to a reference
of type <TT>A&amp;</TT> is better than binding an expression of
type <TT>C</TT> to a reference of type <TT>A&amp;</TT>,</P></LI>

</UL>

<P>Presumably both of these tiebreakers should apply to rvalue
references as well as lvalue references.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 13.3.3.2 [over.ics.rank] paragraph 4 bullet 3 as follows:</P>

<UL><LI><P>If class <TT>B</TT> is derived directly or indirectly from
class <TT>A</TT> and class <TT>C</TT> is derived directly or
indirectly from <TT>B</TT>,</P></LI>

<UL><LI><P>conversion of <TT>C*</TT> to <TT>B*</TT> is better...</P></LI>

<LI><P>binding of an expression of type <TT>C</TT> to a reference
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">of</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">to</SPAN> type <TT>B<SPAN style="text-decoration:line-through;background-color:#FFA0A0">&amp;</SPAN></TT> is better
than binding an expression of type C to a reference <SPAN style="text-decoration:line-through;background-color:#FFA0A0">of</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">to</SPAN> type <TT>A<SPAN style="text-decoration:line-through;background-color:#FFA0A0">&amp;</SPAN></TT>,</P></LI>

<LI><P>...</P></LI>

<LI><P>binding of an expression of type <TT>B</TT> to a reference
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">of</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">to</SPAN> type <TT>A<SPAN style="text-decoration:line-through;background-color:#FFA0A0">&amp;</SPAN></TT> is better
than binding an expression of type <TT>C</TT> to a reference
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">of</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">to</SPAN> type <TT>A<SPAN style="text-decoration:line-through;background-color:#FFA0A0">&amp;</SPAN></TT>,</P></LI>

<LI><P>...</P></LI>

</UL>

</UL>

<BR><BR><HR><A NAME="1275"></A><H4>1275.
  
Incorrect comment in example of template parameter pack restriction
</H4><B>Section: </B>14.1&#160; [temp.param]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Johannes Schaub
 &#160;&#160;&#160;

 <B>Date: </B>2011-03-25<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>The following example from 14.1 [temp.param] paragraph 11
is incorrect:</P>

<PRE>
  //<SPAN style="font-family:Times;font-style:italic"> </SPAN>U<SPAN style="font-family:Times;font-style:italic"> cannot be deduced or specified</SPAN>
  template&lt;class... T, class... U&gt; void f() { }
  template&lt;class... T, class U&gt; void g() { }
</PRE>

<P>In fact, <TT>U</TT> can be deduced to an empty sequence by
14.8.1 [temp.arg.explicit] paragraph 3:</P>

<BLOCKQUOTE>

A trailing template parameter pack (14.5.3 [temp.variadic]) not
otherwise deduced will be deduced to an empty sequence of template
arguments.

</BLOCKQUOTE>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 14.1 [temp.param] paragraph 11 as follows:</P>

<BLOCKQUOTE>

<P>...A template parameter pack of a function template shall not be
followed by another template parameter unless that template parameter
can be deduced <SPAN style="font-weight:bold;background-color:#A0FFA0">from the <I>parameter-type-list</I> of the
function template</SPAN> or has a default argument (14.8.2 [temp.deduct]).  [<I>Example:</I></P>

<PRE>
  template&lt;class T1 = int, class T2&gt; class B;   //<SPAN style="font-family:Times;font-style:italic"> error</SPAN>

  //<SPAN style="font-family:Times;font-style:italic"> </SPAN>U<SPAN style="font-family:Times;font-style:italic"> cannot be deduced <SPAN style="font-weight:bold;background-color:#A0FFA0">from the <I>parameter-type-list</I></SPAN> or specified</SPAN>
  template&lt;class... T, class... U&gt; void f() { } <SPAN style="font-weight:bold;background-color:#A0FFA0">//<SPAN style="font-family:Times;font-style:italic"> error</SPAN></SPAN>
  template&lt;class... T, class U&gt; void g() { }    <SPAN style="font-weight:bold;background-color:#A0FFA0">//<SPAN style="font-family:Times;font-style:italic"> error</SPAN></SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1398"></A><H4>1398.
  
Non-type template parameters of type <TT>std::nullptr_t</TT>
</H4><B>Section: </B>14.3.2&#160; [temp.arg.nontype]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2011-09-27<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>

<P>Although 14.1 [temp.param] paragraph 4 explicitly allows
non-type template parameters of type
<TT>std::nullptr_t</TT>, they cannot actually be used:
14.3.2 [temp.arg.nontype] paragraph 1 does not allow a
<I>template-argument</I> of type <TT>std::nullptr_t</TT>, and
paragraph 5 does not describe any conversions from other types to
<TT>std::nullptr_t</TT>.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Add the following new bullet in 14.3.2 [temp.arg.nontype]
paragraph 1:</P>

<UL><LI><P>...</P></LI>

<LI><P>a pointer to member expressed as described in 5.3.1 [expr.unary.op].</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">an address constant expression of type
<TT>std::nullptr_t</TT>.</SPAN></P></LI>

</UL>

<BR><BR><HR><A NAME="1321"></A><H4>1321.
  
Equivalency of dependent calls
</H4><B>Section: </B>14.5.6.1&#160; [temp.over.link]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2011-05-18<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>Consider the following example:</P>

<PRE>
  int g(int);

  template &lt;class T&gt; decltype(g(T())) f();

  int g();

  template &lt;class T&gt; decltype(g(T())) f() { return g(T()); }

  int i = f&lt;int&gt;();
</PRE>

<P>Do the two <TT>f</TT>s declare the same function template?  According
to 14.5.6.1 [temp.over.link] paragraph 5,</P>

<BLOCKQUOTE>

Two expressions involving template parameters are considered
<I>equivalent</I> if two function definitions containing the expressions
would satisfy the one definition rule (3.2 [basic.def.odr]),
except that the tokens used to name the template parameters may differ
as long as a token used to name a template parameter in one expression
is replaced by another token that names the same template parameter in
the other expression.

</BLOCKQUOTE>

<P>The relevant portion of 3.2 [basic.def.odr] paragraph 5 says,</P>

<BLOCKQUOTE>

in each definition of <TT>D</TT>, corresponding names, looked up
according to 3.4 [basic.lookup], shall refer to an entity
defined within the definition of <TT>D</TT>, or shall refer to the
same entity, after overload resolution (13.3 [over.match]) and
after matching of partial template specialization (14.8.3 [temp.over]), except that a name can refer to a const object with
internal or no linkage if the object has the same literal type in all
definitions of <TT>D</TT>, and the object is initialized with a
constant expression (5.19 [expr.const]), and the value (but
not the address) of the object is used, and the object has the same
value in all definitions of <TT>D</TT>

</BLOCKQUOTE>

<P>This could be read either way, since overload resolution isn't done
at this point.  Either we consider the result of the unqualified name
lookup and say that the expressions aren't equivalent or we need a
new rule for equivalence and merging of dependent calls.</P>

<P><B>Proposed resolution (December, 2011):</B></P>

<OL><LI><P>Change 14.5.6.1 [temp.over.link] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

<P>Two expressions involving template parameters are considered
<I>equivalent</I> if two function definitions containing the
expressions would satisfy the one definition rule (3.2 [basic.def.odr]), except that the tokens used to name the template
parameters may differ as long as a token used to name a template
parameter in one expression is replaced by another token that names
the same template parameter in the other expression. <SPAN style="font-weight:bold;background-color:#A0FFA0">For
determining whether two dependent names (14.6.2 [temp.dep])
are equivalent, only the name itself is considered, not the result of
name lookup in the context of the template. If multiple declarations
of the same function template differ in the result of this name
lookup, the result for the first declaration is used.</SPAN>
[<I>Example:</I></P>

<PRE>
  template &lt;int I, int J&gt; void f(A&lt;I+J&gt;); //<SPAN style="font-family:Times;font-style:italic"> #1</SPAN>
  template &lt;int K, int L&gt; void f(A&lt;K+L&gt;); //<SPAN style="font-family:Times;font-style:italic"> same as #1</SPAN>

<SPAN style="font-weight:bold;background-color:#A0FFA0">  template &lt;class T&gt; decltype(g(T())) h();
  int g(int);
  template &lt;class T&gt; decltype(g(T())) h() //<SPAN style="font-family:Times;font-style:italic"> redeclaration of </SPAN>h()<SPAN style="font-family:Times;font-style:italic"> uses the earlier lookup</SPAN>
    { return g(T()); }                    //<SPAN style="font-family:Times;font-style:italic"> ...although the lookup here does find </SPAN>g(int)
  int i = h&lt;int&gt;();                       //<SPAN style="font-family:Times;font-style:italic"> template argument substitution fails; </SPAN>g(int)
                                          //<SPAN style="font-family:Times;font-style:italic"> was not in scope at the first declaration of </SPAN>h()</SPAN>
</PRE>

<P>&#8212;<I>end example</I>] Two expressions...</P>

</BLOCKQUOTE>

<LI><P>Change 14.6.2 [temp.dep] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<P>...In an expression of the form:</P>

<UL><I>postfix-expression</I> <TT>(</TT> <I>expression-list<SUB>opt</SUB></I> <TT>)</TT></UL>

<P>where the <I>postfix-expression</I> is an
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>id-expression</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>unqualified-id</I></SPAN>, the
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>id-expression</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>unqualified-id</I></SPAN>
denotes a dependent name if</P>

<UL><LI><P>any of the expressions in the <I>expression-list</I> is a pack
expansion (14.5.3 [temp.variadic]),</P></LI>

<LI><P>any of the expressions in the <I>expression-list</I> is a
type-dependent expression (14.6.2.2 [temp.dep.expr]), or</P></LI>

<LI><P>if the <I>unqualified-id</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">of the
<I>id-expression</I></SPAN> is a
<I>template-id</I> in which any of the template arguments depends on a
template parameter.</P></LI>

</UL>

<P>if an operand...</P>

</BLOCKQUOTE>

<LI><P>Change 14.6.4.2 [temp.dep.candidate] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<P>For a function call <SPAN style="text-decoration:line-through;background-color:#FFA0A0">that depends on a template parameter</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">where the <I>postfix-expression</I> is a dependent name</SPAN>,
the candidate functions are found using the usual lookup rules
(3.4.1 [basic.lookup.unqual], 3.4.2 [basic.lookup.argdep]<SPAN style="text-decoration:line-through;background-color:#FFA0A0">,
3.4.3 [basic.lookup.qual]</SPAN>) except that:</P>

<UL><LI><P>For the part of the lookup using unqualified name lookup
(3.4.1 [basic.lookup.unqual]) <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or qualified name lookup (3.4.3 [basic.lookup.qual])</SPAN>, only function declarations from the template
definition context are found.</P></LI>

<LI><P>For the part of the lookup using associated namespaces
(3.4.2 [basic.lookup.argdep]), only function declarations found in
either the template definition context or the template instantiation
context are found.</P></LI>

</UL>

<P>If <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the function name is an <I>unqualified-id</I> and</SPAN> the
call would be ill-formed or would find a better match had the lookup
within the associated namespaces considered all the function
declarations with external linkage introduced in those namespaces in
all translation units, not just considering those declarations found
in the template definition and template instantiation contexts, then
the program has undefined behavior.</P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1406"></A><H4>1406.
  
<I>ref-qualifier</I>s and added parameters of non-static member function templates
</H4><B>Section: </B>14.5.6.2&#160; [temp.func.order]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2011-10-21<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>In describing the partial ordering of function templates,
14.5.6.2 [temp.func.order] paragraph 3 says,</P>

<BLOCKQUOTE>

If only one of the function templates is a non-static member,
that function template is considered to have a new first
parameter inserted in its function parameter list. The new
parameter is of type &#8220;reference to <I>cv</I>
<TT>A</TT>,&#8221; where <I>cv</I> are the cv-qualifiers of the function
template (if any) and <TT>A</TT> is the class of which the function
template is a member. [<I>Note:</I> This allows a non-static member to
be ordered with respect to a nonmember function and for the
results to be equivalent to the ordering of two equivalent
nonmembers. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<P>The Standard appears to be silent as to whether the
reference is an lvalue or rvalue reference; presumably that should
be determined by the <I>ref-qualifier</I> of the member function,
if any.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 14.5.6.2 [temp.func.order] paragraph 3 as follows:</P>

<BLOCKQUOTE>

To produce the transformed template, for each type, non-type, or
template template parameter (including template parameter packs
(14.5.3 [temp.variadic]) thereof) synthesize a unique type,
value, or class template respectively and substitute it for each
occurrence of that parameter in the function type of the template.  If
only one of the function templates is a non-static member <SPAN style="font-weight:bold;background-color:#A0FFA0">of some
class <TT>A</TT></SPAN>, that function template is considered to have a
new first parameter inserted in its function parameter
list. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Given <I>cv</I> as the cv-qualifiers of the
function template (if any), the</SPAN> new parameter is of type
&#8220;<SPAN style="font-weight:bold;background-color:#A0FFA0">rvalue</SPAN> reference to <I>cv</I>
<TT>A</TT><SPAN style="text-decoration:line-through;background-color:#FFA0A0">,</SPAN>&#8221; <SPAN style="font-weight:bold;background-color:#A0FFA0">if the optional
<I>ref-qualifier</I> of the function template is <TT>&amp;&amp;</TT>,
or of type &#8220;lvalue reference to <I>cv</I> <TT>A</TT>&#8221;
otherwise</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">where <I>cv</I> are the cv-qualifiers of the
function template (if any) and <TT>A</TT> is the class of which the
function template is a member</SPAN>. [<I>Note:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1296"></A><H4>1296.
  
Ill-formed template declarations (not just definitions)
</H4><B>Section: </B>14.6&#160; [temp.res]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Nikolay Ivchenkov
 &#160;&#160;&#160;

 <B>Date: </B>2011-04-14<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>According to 14.6 [temp.res] paragraph 8,</P>

<BLOCKQUOTE>

Knowing which names are type names allows the syntax of every template
definition to be checked.  No diagnostic shall be issued for a
template definition for which a valid specialization can be generated.
If no valid specialization can be generated for a template definition,
and that template is not instantiated, the template definition is
ill-formed, no diagnostic required.  If every valid specialization of
a variadic template requires an empty template parameter pack, the
template definition is ill-formed, no diagnostic required.  If a type
used in a non-dependent name...

</BLOCKQUOTE>

<P>It seems that these points could and should apply to template
declarations that are not definitions, as well.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 14.6 [temp.res] paragraph 8 as follows:</P>

<BLOCKQUOTE>

Knowing which names are type names allows the syntax of every template
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">definition</SPAN> to be checked.  No diagnostic shall be issued
for a template <SPAN style="text-decoration:line-through;background-color:#FFA0A0">definition</SPAN> for which a valid specialization
can be generated.  If no valid specialization can be generated for a
template <SPAN style="text-decoration:line-through;background-color:#FFA0A0">definition</SPAN>, and that template is not instantiated,
the template <SPAN style="text-decoration:line-through;background-color:#FFA0A0">definition</SPAN> is ill-formed, no diagnostic
required.  If every valid specialization of a variadic template
requires an empty template parameter pack, the template
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">definition</SPAN> is ill-formed, no diagnostic required.  If a
type used...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1227"></A><H4>1227.
  
Mixing immediate and non-immediate contexts in deduction failure
</H4><B>Section: </B>14.8.2&#160; [temp.deduct]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2010-11-27<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>Consider the following example:</P>

<PRE>
    template &lt;int&gt; struct X {
      typedef int type;
    };
    template &lt;class T&gt; struct Y { };
    template &lt;class T&gt; struct Z {
      static int const value = Y&lt;T&gt;::value;
    };

    template &lt;class T&gt; typename X&lt;Y&lt;T&gt;::value + Z&lt;T&gt;::value&gt;::type f(T);
    int f(...);

    int main() {
      sizeof f(0);
    }
</PRE>

<P>The problem here is that there is a combination of an invalid expression
in the immediate context (<TT>Y&lt;T&gt;::value</TT>) and in the
non-immediate context (within <TT>Z&lt;T&gt;</TT> when evaluating
<TT>Z&lt;T&gt;::value</TT>).  The Standard does not appear to state
clearly whether this program is well-formed (because the error in the
immediate context causes deduction failure) or ill-formed (because of
the error in the non-immediate context).</P>

<P><B>Notes from the March, 2011 meeting:</B></P>

<P>Some members expressed a desire to allow implementations latitude
in whether examples like this should be deduction failure or a
diagnosable error, just as the order of evaluation of arithmetic
operands is largely unconstrained. Others felt that specifying something
like a depth-first left-to-right traversal of the expression or
declaration would be better.  Another possibility suggested was to
enforce ordering only at comma operators.  No consensus was achieved.
</P>

<P>CWG agreed that the arguments should be processed in
left-to-right order.  Some popular existing code (e.g., Boost) depends
on this ordering.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 14.8.2 [temp.deduct] paragraph 7 as follows:</P>

<BLOCKQUOTE>

<P>The substitution occurs in all types and expressions that are used in
the function type and in template parameter declarations. The
expressions include not only constant expressions such as those that
appear in array bounds or as nontype template arguments but also
general expressions (i.e., non-constant expressions) inside
<TT>sizeof</TT>, <TT>decltype</TT>, and other contexts that allow
non-constant expressions. <SPAN style="font-weight:bold;background-color:#A0FFA0">The substitution proceeds in lexical
order and stops when a condition that causes deduction to fail is
encountered.</SPAN>  [<I>Note:</I> The equivalent substitution
in exception specifications is done only when the function is
instantiated, at which point a program is ill-formed if the
substitution results in an invalid type or expression.
&#8212;<I>end note</I>] <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  template &lt;class T&gt; struct A { using X = typename T::X; };
  template &lt;class T&gt; typename T::X f(typename A&lt;T&gt;::X);
  template &lt;class T&gt; void f(...) { }
  template &lt;class T&gt; auto g(typename A&lt;T&gt;::X) -&gt; typename T::X;
  template &lt;class T&gt; void g(...) { }

  void h() {
    f&lt;int&gt;(0); //<SPAN style="font-family:Times;font-style:italic"> OK, substituting return type causes deduction to fail</SPAN>
    g&lt;int&gt;(0); //<SPAN style="font-family:Times;font-style:italic"> error, substituting parameter type instantiates </SPAN>A&lt;int&gt;
  }
</SPAN></PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1262"></A><H4>1262.
  
Default template arguments and deduction failure
</H4><B>Section: </B>14.8.2&#160; [temp.deduct]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Nikolay Ivchenkov
 &#160;&#160;&#160;

 <B>Date: </B>2011-03-16<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 14.8.2 [temp.deduct] paragraph 5 as follows:</P>

<BLOCKQUOTE>

The resulting substituted and adjusted function type is used as the
type of the function template for template argument deduction.  If a
template argument has not been deduced<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, its default template
argument, if any, is used</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">and its corresponding template
parameter has a default argument, the template argument is determined
by substituting the template arguments determined for preceding
template parameters into the default argument. If the substitution
results in an invalid type, as described above, type deduction
fails</SPAN>. [<I>Example:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1388"></A><H4>1388.
  
Missing non-deduced context following a function parameter pack
</H4><B>Section: </B>14.8.2.1&#160; [temp.deduct.call]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>James Widman
 &#160;&#160;&#160;

 <B>Date: </B>2011-09-02<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>Presumably 14.8.2.5 [temp.deduct.type] paragraph 5 should include a
bullet for a function parameter or function parameter pack that follows a
function parameter pack.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 14.8.2.1 [temp.deduct.call] paragraph 1 as follows:</P>

<BLOCKQUOTE>

<P>...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">For a function parameter pack that does not occur at the end of
the <I>parameter-declaration-list</I>, the type of the parameter pack is a
non-deduced context.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">When a function parameter pack appears in a
non-deduced context (14.8.2.5 [temp.deduct.type]), the type of that
parameter pack is never deduced.</SPAN> [<I>Example:</I></P>

<PRE>
  template&lt;class ... Types&gt; void f(Types&amp; ...);
  template&lt;class T1, class ... Types&gt; void g(T1, Types ...);
<SPAN style="font-weight:bold;background-color:#A0FFA0">  template&lt;class T1, class ... Types&gt; void g1(Types ..., T1);</SPAN>

  void h(int x, float&amp; y) {
    const int z = x;
    f(x, y, z);                  //<SPAN style="font-family:Times;font-style:italic"> </SPAN>Types<SPAN style="font-family:Times;font-style:italic"> is deduced to </SPAN>int, float, const int
    g(x, y, z);                  //<SPAN style="font-family:Times;font-style:italic"> </SPAN>T1<SPAN style="font-family:Times;font-style:italic"> is deduced to </SPAN>int<SPAN style="font-family:Times;font-style:italic">; </SPAN>Types<SPAN style="font-family:Times;font-style:italic"> is deduced to </SPAN>float, int
<SPAN style="font-weight:bold;background-color:#A0FFA0">    g1(x, y, z);                 //<SPAN style="font-family:Times;font-style:italic"> error: </SPAN>Types<SPAN style="font-family:Times;font-style:italic"> is not deduced</SPAN>
    g1&lt;int, int, int&gt;(x, y, z);  //<SPAN style="font-family:Times;font-style:italic"> OK, no deduction occurs</SPAN></SPAN>
  }
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<P>This resolution also resolves <A HREF="
     cwg_defects.html#1399">issue 1399</A>.</P>

<BR><BR><HR><A NAME="1399"></A><H4>1399.
  
Deduction with multiple function parameter packs
</H4><B>Section: </B>14.8.2.1&#160; [temp.deduct.call]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2011-09-29<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>Consider:</P>

<PRE>
    template &lt;class... T&gt;
    void f(T..., int, T...) { }

    int main() {
       f(0);          // OK
       f&lt;int&gt;(0,0,0); // OK
       f(0,0,0);      // error
    }
</PRE>

<P>It seems clear that the third call is ill-formed because by
the time we get to the second function parameter pack we've
already assumed that <TT>T</TT> is empty, so deducing anything
for <TT>T</TT> would be nonsensical.  But I don't think this is
expressed anywhere in the standard.</P>

<P>One way to handle this would be to say that a template
parameter pack is not deducible if it is used in a function
parameter pack not at the end of the parameter list.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#1388">issue 1388</A>.</P>

<BR><BR><HR><A NAME="1372"></A><H4>1372.
  
Cross-references incorrect in conversion function template argument deduction
</H4><B>Section: </B>14.8.2.3&#160; [temp.deduct.conv]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Michael Wong
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-15<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>

<P>According to 14.8.2.3 [temp.deduct.conv] paragraph 1,</P>

<BLOCKQUOTE>

Template argument deduction is done by comparing the return type
of the conversion function template (call it <TT>P</TT>; see
8.5 [dcl.init], 13.3.1.5 [over.match.conv], and
13.3.1.6 [over.match.ref] for the determination of that type)
with the type that is required as the result of the conversion
(call it <TT>A</TT>) as described in 14.8.2.5 [temp.deduct.type].

</BLOCKQUOTE>

<P>It would seem that the cross-references should apply to the
determination of the type &#8220;required as the result of the
conversion&#8221; (i.e., <TT>A</TT>) instead of the return type
of the conversion function.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 14.8.2.3 [temp.deduct.conv] paragraph 1 as follows:</P>

<BLOCKQUOTE>

Template argument deduction is done by comparing the return type of
the conversion function template (call it <TT>P</TT><SPAN style="text-decoration:line-through;background-color:#FFA0A0">; see
8.5 [dcl.init], 13.3.1.5 [over.match.conv], and
13.3.1.6 [over.match.ref] for the determination of that
type</SPAN>) with the type that is required as the result of the
conversion (call it A<SPAN style="font-weight:bold;background-color:#A0FFA0">; see 8.5 [dcl.init], 13.3.1.5 [over.match.conv], and 13.3.1.6 [over.match.ref] for the
determination of that type</SPAN>) as described in 14.8.2.5 [temp.deduct.type].

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1387"></A><H4>1387.
  
Missing non-deduced context for <TT>decltype</TT>
</H4><B>Section: </B>14.8.2.5&#160; [temp.deduct.type]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>James Widman
 &#160;&#160;&#160;

 <B>Date: </B>2011-09-02<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>Presumably 14.8.2.5 [temp.deduct.type] paragraph 5 should include
a bullet for a <I>decltype-specifier</I> whose <I>expression</I>
references a template parameter.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 14.8.2.5 [temp.deduct.type] paragraph 5 as follows:</P>

<BLOCKQUOTE>

<P>The non-deduced contexts are:</P>

<UL><LI><P>The <I>nested-name-specifier</I> of a type that was
specified using a <I>qualified-id</I>.</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">The <I>expression</I> of a
<I>decltype-specifier</I>.</SPAN></P></LI>

<LI><P>A non-type template argument...</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1431"></A><H4>1431.
  
Exceptions from other than <I>throw-expression</I>s
</H4><B>Section: </B>15&#160; [except]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Nikolay Ivchenkov
 &#160;&#160;&#160;

 <B>Date: </B>2011-12-16<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>There are a number of places in the Standard that appear to
assume that exceptions are only thrown by <I>throw-expression</I>s.
Various other constructs, such as <TT>dynamic_cast</TT>s,
<TT>typeid</TT>, <I>new-expression</I>s, etc., can also throw
exceptions, so a more general term should be coined and applied
in place of <I>throw-expression</I> wherever necessary.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<OL><LI><P>Change 3.7.4.1 [basic.stc.dynamic.allocation] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

...Any other allocation function that fails to allocate storage shall
indicate failure only by throwing an exception <SPAN style="font-weight:bold;background-color:#A0FFA0">(15.1 [except.throw])</SPAN> of a type that would match a handler (15.3 [except.handle]) of type <TT>std::bad_alloc</TT> (18.6.2.1 [bad.alloc]).

</BLOCKQUOTE>

<LI><P>Change 3.7.4.1 [basic.stc.dynamic.allocation] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

...[<I>Note:</I> In particular, a global allocation function is not
called to allocate storage for objects with static storage duration
(3.7.1 [basic.stc.static]), for objects or references with thread
storage duration (3.7.2 [basic.stc.thread]), for objects of type
<TT>std::type_info</TT> (5.2.8 [expr.typeid]), or for <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the
copy of an object thrown by a throw expression</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an exception
object</SPAN> (15.1 [except.throw]). &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Change 5.2.7 [expr.dynamic.cast] paragraph 9 as follows:</P></LI>

<BLOCKQUOTE>

The value of a failed cast to pointer type is the null pointer value
of the required result type. A failed cast to reference type throws
<SPAN style="font-weight:bold;background-color:#A0FFA0">an exception (15.1 [except.throw]) of a type that would
match a handler (15.3 [except.handle]) of type</SPAN>
<TT>std::bad_cast</TT> (18.7.2 [bad.cast]).

</BLOCKQUOTE>

<LI><P>Change 5.2.8 [expr.typeid] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

...If the glvalue expression is obtained by applying the unary
<TT>*</TT> operator to a pointer<SUP>68</SUP> and the pointer is a
null pointer value (4.10 [conv.ptr]), the <TT>typeid</TT>
expression throws <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an exception (15.1 [except.throw]) of a type that would match a handler of type</SPAN>
<TT>std::bad_typeid</TT> exception (18.7.3 [bad.typeid]).

</BLOCKQUOTE>

<LI><P>Change 5.3.4 [expr.new] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

When the value of the <I>expression</I> in a
<I>noptr-new-declarator</I> is zero, the allocation function is called
to allocate an array with no elements.  If the value of that
<I>expression</I> is less than zero or such that the size of the allocated
object would exceed the implementation-defined limit, or if the
<I>new-initializer</I> is a <I>braced-init-list</I> for which the number of
<I>initializer-clause</I>s exceeds the number of elements to
initialize, no storage is obtained and the <I>new-expression</I>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">terminates by throwing</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">throws</SPAN> an exception
<SPAN style="font-weight:bold;background-color:#A0FFA0">(15.1 [except.throw])</SPAN> of a type that would match a
handler (15.3 [except.handle]) of type
<TT>std::bad_array_new_length</TT> (18.6.2.3 [new.badlength]).

</BLOCKQUOTE>

<LI><P>Change 15 [except] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...A handler will be invoked only by <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a <I>throw-expression</I>
invoked</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">throwing an exception</SPAN> in code executed in the
handler's try block or in functions called from the handler's try
block<SPAN style="text-decoration:line-through;background-color:#FFA0A0"> </SPAN>...

</BLOCKQUOTE>

<LI><P>Change 15 [except] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

A <I>try-block</I> is a <I>statement</I> (Clause 6 [stmt.stmt]).  A <I>throw-expression</I> is of type <TT>void</TT>.
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Code that executes a <I>throw-expression</I> is said to
&#8220;throw an exception;&#8221; code that subsequently gets control
is called a &#8220;handler.&#8221;</SPAN> [<I>Note:</I>...

</BLOCKQUOTE>

<LI><P>Change 15.1 [except.throw] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

Throwing an exception transfers control to a handler. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I>
An exception can be thrown from one of the following contexts:
<I>throw-expression</I> (see below), allocation functions
(3.7.4.1 [basic.stc.dynamic.allocation]), <TT>dynamic_cast</TT>
(5.2.7 [expr.dynamic.cast]), <TT>typeid</TT> (5.2.8 [expr.typeid]),
<I>new-expression</I> (5.3.4 [expr.new]), and standard
library functions (17.5.1.4 [structure.specifications]). &#8212;<I>end
note</I>]</SPAN> An object is passed and the type of that object
determines which handlers can catch it. [<I>Example:</I>...

</BLOCKQUOTE>

<LI><P>Change 15.1 [except.throw] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A <I>throw-expression</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Throwing an exception</SPAN>
copy-initializes (8.5 [dcl.init]<SPAN style="font-weight:bold;background-color:#A0FFA0">, <section-ref ref="12.8">12.8 [class.copy]</section-ref></SPAN>) a temporary object, called the <I>exception
object</I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">, the type of which is determined by removing any top-level
<I>cv-qualifier</I>s from the static type of the operand of
<TT>throw</TT> and adjusting the type from &#8220;array of
<TT>T</TT>&#8221; or &#8220;function returning <TT>T</TT>&#8221; to
&#8220;pointer to <TT>T</TT>&#8221; or &#8220;pointer to function
returning <TT>T</TT>&#8221;, respectively</SPAN>.  The temporary is an
lvalue and is used to initialize the variable named in the matching
<I>handler</I> (15.3 [except.handle]).  If the type of the
exception object would be an incomplete type or a pointer to an
incomplete type other than (possibly cv-qualified) <TT>void</TT> the
program is ill-formed. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">Except for these restrictions and the
restrictions on type matching mentioned in 15.3 [except.handle],
the operand of <TT>throw</TT> is treated exactly as a function
argument in a call (5.2.2 [expr.call]) or the operand of a
return statement.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Evaluating a <I>throw-expression</I> with
an operand throws an exception; the type of the exception object is
determined by removing any top-level <I>cv-qualifier</I>s from the
static type of the operand and adjusting the type from &#8220;array of
<TT>T</TT>&#8221; or &#8220;function returning <TT>T</TT>&#8221; to
&#8220;pointer to <TT>T</TT>&#8221; or &#8220;pointer to function
returning <TT>T</TT>,&#8221; respectively.</SPAN>

</BLOCKQUOTE>

<LI><P>Change 15.1 [except.throw] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

...[<I>Note:</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">an</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">a thrown</SPAN> exception
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">thrown by a <I>throw-expression</I></SPAN> does not propagate to
other threads unless caught, stored, and rethrown using appropriate
library functions; see 18.8.5 [propagation] and 30.6 [futures]. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Change 15.1 [except.throw] paragraph 8 as follows:</P></LI>

<BLOCKQUOTE>

A <I>throw-expression</I> with no operand rethrows the currently
handled exception (15.3 [except.handle]).  The exception is
reactivated with the existing <SPAN style="text-decoration:line-through;background-color:#FFA0A0">temporary</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">exception
object</SPAN>; no new <SPAN style="text-decoration:line-through;background-color:#FFA0A0">temporary</SPAN> exception object is created.
The exception is no longer considered to be caught; therefore, the
value of <TT>std::uncaught_exception()</TT> will again be
<TT>true</TT>. [<I>Example:</I>...

</BLOCKQUOTE>

<LI><P>Change 15.2 [except.ctor] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

As control passes from <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a <I>throw-expression</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">the
point where an exception is thrown</SPAN> to a handler, destructors are
invoked for all automatic objects constructed since the try block was
entered...

</BLOCKQUOTE>

<LI><P>Change 15.2 [except.ctor] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

The process of calling destructors for automatic objects constructed
on the path from a try block to <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a <I>throw-expression</I></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">the point where an exception is thrown</SPAN> is called
&#8220;<I>stack unwinding</I>.&#8221; If a destructor...

</BLOCKQUOTE>

<LI><P>Change 15.3 [except.handle] paragraph 17 as follows:</P></LI>

<BLOCKQUOTE>

When the handler declares <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a non-constant</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an</SPAN>
object, any changes to that object will not affect the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">temporary
object that was initialized by execution of the
<I>throw-expression</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">exception object</SPAN>.  When the
handler declares a reference to <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a non-constant</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">an</SPAN> object, any changes to the referenced object are changes
to the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">temporary object initialized when the
<I>throw-expression</I> was executed</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">exception object</SPAN>
and will have effect should that object be rethrown.

</BLOCKQUOTE>

<LI><P>Change 18.8.3.4 [terminate] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<I>Remarks</I>: Called by the implementation when exception handling
must be abandoned for any of several reasons (15.5.1 [except.terminate]), in effect immediately after <SPAN style="text-decoration:line-through;background-color:#FFA0A0">evaluating the
<I>throw-expression</I> (18.8.3.1 [terminate.handler])</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">throwing the exception</SPAN>.  May also be called directly by the
program.

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="388"></A><H4>388.
  
Catching base<TT>*&amp;</TT> from a throw of derived<TT>*</TT>
</H4><B>Section: </B>15.3&#160; [except.handle]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>28 Oct 2002<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>I have a question about exception handling with respect to derived to base
conversions of pointers caught by reference.</P>

<P>What should the result of this program be?</P>
<PRE>
  struct S             {};
  struct SS : public S {};

  int main()
  {
  	SS ss;
  	int result = 0;
  	try
  	{
  		throw &amp;ss; // throw object has type SS*
  		           // (pointer to derived class)
  	}
  	catch (S*&amp; rs) // (reference to pointer to base class)
  	{
  		result = 1;
  	}
  	catch (...)
  	{
  		result = 2;
  	}
  	return result;
  }
</PRE>

<P>The wording of 15.3 [except.handle] paragraph 3
would seem to say that the catch of S*&amp; does not
match and so the catch ... would be taken.</P>

<P>All of the compilers I tried (EDG, g++, Sun, and Microsoft) used the catch
of S*&amp; though.</P>

<P>What do we think is the desired behavior for such cases?</P>

<P>My initial reaction is that this is a bug in all of these compilers, but
the fact that they all do the same thing gives me pause.</P>

<P>On a related front, if the handler changes the parameter using the
reference, what is caught by a subsequent handler?</P>
<PRE>
  extern "C" int printf(const char *, ...);
  struct S             {};
  struct SS : public S {};
  SS ss;

  int f()
  {
  	try
  	{
  		throw &amp;ss;
  	}
  	catch (S*&amp; rs) // (reference to pointer to base class)
  	{
  		rs = 0;
  		throw;
  	}
  	catch (...)
  	{
  	}
  	return 0;
  }

  int main()
  {
  	try { f(); }
  	catch (S*&amp; rs) {
  		printf("rs=%p, &amp;ss=%p\n", rs, &amp;ss);
  	}
  }
</PRE>

<P>EDG, g++, and Sun all catch the original (unmodified) value.  Microsoft
catches the modified value.  In some sense the EDG/g++/Sun behavior makes
sense because the later catch could catch the derived class instead of the
base class, which would be difficult to do if you let the catch clause
update the value to be used by a subsequent catch.</P>

<P>But on this non-pointer case, all of the compilers later catch the
modified value:</P>
<PRE>
  extern "C" int printf(const char *, ...);
  int f()
  {
  	try
  	{
  		throw 1;
  	}
  	catch (int&amp; i)
  	{
  		i = 0;
  		throw;
  	}
  	catch (...)
  	{
  	}
  	return 0;
  }

  int main()
  {
  	try { f(); }
  	catch (int&amp; i) {
  		printf("i=%p\n", i);
  	}
  }
</PRE>

<P>To summarize:</P>
<OL>
<LI>Should "base*const&amp;" be able to catch a "derived*"? 
The current standard
seems to say "no" but parallels to how calls work, and existing practice,
suggest that the answer should be "yes".</LI>

<LI>Should "base*&amp;" be able to catch a "derived*".  Again,
the standard seems
seems to say "no".  Parallels to how calls work still suggest "no", but
existing practice suggests "yes".</LI>

<LI>If either of the above is "yes", what happens if you modify the pointer
referred to by the reference.  This requires a cast to remove const for
case #2.</LI>

<LI>On a related front, if you catch
"derived*&amp;" when a "derived*" is thrown,
what happens if you modify the pointer referred to by the reference?
EDG/g++/Sun still don't modify the underlying value that would be
caught by a rethrow in this case.  This case seems like it should be
the same as the "int&amp;" example above, but is not on the three compilers
mentioned.</LI>
</OL>

<P>(See also <A HREF="
     cwg_defects.html#729">issue 729</A>.)</P>



<P><B>Notes from the October, 2009 meeting:</B></P>

<P>The consensus of the CWG was that it should not be possible to catch
a pointer to a derived class using a reference to a base class pointer,
and that a handler that takes a reference to non-const pointer should
allow the pointer to be modified by the handler.</P>

<P><B>Proposed resolution (March, 2010):</B></P>

<P>Change 15.3 [except.handle] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<P>A <I>handler</I> is a match for an exception object of type
<TT>E</TT> if</P>

<UL><LI><P>The <I>handler</I> is of type <I>cv</I> <TT>T</TT> or
<I>cv</I> <TT>T&amp;</TT> and <TT>E</TT> and <TT>T</TT> are the
same type (ignoring the top-level <I>cv-qualifier</I>s), or</P></LI>

<LI><P>the <I>handler</I> is of type <I>cv</I> <TT>T</TT> or
<I>cv</I> <TT>T&amp;</TT> and <TT>T</TT> is an unambiguous public
base class of <TT>E</TT>, or</P></LI>

<LI><P>the <I>handler</I> is of type <I>cv<SPAN style="text-decoration:line-through;background-color:#FFA0A0">1</SPAN></I>
<TT>T<SPAN style="text-decoration:line-through;background-color:#FFA0A0">*</SPAN></TT><SPAN style="text-decoration:line-through;background-color:#FFA0A0"> <I>cv2</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">or <TT>const
T&amp;</TT> where <TT>T</TT> is a pointer type</SPAN> and <TT>E</TT> is
a pointer type that can be converted to <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the type of the
handler</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>T</TT></SPAN> by either or both of</P></LI>

<UL><LI><P>a standard pointer conversion (4.10 [conv.ptr]) not involving conversions to pointers to private or
protected or ambiguous classes</P></LI>

<LI><P>a qualification conversion</P></LI>

</UL>

<LI><P>the <I>handler</I> is <SPAN style="font-weight:bold;background-color:#A0FFA0">of type <I>cv</I> <TT>T</TT> or <TT>const T&amp;</TT> where <TT>T</TT> is</SPAN> a pointer or pointer to member type
and <TT>E</TT> is <TT>std::nullptr_t</TT>.</P></LI>

</UL>

</BLOCKQUOTE>

<P>(This resolution also resolves <A HREF="
     cwg_defects.html#729">issue 729</A>.)</P>

<P><B>Notes from the March, 2011 meeting:</B></P>

<P>This resolution would require an ABI change and was thus deferred
for further consideration.</P>

<BR><BR><HR><A NAME="729"></A><H4>729.
  
Qualification conversions and handlers of reference-to-pointer type
</H4><B>Section: </B>15.3&#160; [except.handle]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>6 October, 2008<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>

<P>Given the following example:</P>

<PRE>
    int f() {
        try { /* ... */ }
        catch(const int*&amp;) {
            return 1;
        }
        catch(int*&amp;) {
            return 2;
        }
        return 3;
    }
</PRE>

<P>can <TT>f()</TT> return <TT>2</TT>?  That is, does an
<TT>int*</TT> exception object match a <TT>const int*&amp;</TT>
handler?</P>

<P>According to 15.3 [except.handle] paragraph 3, it does not:</P>

<BLOCKQUOTE>

<P>A <I>handler</I> is a match for an exception object of type
<TT>E</TT> if</P>

<UL>
<LI><P>The <I>handler</I> is of type <I>cv</I> <TT>T</TT> or <I>cv</I>
<TT>T&amp;</TT> and <TT>E</TT> and <TT>T</TT> are the same type
(ignoring the top-level <I>cv-qualifier</I>s), or</P></LI>

<LI><P>the <I>handler</I> is of type <I>cv</I> <TT>T</TT> or <I>cv</I>
<TT>T&amp;</TT> and <TT>T</TT> is an unambiguous public base class of
<TT>E</TT>, or</P></LI>

<LI><P>the handler is of type <I>cv1</I> <TT>T*</TT> <I>cv2</I> and
<TT>E</TT> is a pointer type that can be converted to the type of the
handler by either or both of</P>

<UL>
<LI><P>a standard pointer conversion (4.10 [conv.ptr]) not
involving conversions to pointers to private or protected or ambiguous
classes</P></LI>

<LI><P>a qualification conversion</P></LI>
</UL></LI>

<LI><P>the <I>handler</I> is a pointer or pointer to member type and
<TT>E</TT> is <TT>std::nullptr_t</TT>.</P></LI>

</UL>

</BLOCKQUOTE>

<P>Only the third bullet allows qualification conversions, but
only the first bullet applies to a <I>handler</I> of
reference-to-pointer type.  This is consistent with how other
reference bindings work; for example, the following is ill-formed:</P>

<PRE>
    int* p;
    const int*&amp; r = p;
</PRE>

<P>(The consistency is not complete; the reference binding would be
permitted if <TT>r</TT> had type <TT>const int* const &amp;</TT>, but
a handler of that type would still not match an <TT>int*</TT>
exception object.)</P>

<P>However, implementation practice seems to be in the other
direction; both EDG and g++ do match an <TT>int*</TT> with a <TT>const
int*&amp;</TT>, and the Microsoft compiler issues an error for the
presumed hidden handler in the code above. Should the Standard be
changed to reflect existing practice?</P>

<P>(See also <A HREF="
     cwg_defects.html#388">issue 388</A>.)</P>



<P><B>Notes from the October, 2009 meeting:</B></P>

<P>The CWG agreed that matching the exception object with a handler
should, to the extent possible, mimic ordinary reference binding in
cases like this.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>This issue is resolved by the resolution of <A HREF="
     cwg_defects.html#388">issue 388</A>.</P>

<BR><BR><HR><A NAME="1267"></A><H4>1267.
  
Rvalue reference types in <I>exception-specification</I>s
</H4><B>Section: </B>15.4&#160; [except.spec]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Michael Wong
 &#160;&#160;&#160;

 <B>Date: </B>2011-03-21<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>

<P>The types that may appear in an <I>exception-specification</I>
(15.4 [except.spec] paragraph 2) include rvalue reference types,
although they are excluded as handler types (15.3 [except.handle]
paragraph 1).  This appears to have been an oversight.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 15.4 [except.spec] paragraph 2 as follows:</P>

<BLOCKQUOTE>

...A type denoted in an <I>exception-specification</I> shall not
denote an incomplete type <SPAN style="font-weight:bold;background-color:#A0FFA0">or an rvalue reference type</SPAN>.  A
type denoted in an <I>exception-specification</I> shall not denote a
pointer or reference...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1282"></A><H4>1282.
  
Underspecified destructor <I>exception-specification</I>
</H4><B>Section: </B>15.4&#160; [except.spec]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2011-03-28<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>It is not clear whether the unexpected handler will be invoked in
the following example:</P>

<PRE>
  #include &lt;iostream&gt;
  #include &lt;exception&gt;

  struct A { ~A() throw() { } };
  struct B { ~B() noexcept { } };
  struct C : A, B { ~C() { throw 0; } };

  void unexpected_observer() {
   std::cerr &lt;&lt; "unexpected called" &lt;&lt; std::endl;
   std::terminate();
  }

  int main() {
   std::set_unexpected(unexpected_observer);
   C c;
  }

</PRE>

<P>The problem is 15.4 [except.spec] paragraph 14 only says that
the <I>exception-specification</I> of <TT>C::~C</TT> &#8220;shall allow
no exceptions,&#8221; which could mean either <TT>throw()</TT> or
<TT>noexcept(true)</TT>.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change 15.4 [except.spec] paragraph 14 as follows:</P>

<BLOCKQUOTE>

<P>An implicitly declared special member function (Clause 12 [special]) <SPAN style="text-decoration:line-through;background-color:#FFA0A0">shall have</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">has</SPAN> an
<I>exception-specification</I>.  If <TT>f</TT> is an implicitly
declared default constructor, copy constructor, move constructor,
destructor, copy assignment operator, or move assignment operator, its
implicit <I>exception-specification</I> specifies the <I>type-id</I> <TT>T</TT>
if and only if <TT>T</TT> is allowed by the
<I>exception-specification</I> of a function directly invoked by
<TT>f</TT>'s implicit definition; <TT>f</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">shall allow</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">allows</SPAN> all exceptions if any function it directly invokes
allows all exceptions, and <TT>f</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">shall allow no
exceptions</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">has the <I>exception-specification</I>
<TT>noexcept(true)</TT></SPAN> if every function it directly invokes
allows no exceptions. [<I>Example:</I></P>

<PRE>
  struct A {
    A();
    A(const A&amp;) throw();
    A(A&amp;&amp;) throw();
    ~A() throw(X);
  };
  struct B {
    B() throw();
    B(const B&amp;) throw();
    B(B&amp;&amp;) throw(Y);
    ~B() throw(Y);
  };
  struct D : public A, public B {
      //<SPAN style="font-family:Times;font-style:italic"> Implicit declaration of </SPAN>D::D();
      //<SPAN style="font-family:Times;font-style:italic"> Implicit declaration of </SPAN>D::D(const D&amp;) <SPAN style="text-decoration:line-through;background-color:#FFA0A0">throw()</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">noexcept(true)</SPAN>;
      //<SPAN style="font-family:Times;font-style:italic"> Implicit declaration of </SPAN>D::D(D&amp;&amp;) throw(Y);
      //<SPAN style="font-family:Times;font-style:italic"> Implicit declaration of </SPAN>D::~D() throw(X, Y);
  };
</PRE>

<P>Furthermore, if...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1381"></A><H4>1381.
  
Implicitly-declared special member functions and default <TT>nothrow</TT>
</H4><B>Section: </B>15.4&#160; [except.spec]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>David Svoboda
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-26<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>

<P>According to 15.4 [except.spec] paragraph 14,</P>

<BLOCKQUOTE>

An implicitly declared special member function (Clause 12 [special]) shall
have an <I>exception-specification</I>.  If <TT>f</TT> is an implicitly declared
default constructor, copy constructor, move constructor,
destructor, copy assignment operator, or move assignment
operator, its implicit <I>exception-specification</I> specifies the
<I>type-id</I> <TT>T</TT> if and only if <TT>T</TT> is allowed by the
<I>exception-specification</I> of a function directly invoked by
<TT>f</TT>'s implicit definition; <TT>f</TT> shall allow all
exceptions if any function it directly invokes allows all
exceptions, and <TT>f</TT> shall allow no exceptions if every
function it directly invokes allows no exceptions.

</BLOCKQUOTE>

<P>It would be clearer if this description made explicit the intent
that special member functions that invoke no other functions are to
allow no exceptions.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 15.4 [except.spec] paragraph 14 as follows:</P>

<BLOCKQUOTE>

<P>...and <TT>f</TT> has the <I>exception-specification</I>
<TT>noexcept(true)</TT> if every function it directly invokes allows
no exceptions. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> It follows that <TT>f</TT> has the
<I>exception-specification</I> <TT>noexcept(true)</TT> if it invokes
no other functions. &#8212;<I>end note</I>]</SPAN> [<I>Example:</I></P>

<PRE>
  struct A {
    A();
    A(const A&amp;) throw();
    A(A&amp;&amp;) throw();
    ~A() throw(X);
  };
  struct B {
    B() throw();
    B(const B&amp;) <SPAN style="text-decoration:line-through;background-color:#FFA0A0">throw()</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">= default</SPAN>;  <SPAN style="font-weight:bold;background-color:#A0FFA0">//<SPAN style="font-family:Times;font-style:italic"> Declaration of </SPAN>B::B(const B&amp;) noexcept(true)</SPAN>
    B(B&amp;&amp;) throw(Y);
    ~B() throw(Y);
  };
  ...
</PRE>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1370"></A><H4>1370.
  
<I>identifier-list</I> cannot contain ellipsis
</H4><B>Section: </B>16.3&#160; [cpp.replace]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Nikolay Ivchenkov
 &#160;&#160;&#160;

 <B>Date: </B>2011-08-14<BR>


<P>[Moved to DR at the October, 2012 meeting.]</P>



<P>16.3 [cpp.replace] paragraph 12 says,</P>

<BLOCKQUOTE>

If there is a <TT>...</TT> in the <I>identifier-list</I> in the
macro definition...

</BLOCKQUOTE>

<P>However, an <I>identifier-list</I> cannot contain an ellipsis
according to the grammar in 16 [cpp] paragraph 1.</P>

<P><B>Proposed resolution (February, 2012):</B></P>

<P>Change 16.3 [cpp.replace] paragraph 12 as follows:</P>

<BLOCKQUOTE>

If there is a <TT>...</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">in the identifier-list</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">immediately preceding the <TT>)</TT></SPAN> in the
<SPAN style="font-weight:bold;background-color:#A0FFA0">function-like</SPAN> macro definition, then the trailing
arguments, including any separating comma preprocessing tokens, are
merged to form a single item: the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">variable arguments</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>variable arguments</I></SPAN>.  The number of arguments so
combined is such that, following merger, the number of arguments is
one more than the number of parameters in the macro definition
(excluding the <TT>...</TT>).

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1329"></A><H4>1329.
  
Recursive deduction substitutions
</H4><B>Section: </B>B&#160; [implimits]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2011-06-02<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>It is not clear whether the implementation limit on recursion in
template instantiation applies only to instantiation itself or also
to recursion that occurs during template argument deduction.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Change B [implimits] as follows:</P>

<UL><LI><P>Recursively nested template instantiations<SPAN style="font-weight:bold;background-color:#A0FFA0">, including
substitution during template argument deduction (14.8.2 [temp.deduct])</SPAN> [1 024].</P></LI></UL>

<BR><BR><HR><A NAME="1251"></A><H4>1251.
  
C compatibility: casting to unqualified <TT>void*</TT>
</H4><B>Section: </B>C.1.3&#160; [diff.conv]
 &#160;&#160;&#160;

 <B>Status: </B>DRWP
 &#160;&#160;&#160;

 <B>Submitter: </B>Johannes Schaub
 &#160;&#160;&#160;

 <B>Date: </B>2011-03-04<BR>


<P>[Voted into the WP at the February, 2012 meeting;
moved to DR at the October, 2012 meeting.]</P>



<P>The incompatibility described appears not to exist.</P>

<P><B>Proposed resolution (August, 2011):</B></P>

<P>Delete the second entry in C.1.3 [diff.conv], i.e., the
one headed by</P>

<BLOCKQUOTE>

<B>Change:</B> Only pointers to non-const and non-volatile objects may
be implicitly converted to <TT>void*</TT>

</BLOCKQUOTE>

<BR><BR><BR><BR><HR><A NAME="WP Status"></A><H3>Issues with "WP" Status</H3><BR><BR><HR><A NAME="CD1 Status"></A><H3>Issues with "CD1" Status</H3>
<HR><A NAME="663"></A><H4>663.
  
Valid Cyrillic identifier characters
</H4><B>Section: </B>_N2691_.E&#160; [extendid]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Clamage
 &#160;&#160;&#160;

 <B>Date: </B>30 November 2007<BR>


<P>[Voted into the WP at the June, 2008 meeting.]</P>

<P>The C99 and C++ Standards disagree about the validity of two
Cyrillic characters for use in identifiers.  C++ (_N2691_.E [extendid]) says that 040d is valid in an identifier but that 040e is
not; C99 (Annex D) says exactly the opposite.  In fact, both
characters should be accepted in identifiers; see
<A href="http://www.unicode.org/charts/PDF/U0400.pdf">the
Unicode chart</A>.</P>

<P><B>Proposed resolution (February, 2008):</B></P>

<P>The reference in paragraph 2 should be changed to ISO/IEC TR 10176:2003
and the table should be changed to conform to the one in that document
(beginning on page 34).  
</P>

<BR><BR><HR><A NAME="357"></A><H4>357.
  
Definition of signature should include name
</H4><B>Section: </B>1.3&#160; [intro.defs]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Clamage
 &#160;&#160;&#160;

 <B>Date: </B>26 May 2002<BR>


<P>[Voted into WP at April, 2007 meeting.]</P>



<P>Section 1.3 [intro.defs], definition of "signature"
omits the function name as part of the signature. Since the name participates
in overload resolution, shouldn't it be included in the definition?
I didn't find a definition of signature in the ARM,
but I might have missed it.</P>

<P><U>Fergus Henderson:</U>
I think so.  In particular, 17.6.4.3.2 [global.names]
reserves certain "function
signatures" for use by the implementation, which would be wrong
unless the signature includes the name.</P>
<BLOCKQUOTE>
<P>-2- Each global function signature declared with external linkage in a
header is reserved to the implementation to designate that function
signature with external linkage.</P>
<P>-5- Each function signature from the Standard C library declared with
external linkage is reserved to the implementation for use as a
function signature with both extern "C" and extern "C++" linkage,
or as a name of namespace scope in the global namespace.
</P>
</BLOCKQUOTE>
<P>Other uses of the term "function signature" in the description of the
standard library also seem to assume that it includes the name.</P>

<P><U>James Widman</U>: </P>

<P>Names don't participate in overload resolution; name lookup is
separate from overload resolution.  However, the word
&#8220;signature&#8221; is not used in clause 13 [over].
It <I>is</I> used in linkage and declaration matching (e.g.,
14.5.6.1 [temp.over.link]).  This suggests that the name
and scope of the function should be part of its signature.</P>

<P><B>Proposed resolution (October, 2006):</B></P>

<OL>

<LI><P>Replace 1.3 [intro.defs] &#8220;<SPAN style="font-weight:bold;background-color:#A0FFA0">signature</SPAN>&#8221;
with the following:</P>
</LI>

<BLOCKQUOTE>

the name and the parameter-type-list (8.3.5 [dcl.fct])
of a function, as well as the class or namespace of which it is a
member.  If a function or function template is a class member its
signature additionally includes the <I>cv</I>-qualifiers (if any) on
the function or function template itself.  The signature of a function
template additionally includes its return type and its template
parameter list.  The signature of a function template specialization
includes the signature of the template of which it is a specialization
and its template arguments (whether explicitly specified or deduced).
[<I>Note:</I> Signatures are used as a basis for name-mangling and
linking.  &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Delete paragraph 3 and replace the first sentence of
14.5.6.1 [temp.over.link] as follows:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">The signature of a function template specialization consists of the
signature of the function template and of the actual template
arguments (whether explicitly specified or deduced).</SPAN></P>

<P>The signature of a function template <SPAN style="text-decoration:line-through;background-color:#FFA0A0">consists of its function
signature, its return type and its template parameter list</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">is
defined in 1.3 [intro.defs]</SPAN>. The names
of the template parameters are significant...</P>

</BLOCKQUOTE>

</OL>

<P>(See also <A HREF="
     cwg_defects.html#537">issue 537</A>.)</P>

<BR><BR><HR><A NAME="537"></A><H4>537.
  
Definition of &#8220;signature&#8221;
</H4><B>Section: </B>1.3&#160; [intro.defs]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>12 October 2005<BR>


<P>[Voted into WP at April, 2007 meeting.]</P>



<P>The standard defines &#8220;signature&#8221; in two places:
1.3 [intro.defs] and 14.5.6.1 [temp.over.link]
paragraphs 3-4.  The former seems to be meant as a formal definition
(I think it's the only place covering the nontemplate case), yet it
lacks some bits mentioned in the latter (specifically, the notion of a
&#8220;signature of a function template,&#8221; which is part of every
signature of the associated function template specializations).</P>

<P>Also, I think the 1.3 [intro.defs] words &#8220;the
information about a function that participates in overload
resolution&#8221; isn't quite right either.  Perhaps, &#8220;the
information about a function that distinguishes it in a set of
overloaded functions?&#8221;</P>

<P><U>Eric Gufford</U>:</P>

<P>In 1.3 [intro.defs] the definition states that
&#8220;Function signatures do not include return type, because that
does not participate in overload resolution,&#8221; while 14.5.6.1 [temp.over.link] paragraph 4 states &#8220;The signature of a
function template consists of its function signature, its return type
and its template parameter list.&#8221; This seems inconsistent and
potentially confusing. It also seems to imply that two identical
function templates with different return types are distinct
signatures, which is in direct violation of 13.3 [over.match]. 14.5.6.1 [temp.over.link] paragraph 4 should be
amended to include verbiage relating to overload resolution.</P>

<P>Either return types are included in function signatures, or they're
not, across the board. IMHO, they should be included as they are an
integral part of the function declaration/definition irrespective of
overloads.  Then verbiage should be added about overload resolution to
distinguish between signatures and overload rules. This would help
clarify things, as it is commonly understood that overload
resolution is based on function signature.</P>

<P>In short, the term &#8220;function signature&#8221; should be made
consistent, and removed from its (implicit, explicit or otherwise)
linkage to overload resolution as it is commonly understood.</P>

<P><U>James Widman</U>: </P>

<P>The problem is that (a) if you say the return type is part of the  
signature of a non-template function, then you have overloading but  
not overload resolution on return types (i.e., what we have now with  
function templates).  I don't think anyone wants to make the language  
uglier in that way.   And (b) if you say that the return type is not  
part of the signature of a function template, you will break code.   
Given those alternatives, it's probably best to maintain the status  
quo (which the implementors appear to have rendered faithfully).
</P>

<P><B>Proposed resolution (September, 2006):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#357">issue 357</A>.</P>

<BR><BR><HR><A NAME="513"></A><H4>513.
  
Non-class &#8220;most-derived&#8221; objects
</H4><B>Section: </B>1.8&#160; [intro.object]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Marc Schoolderman
 &#160;&#160;&#160;

 <B>Date: </B>20 Mar 2005<BR>


<P>[Voted into WP at April, 2006 meeting.]</P>

<P>The standard uses &#8220;most derived object&#8221; in some places
(for example, 1.3 [intro.defs] &#8220;<B>dynamic
type</B>,&#8221; 5.3.5 [expr.delete]) to refer to objects of
both class and non-class type. However, 1.8 [intro.object] only
formally defines it for objects of class type.</P>

<P>Possible fix: Change the wording in 1.8 [intro.object]
paragraph 4 from</P>

<BLOCKQUOTE>
an object of a most derived class type is called a most derived object
</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>
an object of a most derived class type, or of non-class type, is called
a most derived object
</BLOCKQUOTE>

<P><B>Proposed resolution (October, 2005):</B></P>

<P>Add the indicated words to 1.8 [intro.object] paragraph 4:</P>

<BLOCKQUOTE>

If a complete object, a data member (9.2 [class.mem]), or
an array element is of class type, its type is considered the <I>most
derived</I> class, to distinguish it from the class type of any base
class subobject; an object of a most derived class type<SPAN style="font-weight:bold;background-color:#A0FFA0">, or of a
non-class type,</SPAN> is called a <I>most derived object</I>.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="637"></A><H4>637.
  
Sequencing rules and example disagree
</H4><B>Section: </B>1.9&#160; [intro.execution]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Ofer Porat
 &#160;&#160;&#160;

 <B>Date: </B>2 June 2007<BR>


<P>[Voted into the WP at the September, 2008 meeting.]</P>



<P>In 1.9 [intro.execution] paragraph 16, the following expression is
still listed as an example of undefined behavior:</P>

<PRE>
    i = ++i + 1;
</PRE>

<P>However, it appears that the new sequencing rules make this expression
well-defined:</P>
<OL>
<LI><P>The assignment side-effect is required to be sequenced
after the value computations of both its LHS and RHS
(5.17 [expr.ass] paragraph 1).</P></LI>

<LI><P>The LHS (<TT>i</TT>) is an lvalue, so its value
computation involves computing the address
of <TT>i</TT>.</P></LI>

<LI><P>In order to value-compute the RHS (<TT>++i + 1</TT>), it is necessary to
first value-compute the lvalue expression <TT>++i</TT> and then do an
lvalue-to-rvalue conversion on the result.  This guarantees that the
incrementation side-effect is sequenced before the computation of the
addition operation, which in turn is sequenced before the assignment
side effect.  In other words, it yields a well-defined order and final
value for this expression.</P></LI>
</OL>

<P>It should be noted that a similar expression</P>

<PRE>
    i = i++ + 1;
</PRE>

<P>is still not well-defined, since the incrementation side-effect remains
unsequenced with respect to the assignment side-effect.</P>

<P>It's unclear whether making the expression in the example
well-defined was intentional or just a coincidental byproduct of
the new sequencing rules.  In either case either the example
should be fixed, or the rules should be changed.</P>

<P><U>Clark Nelson</U>: In my opinion, the poster's argument is
perfectly correct. The rules adopted reflect the CWG's desired
outcome for <A HREF="
     cwg_defects.html#222">issue 222</A>. At the Portland
meeting, I presented (and still sympathize with) Tom Plum's case
that these rules go a little too far in nailing down required
behavior; this is a consequence of that.</P>

<P>One way or another, a change needs to be made, and I think we
should seriously consider weakening the resolution of <A HREF="
     cwg_defects.html#222">issue 222</A> to keep this example as having
undefined behavior. This could be done fairly simply by having
the sequencing requirements for an assignment expression depend
on whether it appears in an lvalue context.</P>

<P><U>James Widman</U>: How's this for a possible re-wording?</P>

<BLOCKQUOTE>

In all cases, the side effect of the assignment expression is
sequenced after the value computations of the right and left
operands.  Furthermore, if the assignment expression appears in a
context where an lvalue is required, the side effect of the
assignment expression is sequenced before its value computation.

</BLOCKQUOTE>

<P><B>Notes from the February, 2008 meeting:</B></P>

<P>There was no real support in the CWG for weakening the resolution
of <A HREF="
     cwg_defects.html#222">issue 222</A> and returning the example to
having undefined behavior. No one knew of an implementation that
doesn't already do the (newly) right thing for such an example, so
there was little motivation to go out of our way to increase the
domain of undefined behavior. So the proposed resolution is to change
the example to one that definitely does have undependable behavior in
existing practice, and undefined behavior under the new rules.</P>

<P>Also, the new formulation of the sequencing rules approved in
Oxford contained the wording that by and large resolved <A HREF="
     cwg_defects.html#222">issue 222</A>, so with the resolution of this issue, we
can also close <A HREF="
     cwg_defects.html#222">issue 222</A>.</P>

<P><B>Proposed resolution (March, 2008):</B></P>

<P>Change the example in 1.9 [intro.execution] paragraph 16 as
follows:</P>

<PRE>
    i = v[i++];             //<SPAN style="font-family:Times;font-style:italic"> the behavior is undefined</SPAN>
    i = 7, i++, i++;        //<SPAN style="font-family:Times;font-style:italic"> </SPAN>i<SPAN style="font-family:Times;font-style:italic"> becomes </SPAN>9
    i = <SPAN style="text-decoration:line-through;background-color:#FFA0A0">++i</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">i++</SPAN> + 1;        //<SPAN style="font-family:Times;font-style:italic"> the behavior is undefined</SPAN>
    i = i + 1;              //<SPAN style="font-family:Times;font-style:italic"> the value of </SPAN>i<SPAN style="font-family:Times;font-style:italic"> is incremented</SPAN>
</PRE>

<BR><BR><HR><A NAME="639"></A><H4>639.
  
What makes side effects &#8220;different&#8221; from one another?
</H4><B>Section: </B>1.9&#160; [intro.execution]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>James Widman
 &#160;&#160;&#160;

 <B>Date: </B>26 July 2007<BR>


<P>[Voted into the WP at the September, 2008 meeting.]</P>



<P>Is the behavior undefined in the following example?</P>

<PRE>
    void f() {
         int n = 0;
         n = --n;
    }
</PRE>

<P>1.9 [intro.execution] paragraph 16 says,</P>

<BLOCKQUOTE>

If a side effect on a scalar object is unsequenced relative to
either a different side effect on the same scalar object or a
value computation using the value of the same scalar object, the
behavior is undefined.

</BLOCKQUOTE>

<P>It's not clear to me whether the two side-effects in <TT>n=--n</TT>
are &#8220;different.&#8221;  As far as I can tell, it seems that both
side-effects involve the assignment of -1 to n, which in a sense
makes them non-&#8220;different.&#8221;  But I don't know if that's the
intent.  Would it be better to say &#8220;another&#8221; instead of
&#8220;a different?&#8221;</P>

<P>On a related note, can we include this example to illustrate?</P>

<PRE>
    void f( int, int );
    void g( int a ) { f( a = -1, a = -1 ); } // Undefined?
</PRE>

<P><B>Proposed resolution (March, 2008):</B></P>

<P>Change 1.9 [intro.execution] paragraph 16 as follows:</P>

<BLOCKQUOTE>

<P>...If a side effect on a scalar object is unsequenced
relative to either <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a different</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">another</SPAN> side effect
on the same scalar object or a value computation using the value
of the same scalar object, the behavior is
undefined. [<I>Example:</I></P>

<PRE>
    <SPAN style="font-weight:bold;background-color:#A0FFA0">void f(int, int);
    void g(int i, int* v) {</SPAN>
        i = v[i++];         //<SPAN style="font-family:Times;font-style:italic"> the behavior is undefined</SPAN>
        i = 7, i++, i++;    //<SPAN style="font-family:Times;font-style:italic"> </SPAN>i<SPAN style="font-family:Times;font-style:italic"> becomes </SPAN>9

        i = ++i + 1;        //<SPAN style="font-family:Times;font-style:italic"> the behavior is undefined</SPAN>
        i = i + 1;          //<SPAN style="font-family:Times;font-style:italic"> the value of </SPAN>i<SPAN style="font-family:Times;font-style:italic"> is incremented</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">
        f(i = -1, i = -1);  //<SPAN style="font-family:Times;font-style:italic"> the behavior is undefined</SPAN>
    }</SPAN>
</PRE>

<P>&#8212;<I>end example</I>] When calling...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="362"></A><H4>362.
  
Order of initialization in instantiation units
</H4><B>Section: </B>2.2&#160; [lex.phases]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mark Mitchell
 &#160;&#160;&#160;

 <B>Date: </B>2 July 2002<BR>


<P>[Voted into WP at March 2004 meeting.]</P>

<P>Should this program do what its author obviously expects?  As far as
I can tell, the standard says that the point of instantiation for
Fib&lt;n-1&gt;::Value is the same as the point of instantiation as the
enclosing specialization, i.e., Fib&lt;n&gt;::Value.  What in the standard
actually says that these things get initialized in the right order?</P>
<PRE>
  template&lt;int n&gt;
  struct Fib { static int Value; };

  template &lt;&gt;
  int Fib&lt;0&gt;::Value = 0;

  template &lt;&gt;
  int Fib&lt;1&gt;::Value = 1;

  template&lt;int n&gt;
  int Fib&lt;n&gt;::Value = Fib&lt;n-1&gt;::Value + Fib&lt;n-2&gt;::Value;

  int f ()
  {
    return Fib&lt;40&gt;::Value;
  }
</PRE>
<P><U>John Spicer</U>:
My opinion is that the standard does not specify
the behavior of this program.
I thought there was a core issue related to this, but I could not find it.
The issue that I recall proposed tightening up the static initialization
rules to make more cases well defined.</P>

<P>Your comment about point of instantiation is correct, but I don't think that
really matters.  What matters is the order of execution of the initialization
code at execution time.  Instantiations don't really live in
"translation units"
according to the standard.  They live in "instantiation units", and the
handling of instantiation units in initialization is unspecified (which should
probably be another core issue).  See 2.2 [lex.phases]
paragraph 8.</P>

<P><B>Notes from October 2002 meeting:</B></P>

<P>We discussed this and agreed that we really do mean the the order
is unspecified.  John Spicer will propose wording on handling of
instantiation units in initialization.</P>

<P><B>Proposed resolution (April 2003):</B></P>
<P>
TC1 contains the following text in 3.6.2 [basic.start.init]
paragraph 1:</P>

<BLOCKQUOTE>
Objects with static storage duration defined in namespace scope in the
same translation unit and dynamically initialized shall be initialized
in the order in which their definition appears in the translation
unit.
</BLOCKQUOTE>

<P>
This was revised by <A HREF="
     cwg_defects.html#270">issue 270</A> to read:</P>

<BLOCKQUOTE>
Dynamic initialization of an object is either ordered or unordered.
Explicit specializations and definitions
of class template static data members have ordered
initialization. Other class template static data member instances have
unordered initialization. Other objects defined in namespace scope
have ordered initialization. Objects defined within a single
translation unit and with ordered initialization shall be initialized
in the order of their definitions in the translation unit. The order
of initialization is unspecified for objects with unordered
initialization and for objects defined in different translation units.
</BLOCKQUOTE>

<P>
This addresses this issue but while reviewing this issue some
additional changes were suggested for the above wording:</P>

<BLOCKQUOTE>
Dynamic initialization of an object is either ordered or unordered.
<SPAN style="font-weight:bold;background-color:#A0FFA0">Definitions of explicitly specialized</SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Explicit specializations and definitions of</SPAN>
class template static data members have ordered
initialization. Other class template static data member<SPAN style="font-weight:bold;background-color:#A0FFA0">s (i.e.,
implicitly or explicitly instantiated specializations)</SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">instances</SPAN> have
unordered initialization. Other objects defined in namespace scope
have ordered initialization. Objects defined within a single
translation unit and with ordered initialization shall be initialized
in the order of their definitions in the translation unit. The order
of initialization is unspecified for objects with unordered
initialization and for objects defined in different translation units.
</BLOCKQUOTE>

<BR><BR><HR><A NAME="558"></A><H4>558.
  
Excluded characters in universal character names
</H4><B>Section: </B>2.3&#160; [lex.charset]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>8 February 2006<BR>


<P>[Moved to DR at October 2007 meeting.]</P>

<P>C99 and C++ differ in their approach to universal character
names (UCNs).</P>

<P><A HREF="
     cwg_defects.html#248">Issue 248</A> already covers the differences
in UCNs allowed for identifiers, but a more fundamental issue is that
of UCNs that correspond to codes reserved by ISO 10676 for surrogate
pair forms.</P>

<P>Specifically, C99 does not allow UCNs whose short names
are in the range 0xD800 to 0xDFFF.  I think C++ should
have the same constraint.  If someone really wants to
place such a code in a character or string literal,
they should use a hexadecimal escape sequence instead,
for example:</P>

<PRE>
    wchar_t  w1 = L'\xD900'; // Okay.
    wchar_t  w2 = L'\uD900'; // Error, not a valid character.
</PRE>

<P>(Compare 6.4.3 paragraph 2 in ISO/IEC 9899/1999 with
2.3 [lex.charset] paragraph 2 in the C++
standard.)</P>

<P><B>Proposed resolution (October, 2007):</B></P>

<P>This issue is resolved by the adoption of paper
J16/07-0030 = WG21 N2170.</P>

<BR><BR><HR><A NAME="505"></A><H4>505.
  
Conditionally-supported behavior for unknown character escapes
</H4><B>Section: </B>2.14.3&#160; [lex.ccon]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>14 Apr 2005<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>

<P>The current wording of 2.14.3 [lex.ccon] paragraph 3
states,</P>

<BLOCKQUOTE>

If the character following a backslash is not one of those specified,
the behavior is undefined.

</BLOCKQUOTE>

<P>Paper J16/04-0167=WG21 N1727 suggests that such character escapes
be ill-formed.  In discussions at the Lillehammer meeting, however,
the CWG felt that the newly-approved category of
conditionally-supported behavior would be more appropriate.</P>

<P><B>Proposed resolution (April, 2006):</B></P>

<P>Change the next-to-last sentence of 2.14.3 [lex.ccon]
paragraph 3 from:</P>

<BLOCKQUOTE>

If the character following a backslash is not one of those specified,
the behavior is undefined.

</BLOCKQUOTE>

<P>to:</P>

<BLOCKQUOTE>

Escape sequences in which the character following the backslash is not
listed in Table 6 are conditionally-supported, with
implementation-defined semantics.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="309"></A><H4>309.
  
Linkage of entities whose names are not simply identifiers, in introduction
</H4><B>Section: </B>3&#160; [basic]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>17 Sep 2001<BR>


<P>[Voted into the WP at the June, 2008 meeting.]</P>

<P>
3 [basic] paragraph 8, while not incorrect, does not
allow for linkage of operators and conversion functions. It says:</P>
<BLOCKQUOTE>
An identifier used in more than one translation unit can potentially
refer to the same entity in these translation units depending on the
linkage (3.5 [basic.link]) of the identifier specified in each
translation unit.
</BLOCKQUOTE>

<P><B>Proposed Resolution (November, 2006):</B></P>

<P>This issue is resolved by the proposed resolution of
<A HREF="
     cwg_defects.html#485">issue 485</A>.</P>
<BR><BR><HR><A NAME="485"></A><H4>485.
  
What is a &#8220;name&#8221;?
</H4><B>Section: </B>3&#160; [basic]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Gabriel Dos Reis
 &#160;&#160;&#160;

 <B>Date: </B>9 Nov 2004<BR>


<P>[Voted into the WP at the June, 2008 meeting.]</P>



<P>Clause 3 [basic] paragraph 4 says:</P>

<BLOCKQUOTE>

A <I>name</I> is a use of an identifier (2.11 [lex.name])
that denotes an entity or label (6.6.4 [stmt.goto],
6.1 [stmt.label]).

</BLOCKQUOTE>

<P>Just three paragraphs later, it says</P>

<BLOCKQUOTE>

<P>Two names are the <I>same</I> if</P>

<P><UL>

<LI>they are identifiers composed of the same character sequence;
or</LI>

<LI>they are the names of overloaded operator functions formed with
the same operator; or</LI>

<LI>they are the names of user-defined conversion functions formed
with the same type.</LI>
</UL></P>

</BLOCKQUOTE>

<P>The last two bullets contradict the definition of <I>name</I>
in paragraph 4 because they are not identifiers.</P>

<P>This definition affects other parts of the Standard, as well.
For example, in 3.4.2 [basic.lookup.argdep] paragraph 1,</P>

<BLOCKQUOTE>

When an unqualified name is used as the <I>postfix-expression</I>
in a function call (5.2.2 [expr.call]), other
namespaces not considered during the usual unqualified lookup
(3.4.1 [basic.lookup.unqual]) may be searched, and in those
namespaces, namespace-scope friend function declarations
(11.3 [class.friend]) not otherwise visible may be found.

</BLOCKQUOTE>

<P>With the current definition of <I>name</I>, argument-dependent
lookup apparently does not apply to function-notation calls to
overloaded operators.</P>

<P>Another related question is whether a <I>template-id</I> is a
name or not and thus would trigger an argument-dependent lookup.
Personally, I have always viewed a <I>template-id</I> as a name,
just like <TT>operator+</TT>.</P>

<P><B>Proposed Resolution (November, 2006):</B></P>

<OL><LI><P>Change clause 3 [basic] paragraphs 3-8 as
follows:</P>

<BLOCKQUOTE>

<OL>
<LI value="3"><P>An <I>entity</I> is a value, object, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">subobject,
base class subobject, array element,</SPAN> variable, <SPAN style="font-weight:bold;background-color:#A0FFA0">reference,</SPAN>
function, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">instance of a function,</SPAN> enumerator, type, class
member, template, <SPAN style="font-weight:bold;background-color:#A0FFA0">template specialization,</SPAN> namespace, or
parameter pack.</P></LI>

<LI value="4"><P>A <I>name</I> is a use of
an <SPAN style="text-decoration:line-through;background-color:#FFA0A0">identifier</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>identifier</I></SPAN> (2.11 [lex.name])<SPAN style="font-weight:bold;background-color:#A0FFA0">, <I>operator-function-id</I> (13.5 [over.oper]), <I>conversion-function-id</I> (12.3.2 [class.conv.fct]), or <I>template-id</I> (14.2 [temp.names])</SPAN>
that denotes an entity or <I>label</I> (6.6.4 [stmt.goto],
6.1 [stmt.label]). <SPAN style="text-decoration:line-through;background-color:#FFA0A0">A <I>variable</I> is introduced by the
declaration of an object. The variable's name denotes the object.</SPAN></P></LI>

<LI value="5"><P>Every name that denotes an entity is introduced by a
<I>declaration</I>. Every name that denotes a label is introduced
either by a <TT>goto</TT> statement (6.6.4 [stmt.goto]) or
a <I>labeled-statement</I> (6.1 [stmt.label]).</P></LI>

<LI type="a" value="1"><P><SPAN style="font-weight:bold;background-color:#A0FFA0">A <I>variable</I> is introduced by the
declaration of an object.  The variable's name denotes the
object.</SPAN></P></LI>

<LI type="1" value="6"><P>Some names denote types<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, classes,
enumerations,</SPAN> or templates. In general, it is necessary to
determine whether or not a name denotes one of these entities before
parsing the program that contains it. The process that determines this
is called <I>name lookup</I> (3.4 [basic.lookup]).</P></LI>

<LI value="7"><P>Two names are <I>the same</I> if</P>

<UL>

<LI><P>they are <SPAN style="text-decoration:line-through;background-color:#FFA0A0">identifiers</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>identifier</I>s</SPAN> composed
of the same character sequence; or</P></LI>

<LI><P>they are <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the names of overloaded operator functions</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>operator-function-id</I>s</SPAN> formed with the same operator;
or</P></LI>

<LI><P>they are <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the names of user-defined conversion functions</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>conversion-function-id</I>s</SPAN> formed with the same
type<SPAN style="text-decoration:line-through;background-color:#FFA0A0">.</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">, or</SPAN></P></LI>

<SPAN style="font-weight:bold;background-color:#A0FFA0"><LI><P>they are <I>template-id</I>s that refer to the same class
or function (14.4 [temp.type]).</P></LI></SPAN>
</UL></LI>

<LI value="8"><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">An identifier</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">A name</SPAN> used in more than one
translation unit can potentially refer to the same entity in these
translation units depending on the linkage (3.5 [basic.link])
of the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">identifier</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">name</SPAN> specified in each translation
unit.</P></LI>
</OL>
</BLOCKQUOTE>
</LI>

<LI><P>Change 3.3.7 [basic.scope.class] paragraph 1 item 5 as follows:</P>

<BLOCKQUOTE>

The potential scope of a declaration that extends to or past the end
of a class definition also extends to the regions defined by its
member definitions, even if the members are defined lexically outside
the class (this includes static data member definitions, nested class
definitions, member function definitions (including the member
function body and any portion of the declarator part of such
definitions which follows
the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">identifier</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>declarator-id</I></SPAN>, including a
<I>parameter-declaration-clause</I> and any default arguments
(8.3.6 [dcl.fct.default]).

</BLOCKQUOTE>

<P><I>[Drafting note: This last change is not really mandated by the
issue, but it's another case of &#8220;identifier&#8221; confusion.]</I></P>
</LI>
</OL>

<P>(This proposed resolution also resolves <A HREF="
     cwg_defects.html#309">issue 309</A>.)</P>

<BR><BR><HR><A NAME="261"></A><H4>261.
  
When is a deallocation function "used?"
</H4><B>Section: </B>3.2&#160; [basic.def.odr]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>7 Nov 2000<BR>


<P>[Moved to DR at October 2002 meeting.]</P>



<P>3.2 [basic.def.odr] paragraph 2 says that a deallocation
function is "used" by a <I>new-expression</I> or
<I>delete-expression</I> appearing in a potentially-evaluated
expression.  3.2 [basic.def.odr] paragraph 3 requires only that
"used" functions be defined.</P>

<P>This wording runs afoul of the typical implementation technique for
polymorphic <I>delete-expression</I>s in which the deallocation
function is invoked from the virtual destructor of the most-derived
class.  The problem is that the destructor must be defined, because
it's virtual, and if it contains an implicit reference to the
deallocation function, the deallocation function must also be defined,
even if there are no relevant <I>new-expression</I>s or
<I>delete-expression</I>s in the program.</P>

<P>For example:</P>

<PRE>
        struct B { virtual ~B() { } };

        struct D: B {
            void operator delete(void*);
            ~D() { }
        };
</PRE>

<P>Is it required that <TT>D::operator delete(void*)</TT> be defined,
even if no <TT>B</TT> or <TT>D</TT> objects are ever created or
deleted?</P>

<P><B>Suggested resolution:</B> Add the words "or if it is found by
the lookup at the point of definition of a virtual destructor
(12.4 [class.dtor])" to the specification in 3.2 [basic.def.odr] paragraph 2.</P>

<P><B>Notes from 04/01 meeting:</B></P>

<P>The consensus was in favor of requiring that any declared
non-placement <TT>operator delete</TT> member function be
defined if the destructor for the class is defined (whether
virtual or not), and similarly for a non-placement
<TT>operator new</TT> if a constructor is defined.</P>

<P><B>Proposed resolution (10/01):</B></P>

<P> In 3.2 [basic.def.odr] paragraph 2, add the indicated text:
<BLOCKQUOTE>
An allocation or deallocation function for a class is
used by a new expression appearing in a potentially-evaluated
expression as specified in 5.3.4 [expr.new]
and 12.5 [class.free].
A deallocation function for a class is used by a delete expression
appearing in a potentially-evaluated expression as specified in
5.3.5 [expr.delete] and 12.5 [class.free].
<SPAN style="font-weight:bold;background-color:#A0FFA0"> A non-placement allocation or deallocation function for a
class is used by the definition of a constructor of that class.  A
non-placement deallocation function for a class is used by the
definition of the destructor of that class, or by being selected by
the lookup at
the point of definition of a virtual destructor (12.4 [class.dtor]).
[Footnote: An implementation is not required to call
allocation and deallocation functions from constructors or
destructors; however, this is a permissible implementation
technique.]</SPAN>
</BLOCKQUOTE>
</P>

<BR><BR><HR><A NAME="289"></A><H4>289.
  
Incomplete list of contexts requiring a complete type
</H4><B>Section: </B>3.2&#160; [basic.def.odr]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>25 May 2001<BR>


<P>[Moved to DR at October 2002 meeting.]</P>

<P>3.2 [basic.def.odr] paragraph 4 has a note listing the contexts
that require a class type to be complete.  It does not list use as a
base class as being one of those contexts.</P>

<P><B>Proposed resolution (10/01):</B></P>

<P>In 3.2 [basic.def.odr] paragraph 4 add a new bullet at the
end of the note as the next-to-last bullet:
<UL>
<LI>
a class with a base class of type <TT>T</TT> is defined
(10 [class.derived]), or
</LI>
</UL>
</P>

<BR><BR><HR><A NAME="433"></A><H4>433.
  
Do elaborated type specifiers in templates inject into enclosing namespace scope?
</H4><B>Section: </B>3.3.2&#160; [basic.scope.pdecl]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>2 September 2003<BR>


<P>[Voted into WP at March 2004 meeting.]</P>



<P>Consider the following translation unit:</P>
<PRE>
  template&lt;class T&gt; struct S {
    void f(union U*);  // (1)
  };
  template&lt;class T&gt; void S&lt;T&gt;::f(union U*) {}  // (2)
  U *p;  // (3)
</PRE>
<P>Does (1) introduce U as a visible name in the surrounding
namespace scope?</P>

<P>If not, then (2) could presumably be an error since the
"union U" in that definition does not find the same type
as the declaration (1).</P>

<P>If yes, then (3) is OK too.  However, we have gone through
much trouble to allow template implementations that do not
pre-parse the template definitions, but requiring (1) to
be visible would change that.</P>

<P>A slightly different case is the following:</P>
<PRE>
  template&lt;typename&gt; void f() { union U *p; }
  U *q;  // Should this be valid?
</PRE>

<P><B>Notes from October 2003 meeting:</B></P>

<P>There was consensus that example 1 should be allowed.
(Compilers already parse declarations in templates; even MSVC++ 6.0
accepts this case.)  The vote was 7-2.</P>

<P>Example 2, on the other hand, is wrong; the union name goes
into a block scope anyway.</P>

<P><B>Proposed resolution:</B></P>

<P>
In 3.3.2 [basic.scope.pdecl]
change the second bullet of paragraph 5 as follows:</P>
<BLOCKQUOTE>
for an <I>elaborated-type-specifier</I> of the form
<PRE>
   class-key identifier
</PRE>
if the <I>elaborated-type-specifier</I> is used in the
<I>decl-specifier-seq</I> or <I>parameter-declaration-clause</I>
of a function defined in namespace scope, the identifier is declared
as a <I>class-name</I> in the namespace that contains the
declaration; otherwise, except as a friend declaration, the identifier
is declared in the smallest non-class, non-function-prototype scope
that contains the declaration. <SPAN style="font-weight:bold;background-color:#A0FFA0">[Note: These rules also apply within
templates.]</SPAN> [Note: ...]
</BLOCKQUOTE>

<BR><BR><HR><A NAME="432"></A><H4>432.
  
Is injected class name visible in base class specifier list?
</H4><B>Section: </B>3.3.7&#160; [basic.scope.class]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>29 August 2003<BR>


<P>[Voted into WP at March 2004 meeting.]</P>



<P>Consider the following example (inspired by a
question from comp.lang.c++.moderated):</P>
<PRE>
  template&lt;typename&gt; struct B {};
  template&lt;typename T&gt; struct D: B&lt;D&gt; {};
</PRE>
<P>Most (all?) compilers reject this code because
D is handled as a template name rather than as
the injected class name.</P>

<P>9 [class]/2 says that the injected class
name is "inserted into the scope of the class."</P>

<P>3.3.7 [basic.scope.class]/1 seems to be the text
intended to describe
what "scope of a class" means, but it assumes that
every name in that scope was introduced using a
"declarator".  For an implicit declaration such
as the injected-class name it is not clear what
that means.</P>

<P>So my questions:</P>
<OL>
<LI>
Should the injected class name be available
in the base class specifiers?
<BLOCKQUOTE>
<U>John Spicer:</U>
I do not believe the injected class name should be available in the base 
specifier.  I think the semantics of injected class names should be as 
if a magic declaration were inserted after the opening "{" of the class 
definition.  The injected class name is a member of the class and 
members don't exist at the point where the base specifiers are scanned.
</BLOCKQUOTE>
</LI>
<LI>
Do you agree the wording should be clarified
whatever the answer to the first question? 
<BLOCKQUOTE>
<U>John Spicer:</U>
I believe the 3.3.7 [basic.scope.class] wording should be
updated to reflect the fact that not all names come from declarators.
</BLOCKQUOTE>
</LI>
</OL>

<P><B>Notes from October 2003 meeting:</B></P>

<P>We agree with John Spicer's suggested answers above.</P>

<P><B>Proposed Resolution (October 2003):</B></P>

<P>
The answer to question 1 above is 
No and no change is required.</P>
<P>
For question 1, change 3.3.7 [basic.scope.class]
paragraph 1 rule 1 to:</P>
<BLOCKQUOTE>
1) The potential scope of a name declared in a class consists not only of the 
declarative region following the name's <SPAN style="font-weight:bold;background-color:#A0FFA0">point of declaration</SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">declarator</SPAN>,
but also of all function
bodies, default arguments, and constructor <I>ctor-initializers</I>
in that class (including such things in nested classes).
The point of declaration of an <I>injected-class-name</I>
(clause 9 [class]) is 
immediately following the opening brace of the class definition.
</BLOCKQUOTE>
<P>(Note that this change overlaps a change in
<A HREF="
     cwg_defects.html#417">issue 417</A>.)</P>
<P>
Also change 3.3.2 [basic.scope.pdecl]
by adding a new paragraph 8 for the <I>injected-class-name</I> case:</P>
<BLOCKQUOTE>
The point of declaration for an <I>injected-class-name</I>
(clause 9 [class]) is
immediately following the opening brace of the class definition.
</BLOCKQUOTE>
<P>Alternatively this paragraph could be added after paragraph 5 and before the
two note paragraphs (i.e. it would become paragraph 5a).</P>

<BR><BR><HR><A NAME="139"></A><H4>139.
  
Error in <TT>friend</TT> lookup example
</H4><B>Section: </B>3.4.1&#160; [basic.lookup.unqual]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>14 Jul 1999<BR>



<P>[Moved to DR at 10/01 meeting.]</P>

<P>The example in
3.4.1 [basic.lookup.unqual]
 paragraph 3 is
incorrect:</P>

<PRE>
    typedef int f;
    struct A {
        friend void f(A &amp;);
        operator int();
        void g(A a) {
            f(a);
        }
    };
</PRE>

Regardless of the resolution of other issues concerning the lookup
of names in <TT>friend</TT> declarations, this example is ill-formed
(the function and the typedef cannot exist in the same scope).

<P>One possible repair of the example would be to make <TT>f</TT>
a class with a constructor taking either <TT>A</TT> or <TT>int</TT>
as its parameter.</P>

<P>(See also issues
<A HREF="
     cwg_closed.html#95">95</A>,
<A HREF="
     cwg_defects.html#136">136</A>,
<A HREF="
     cwg_active.html#138">138</A>,
<A HREF="
     cwg_defects.html#143">143</A>,
<A HREF="
     cwg_closed.html#165">165</A>, and
<A HREF="
     cwg_defects.html#166">166</A>.)</P>

<P><B>Proposed resolution (04/01):</B></P>

<OL>

<LI><P>Change the example in 3.4.1 [basic.lookup.unqual]
paragraph 3 to read:</P>

<PRE>
    typedef int f;
    namespace N {
        struct A {
            friend int f(A &amp;);
            operator int();
            void g(A a) {
                int i = f(a);
                      // f is the typedef, not the friend function:
                      // equivalent to int(a)
            }
        };
    }
</PRE>
</LI>

<LI><P>Delete the sentence immediately following the example:</P>

<BLOCKQUOTE>

The expression <TT>f(a)</TT> is a <I>cast-expression</I>
equivalent to <TT>int(a)</TT>.

</BLOCKQUOTE>
</LI>

</OL>

<BR><BR><HR><A NAME="514"></A><H4>514.
  
Is the initializer for a namespace member in the scope of the namespace?
</H4><B>Section: </B>3.4.1&#160; [basic.lookup.unqual]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>24 Mar 2005<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>

<P>Is the following code well-formed?</P>

<PRE>
    namespace N {
      int i;
      extern int j;
    }
    int N::j = i;
</PRE>

<P>The question here is whether the lookup for <TT>i</TT> in the
initializer of <TT>N::j</TT> finds the declaration in namespace
<TT>N</TT> or not.  Implementations differ on this question.</P>

<P>If <TT>N::j</TT> were a static data member of a class, the
answer would be clear: both 3.4.1 [basic.lookup.unqual]
paragraph 12 and 8.5 [dcl.init] paragraph 11 say that
the initializer &#8220;is in the scope of the member's
class.&#8221;  There is no such provision for namespace
members defined outside the namespace, however.</P>

<P>The reasoning given in 3.4.1 [basic.lookup.unqual] may be
instructive:</P>

<BLOCKQUOTE>

A name used in the definition of a <TT>static</TT> data member of
class <TT>X</TT> (9.4.2 [class.static.data]) (after the
<I>qualified-id</I> of the static member) is looked up as if the name
was used in a member function of <TT>X</TT>.

</BLOCKQUOTE>

<P>It is certainly the case that a name used in a function that is
a member of a namespace is looked up in that namespace
(3.4.1 [basic.lookup.unqual] paragraph 6), regardless of whether
the definition is inside or outside that namespace.  Initializers
for namespace members should probably be looked up the same way.</P>

<P><B>Proposed resolution (April, 2006):</B></P>

<P>Add a new paragraph following 3.4.1 [basic.lookup.unqual]
paragraph 12:</P>

<BLOCKQUOTE>

<P>If a variable member of a namespace is defined outside of the scope
of its namespace then any name used in the definition of the variable
member (after the <I>declarator-id</I>) is looked up as if the
definition of the variable member occurred in its
namespace. [<I>Example:</I></P>

<PRE>
    namespace N {
      int i = 4;
      extern int j;
    }

    int i = 2;

    int N::j = i;	//<SPAN style="font-family:Times;font-style:italic"> </SPAN>N::j<SPAN style="font-family:Times;font-style:italic"> == 4</SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="143"></A><H4>143.
  
Friends and Koenig lookup
</H4><B>Section: </B>3.4.2&#160; [basic.lookup.argdep]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>21 Jul 1999<BR>



<P>[Moved to DR at 4/02 meeting.]</P>



<P>Paragraphs 1 and 2 of
3.4.2 [basic.lookup.argdep]
 say, in part,</P>

<BLOCKQUOTE>
When an unqualified name is used as the <I>postfix-expression</I>
in a function call
(5.2.2 [expr.call]
)... namespace-scope
friend function declarations
(11.3 [class.friend]
) not otherwise
visible may be found... the set of declarations found
by the lookup of the function name [includes] the set
of declarations found in the... classes associated with
the argument types.
</BLOCKQUOTE>

The most straightforward reading of this wording is that if a function of
namespace scope (as opposed to a class member function) is
declared as a friend in a class, and that class is an
associated class in a function call, the friend function will
be part of the overload set, even if it is not visible to
normal lookup.

<P>Consider the following example:</P>

<PRE>
    namespace A {
	class S;
    };
    namespace B {
	void f(A::S);
    };
    namespace A {
	class S {
	    int i;
	    friend void B::f(S);
	};
    }
    void g() {
	A::S s;
	f(s); // should find B::f(A::S)
    }
</PRE>

This example would seem to satisfy the criteria from
3.4.2 [basic.lookup.argdep]
:
<TT>A::S</TT> is an associated class of the argument, and
<TT>A::S</TT> has a
friend declaration of the namespace-scope function
<TT>B::f(A::S)</TT>,
so Koenig lookup should include <TT>B::f(A::S)</TT> as part of the
overload set in the call.

<P>Another interpretation is that, instead of finding the friend
declarations in associated classes, one only looks for namespace-scope
functions, visible or invisible, in the namespaces of which the the
associated classes are members; the only use of the friend
declarations in the associated classes is to validate whether an
invisible function declaration came from an associated class or not
and thus whether it should be included in the overload set or not.
By this interpretation, the call <TT>f(s)</TT> in the example will
fail, because <TT>B::f(A::S)</TT> is not a member of namespace
<TT>A</TT> and thus is not found by the lookup.</P>

<P><B> Notes from 10/99 meeting:</B> The second interpretation
is correct.  The wording should be revised to make clear that Koenig
lookup works by finding "invisible" declarations in namespace scope
and not by finding <TT>friend</TT> declarations in associated
classes.</P>

<P><B>Proposed resolution (04/01):</B> The "associated classes"
are handled adequately under this interpretation by
3.4.2 [basic.lookup.argdep] paragraph 3, which describes the
lookup in the associated namespaces as including the friend
declarations from the associated classes.  Other mentions of the
associated classes should be removed or qualified to avoid the
impression that there is a lookup in those classes:</P>

<OL>

<LI><P>In 3.4.2 [basic.lookup.argdep], change</P>

<BLOCKQUOTE>

When an unqualified name is used as the <I>postfix-expression</I>
in a function call (5.2.2 [expr.call]), other
namespaces not considered during the usual unqualified lookup
(3.4.1 [basic.lookup.unqual]) may be searched, and
namespace-scope friend function declarations
(11.3 [class.friend]) not otherwise visible may be found.

</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>

When an unqualified name is used as the <I>postfix-expression</I>
in a function call (5.2.2 [expr.call]), other
namespaces not considered during the usual unqualified lookup
(3.4.1 [basic.lookup.unqual]) may be searched, and
<SPAN style="font-weight:bold;background-color:#A0FFA0">in those namespaces,</SPAN>
namespace-scope friend function declarations
(11.3 [class.friend]) not otherwise visible may be found.

</BLOCKQUOTE>

</LI>

<LI><P>In 3.4.2 [basic.lookup.argdep] paragraph 2, delete
the words <B>and classes</B> in the following two sentences:</P>

<BLOCKQUOTE>

If the ordinary unqualified lookup of the name finds the
declaration of a class member function, the associated namespaces
<B><SPAN style="text-decoration:line-through;background-color:#FFA0A0">and classes</SPAN></B> are not considered.  Otherwise the
set of declarations found by the lookup of the function name is
the union of the set of declarations found using ordinary
unqualified lookup and the set of declarations found in the
namespaces <B><SPAN style="text-decoration:line-through;background-color:#FFA0A0">and classes</SPAN></B> associated with the
argument types.

</BLOCKQUOTE>

</LI>

</OL>

<P>(See also issues
<A HREF="
     cwg_closed.html#95">95</A>,
<A HREF="
     cwg_defects.html#136">136</A>,
<A HREF="
     cwg_active.html#138">138</A>,
<A HREF="
     cwg_defects.html#139">139</A>,
<A HREF="
     cwg_closed.html#165">165</A>,
<A HREF="
     cwg_defects.html#166">166</A>, and
<A HREF="
     cwg_defects.html#218">218</A>.)</P>
<BR><BR><HR><A NAME="218"></A><H4>218.
  
Specification of Koenig lookup
</H4><B>Section: </B>3.4.2&#160; [basic.lookup.argdep]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Hyman Rosen
 &#160;&#160;&#160;

 <B>Date: </B>28 Mar 2000<BR>


<P>[Voted into WP at April, 2007 meeting.]</P>



<P>The original intent of the Committee when Koenig lookup was added
to the language was apparently something like the following:</P>

<OL>
<LI>The name in the function call expression is looked up like any
other unqualified name.</LI>

<LI>If the ordinary unqualified lookup finds nothing or finds the
declaration of a (non-member) function, function template, or overload
set, argument-dependent lookup is done and any functions found in
associated namespaces are added to the result of the ordinary
lookup.</LI>
</OL>

<P>This approach is not reflected in the current wording of the
Standard.  Instead, the following appears to be the status quo:</P>

<OL>

<LI>Lookup of an unqualified name used as the
<I>postfix-expression</I> in the function call syntax always performs
Koenig lookup (3.4.1 [basic.lookup.unqual] paragraph 3).</LI>

<LI>Unless ordinary lookup finds a class member function, the result
of Koenig lookup always includes the declarations found in associated
namespaces (3.4.2 [basic.lookup.argdep] paragraph 2), regardless of
whether ordinary lookup finds a declaration and, if so, what kind of
entity is found.</LI>

<LI>The declarations from associated namespaces are not limited to
functions and template functions by anything in 3.4.2 [basic.lookup.argdep].  However, if Koenig lookup results in more than one
declaration and at least one of the declarations is a non-function,
the program is ill-formed (7.3.4 [namespace.udir], paragraph 4;
although this restriction is in the description of the
<I>using-directive</I>, the wording applies to any lookup that spans
namespaces).</LI>

</OL>

<P><U>John Spicer</U>: Argument-dependent lookup was created to solve
the problem of looking up function names within templates where you
don't know which namespace to use because it may depend on the
template argument types (and was then expanded to permit use in
nontemplates).  The original intent only concerned functions.  The
safest and simplest change is to simply clarify the existing wording
to that effect.</P>

<P><U>Bill Gibbons</U>: I see no reason why non-function declarations
should not be found.  It would take a special rule to exclude
"function objects", as well as pointers to functions, from
consideration.  There is no such rule in the standard and I see no
need for one.</P>

<P>There is also a problem with the wording in 3.4.2 [basic.lookup.argdep] paragraph 2:</P>

<BLOCKQUOTE>
If the ordinary unqualified lookup of the name finds the declaration
of a class member function, the associated namespaces and classes are
not considered.
</BLOCKQUOTE>

<P>This implies that if the ordinary lookup of the name finds the
declaration of a data member which is a pointer to function or
function object, argument-dependent lookup is still done.</P>

<P>My guess is that this is a mistake based on the incorrect
assumption that finding any member other than a member function would
be an error.  I would just change "class member function" to "class
member" in the quoted sentence.</P>

<P><U>Mike Miller</U>: In light of the issue of "short-circuiting"
Koenig lookup when normal lookup finds a non-function, perhaps it
should be written as "...finds the declaration of a class member, an
object, or a reference, the associated namespaces..."?</P>

<P><U>Andy Koenig</U>: I think I have to weigh in on the side of
extending argument-dependent lookup to include function objects and
pointers to functions.  I am particularly concerned about [function
objects], because I think that programmers should be able to replace
functions by function objects without changing the behavior of their
programs in fundamental ways.</P>

<P><U>Bjarne Stroustrup</U>: I don't think we could seriously argue
from first principles that [argument-dependent lookup should find only
function declarations].  In general, C++ name lookup is designed to be
independent of type: First we find the name(s), then, we consider
its(their) meaning.  3.4 [basic.lookup] states "The name
lookup rules apply uniformly to all names ..." That is an important
principle.</P>

<P>Thus, I consider text that speaks of "function call" instead of
plain "call" or "application of ()" in the context of koenig lookup an
accident of history. I find it hard to understand how 5.2.2 [expr.call] doesn't either disallow all occurrences of
<TT>x(y)</TT> where <TT>x</TT> is a class object (that's clearly not
intended) or requires koenig lookup for <TT>x</TT> independently of
its type (by reference from 3.4 [basic.lookup]).  I suspect
that a clarification of 5.2.2 [expr.call] to mention
function objects is in order. If the left-hand operand of () is a
name, it should be looked up using koenig lookup.</P>

<P><U>John Spicer</U>: This approach causes otherwise well-formed
programs to be ill-formed, and it does so by making names visible that
might be completely unknown to the author of the program.
Using-directives already do this, but argument-dependent lookup is
different.  You only get names from using-directives if you actually
<I>use</I> using-directives.  You get names from argument-dependent
lookup whether you want them or not.</P>

<P>This basically breaks an important reason for having namespaces.
You are not supposed to need any knowledge of the names used by a
namespace.</P>

<P>But this example breaks if argument-dependent lookup finds
non-functions and if the translation unit includes the &lt;list&gt;
header somewhere.</P>

<PRE>
    namespace my_ns {
        struct A {};
        void list(std::ostream&amp;, A&amp;);

        void f() {
            my_ns::A a;
            list(cout, a);
        }
    }
</PRE>

<P>This really makes namespaces of questionable value if you still
need to avoid using the same name as an entity in another namespace to
avoid problems like this.</P>

<P><U>Erwin Unruh</U>: Before we really decide on this topic, we should
have more analysis on the impact on programs. I would also like to see
a paper on the possibility to overload functions with function
surrogates (no, I won't write one).  Since such an extension is bound
to wait until the next official update, we should not preclude any
outcome of the discussion.</P>

<P>I would like to have a change right now, which leaves open several
outcomes later. I would like to say that:</P>

<BLOCKQUOTE>
Koenig lookup will find non-functions as well. If it finds a variable, the
program is ill-formed. 
If the primary lookup finds a variable, Koenig lookup is done. If the result
contains both functions and variables, the program is ill-formed.
[<I>Note:</I> A future standard will assign semantics to such a program.]
</BLOCKQUOTE>

<P>I myself are not comfortable with this as a long-time result, but it
prepares the ground for any of the following long term solutions:</P>

<UL>
<LI>Do overloading on mixed function/variable sets.</LI>
<LI>Ignore variables on Koenig lookup.</LI>
<LI>Don't do Koenig lookup if the primary lookup finds a variable.</LI>
<LI>Find variables on Koenig lookup and give an error if there is a
variable/function mix.</LI>
</UL>

<P>The note is there to prevent compiler vendors to put their own
extensions in here.</P>

<P>(See also issues <A HREF="
     cwg_defects.html#113">113</A> and
<A HREF="
     cwg_defects.html#143">143</A>.)</P>

<P><B>Notes from 04/00 meeting:</B></P>

<P>Although many agreed that there were valid concerns motivating a
desire for Koenig lookup to find non-function declarations, there was
also concern that supporting this capability would be more dangerous
than helpful in the absence of overload resolution for mixed function
and non-function declarations.</P>

<P>A straw poll of the group revealed 8 in favor of Koenig lookup
finding functions and function templates only, while 3 supported the
broader result.   </P>

<P><B>Notes from the 10/01 meeting:</B></P>

<P>There was unanimous agreement on one less controversial point:
if the normal lookup of the identifier finds a non-function, argument-dependent
lookup should not be done.</P>

<P>On the larger issue, the primary point of consensus is that making
this change is
an extension, and therefore it should wait until the point at
which we are considering extensions (which could be very soon).
There was also consensus on the fact that the standard as it
stands is not clear: some introductory text suggests that
argument-dependent lookup finds only functions, but the more
detailed text that describes the lookup does not have any
such restriction.</P>

<P>It was also noted that some existing implementations (e.g., g++) do
find some non-functions in some cases.</P>

<P>The issue at this point is whether we should (1) make a small change
to make the standard clear (presumably in the direction of not
finding the non-functions in the lookup), and revisit the issue
later as an extension, or (2) leave the standard alone for now and
make any changes only as part of considering the extension.
A straw vote favored option (1) by a strong majority.</P>



<P><B>Additional Notes (September, 2006):</B></P>

<P>Recent discussion of this issue

has emphasized the following points:</P>

<OL><LI><P>The concept of finding function pointers and function objects
as part of argument-dependent lookup is not currently under active
discussion in the Evolution Working Group.
</P></LI>

<LI><P>The major area of concern with argument-dependent lookup is
finding functions in unintended namespaces.  There are current
proposals to deal with this concern either by changing the
definition of &#8220;associated namespace&#8221; so that fewer
namespaces are considered or to provide a mechanism for enabling
or disabling ADL altogether.  Although this concern is conceptually
distinct from the question of whether ADL finds function pointers
and function objects, it is related in the sense that the current
rules are perceived as finding too many functions (because of
searching too many namespaces), and allowing function pointers
and function objects would also increase the number of entities
found by ADL.
</P></LI>

<LI><P>Any expansion of ADL to include function pointers and
function objects must necessarily update the overloading rules
to specify how they interact with functions and function
templates in the overload set.  Current implementation experience
(g++) is not helpful in making this decision because, although
it performs a uniform lookup and finds non-function entities, it
diagnoses an error in overload resolution if non-function entities
are in the overload set.
</P></LI>

<LI><P>There is a possible problem if types are found by ADL: it
is not clear that overloading between callable entities
(functions, function templates, function pointers, and function
objects) and types (where the postfix syntax means a cast or
construction of a temporary) is reasonable or useful.
</P></LI>

</OL>

<P><U>James Widman</U>:</P>

<P>There is a larger debate here about whether ADL should find object
names; the proposed wording below is only intended to answer the
request for wording to clarify the status quo (option 1 above) and
not to suggest the outcome of the larger debate.</P>

<P><B>Proposed Resolution (October, 2006):</B></P>

<OL>

<LI><P>Replace the normative text in 3.4.2 [basic.lookup.argdep]
paragraph 3 with the following (leaving the text
of the note and example unchanged):</P>

<BLOCKQUOTE>

<P>Let X be the lookup set produced by unqualified lookup
(3.4.1 [basic.lookup.unqual]) and let Y be the lookup set
produced by argument dependent lookup (defined as follows).  If X
contains</P>

<P><UL>

<LI>a declaration of a class member, or</LI>

<LI>a block-scope function declaration that is not
a <I>using-declaration</I>, or</LI>

<LI>a declaration that is neither a function nor a function template</LI>

</UL></P>

<P>then Y is empty.  Otherwise Y is the set of declarations
found in the namespaces associated with the argument types as
described below.  The set of declarations found by the lookup of
the name is the union of X and Y.</P>

</BLOCKQUOTE>
</LI>

<LI><P>Change 3.4.1 [basic.lookup.unqual] paragraph 4 as
indicated:</P>

<BLOCKQUOTE>

<P>When considering an associated namespace, the lookup is the same
as the lookup performed when the associated namespace is used as
a qualifier (3.4.3.2 [namespace.qual]) except that:</P>

<P><UL>

<LI>Any <I>using-directive</I>s in the associated namespace are
ignored.</LI>

<LI>Any namespace-scope friend functions <SPAN style="font-weight:bold;background-color:#A0FFA0">or friend function
templates</SPAN> declared in associated classes are visible within their
respective namespaces even if they are not visible during an
ordinary lookup (11.3 [class.friend]).</LI>

<SPAN style="font-weight:bold;background-color:#A0FFA0"><LI>All names except those of (possibly overloaded) functions
and function templates are ignored.</LI></SPAN>

</UL></P>

</BLOCKQUOTE>

</LI>

</OL>

<BR><BR><HR><A NAME="403"></A><H4>403.
  
Reference to a type as a <I>template-id</I>
</H4><B>Section: </B>3.4.2&#160; [basic.lookup.argdep]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>18 Sep 2003<BR>


<P>[Voted into WP at March 2004 meeting.]</P>



<P>Spun off from <A HREF="
     cwg_closed.html#384">issue 384</A>.</P>

<P>3.4.2 [basic.lookup.argdep] says:
<BLOCKQUOTE>
If T is a template-id, its associated namespaces and classes are the
    namespace  in  which  the template is defined; for member templates,
    the member template's class; the namespaces and  classes  associated
    with  the types of the template arguments provided for template type
    parameters (excluding template template parameters); the  namespaces
    in  which  any  template  template  arguments  are  defined; and the
    classes in which any member  templates  used  as  template  template
    arguments  are  defined.   [Note: non-type template arguments do not
    contribute to the set of associated namespaces.  ]
</BLOCKQUOTE>
There is a problem with the term "is a template-id".  template-id
is a syntactic construct and you can't really talk about a type being a
template-id.  Presumably, this is intended to mean "If T is the type of a
class template specialization ...".</P>

<P><B>Proposed Resolution (October 2003):</B></P>

<P>
In 3.4.2 [basic.lookup.argdep], paragraph 2, bullet 8, replace
<BLOCKQUOTE>
If T is a <I>template-id</I> ...
</BLOCKQUOTE>

with

<BLOCKQUOTE>
If T is a class template specialization ...
</BLOCKQUOTE>
</P>

<BR><BR><HR><A NAME="557"></A><H4>557.
  
Does argument-dependent lookup cause template instantiation?
</H4><B>Section: </B>3.4.2&#160; [basic.lookup.argdep]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>8 February 2006<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>

<P>One might assume from 14.7.1 [temp.inst] paragraph 1
that argument-dependent lookup would require instantiation of any
class template specializations used in argument types:</P>

<BLOCKQUOTE>

Unless a class template specialization has been explicitly
instantiated (14.7.2 [temp.explicit]) or explicitly specialized
(14.7.3 [temp.expl.spec]), the class template specialization is
implicitly instantiated when the specialization is referenced in a
context that requires a completely-defined object type or when the
completeness of the class type affects the semantics of the program.

</BLOCKQUOTE>

<P>A complete class type is required to determine the associated
classes and namespaces for the argument type (to determine the class's
bases) and to determine the friend functions declared by the class, so
the completeness of the class type certainly &#8220;affects the
semantics of the program.&#8221;</P>

<P>This conclusion is reinforced by the second bullet of
3.4.2 [basic.lookup.argdep] paragraph 2:</P>

<UL><LI><P>If <TT>T</TT> is a class type (including unions), its associated
classes are: the class itself; the class of which it is a member, if
any; and its direct and indirect base classes. Its associated
namespaces are the namespaces in which its associated classes are
defined.</P></LI></UL>

<P>A class template specialization is a class type, so the second
bullet would appear to apply, requiring the specialization to be
instantiated in order to determine its base classes.</P>

<P>However, bullet 8 of that paragraph deals explicitly with class
template specializations:</P>

<UL><LI><P>If <TT>T</TT> is a class template specialization its
associated namespaces and classes are the namespace in which the
template is defined; for member templates, the member template's
class; the namespaces and classes associated with the types of the
template arguments provided for template type parameters (excluding
template template parameters); the namespaces in which any template
template arguments are defined; and the classes in which any member
templates used as template template arguments are
defined.</P></LI></UL>

<P>Note that the class template specialization itself is <I>not</I>
listed as an associated class, unlike other class types, and there is
no mention of base classes.  If bullet 8 were intended as a supplement
to the treatment of class types in bullet 2, one would expect phrasing
along the lines of, &#8220;In addition to the associated namespaces
and classes for all class types...&#8221; or some such; instead,
bullet 8 reads like a self-contained and complete specification.</P>

<P>If argument-dependent lookup does not cause implicit
instantiation, however, examples like the following fail:</P>

<PRE>
    template &lt;typename T&gt; class C {
        friend void f(C&lt;T&gt;*) { }
    };
    void g(C&lt;int&gt;* p) {
        f(p);    // found by ADL??
    }
</PRE>

<P>Implementations differ in whether this example works or not.</P>

<P><B>Proposed resolution (April, 2006):</B></P>

<OL>

<LI><P>Change bullet 2 of 3.4.2 [basic.lookup.argdep] paragraph 2
as indicated:</P>

<UL><LI><P>

If <TT>T</TT> is a class type (including unions), its associated
classes are: the class itself; the class of which it is a member, if
any; and its direct and indirect base classes. Its associated
namespaces are the namespaces <SPAN style="text-decoration:line-through;background-color:#FFA0A0">in</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">of</SPAN> which its associated
classes are <SPAN style="text-decoration:line-through;background-color:#FFA0A0">defined</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">members</SPAN>.  <SPAN style="font-weight:bold;background-color:#A0FFA0">Furthermore,
if <TT>T</TT> is a class template specialization, its associated
namespaces and classes also include: the namespaces and classes
associated with the types of the template arguments provided for
template type parameters (excluding template template parameters); the
namespaces of which any template template arguments are members; and
the classes of which any member templates used as template template
arguments are members. [<I>Note:</I> Non-type template arguments do not
contribute to the set of associated namespaces.  &#8212;<I>end
note</I>]</SPAN>

</P></LI></UL>

</LI>

<LI><P>Delete bullet 8 of 3.4.2 [basic.lookup.argdep] paragraph 2:</P>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">

If <TT>T</TT> is a class template specialization its associated
namespaces and classes are the namespace in which the template is
defined; for member templates, the member template's class; the
namespaces and classes associated with the types of the template
arguments provided for template type parameters (excluding template
template parameters); the namespaces in which any template template
arguments are defined; and the classes in which any member templates
used as template template arguments are defined. [<I>Note:</I> non-type
template arguments do not contribute to the set of associated
namespaces. &#8212;<I>end note</I>]

</SPAN></P></LI></UL>

</LI>

</OL>

<BR><BR><HR><A NAME="298"></A><H4>298.
  
<TT>T::x</TT> when <TT>T</TT> is cv-qualified
</H4><B>Section: </B>3.4.3.1&#160; [class.qual]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>7 Jul 2001<BR>


<P>[Voted into WP at April 2003 meeting.]</P>

<P>Can a typedef <TT>T</TT> to a cv-qualified class type be used
in a qualified name <TT>T::x</TT>?</P>

<PRE>
    struct A { static int i; };
    typedef const A CA;
    int main () {
      CA::i = 0;  // Okay?
    }
</PRE>

<P>Suggested answer: Yes.  All the compilers I tried accept the test case.</P>

<P><B>Proposed resolution (10/01):</B></P>

<P>In 3.4.3.1 [class.qual] paragraph 1 add the indicated text:
<BLOCKQUOTE>
If the <I>nested-name-specifier</I> of a <I>qualified-id</I> nominates
a class,  the
name  specified  after  the  <I>nested-name-specifier</I> is looked up in the
scope of the  class  (10.2 [class.member.lookup]),  except  for  the  cases
listed  below.   The  name shall represent one or more members of that
class or of one of its base classes (clause 10 [class.derived]). 
<SPAN style="font-weight:bold;background-color:#A0FFA0">If the <I>class-or-namespace-name</I> of the <I>nested-name-specifier</I>
names a cv-qualified class type, it nominates the underlying class
(the cv-qualifiers are ignored).</SPAN>
</BLOCKQUOTE>
</P>

<P><B>Notes from 4/02 meeting:</B></P>

<P>There is a problem in that <I>class-or-namespace-name</I> does not
include typedef names for cv-qualified class types.  See
7.1.3 [dcl.typedef] paragraph 4:</P>

<P><B>Argument and text removed from proposed resolution
(October 2002):</B></P>

<P><B>7.1.3 [dcl.typedef] paragraph 5:</B></P>
<P>
Here's a good question: in this example, should <TT>X</TT>
be used as a name-for-linkage-purposes (FLP name)?
</P>
<PRE>
  typedef class { } const X;
</PRE>
<P>
Because a <I>type-qualifier</I> is parsed as a
<I>decl-specifier</I>, it isn't possible to declare cv-qualified
and cv-unqualified typedefs for a type in a single declaration.
Also, of course, there's no way to declare a typedef for the
cv-unqualified version of a type for which only a cv-qualified version
has a name.
So, in the above example, if <TT>X</TT> isn't used as the FLP name,
then there can be no FLP name.
Also note that a FLP name usually represents a parameter type, where
top-level cv-qualifiers are usually irrelevant anyway.
</P>
<P>
Data points: for the above example, Microsoft uses <TT>X</TT> as the
FLP name; GNU and EDG do not.
</P>
<P>
My recommendation: for consistency with the direction we're going on
this issue, for simplicity of description (e.g., "the first
<I>class-name</I> declared by the declaration"), and for (very
slightly) increased utility, I think Microsoft has this right.
</P>
<BLOCKQUOTE>
If the typedef declaration defines an unnamed class <SPAN style="font-weight:bold;background-color:#A0FFA0">type</SPAN> (or
enum <SPAN style="font-weight:bold;background-color:#A0FFA0">type</SPAN>), the first <I>typedef-name</I> declared by the
declaration to <SPAN style="text-decoration:line-through;background-color:#FFA0A0">be</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">have</SPAN> that <SPAN style="text-decoration:line-through;background-color:#FFA0A0">class</SPAN> type
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">(or enum type)</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">or a cv-qualified version thereof</SPAN>
is used to denote the class type (or enum type) for linkage purposes
only (3.5 [basic.link]).
[<I>Example:</I> ...
</BLOCKQUOTE>

<P><B>Proposed resolution (October 2002):</B></P>

<P><B>3.4.4 [basic.lookup.elab] paragraphs 2 and 3:</B></P>
<P>
This sentence is deleted twice:
</P>
<BLOCKQUOTE>
...
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">If this name lookup finds a <I>typedef-name</I>, the
<I>elaborated-type-specifier</I> is ill-formed.</SPAN>
...
</BLOCKQUOTE>
<P>Note that the above changes are included in
N1376 as part of the resolution of <A HREF="
     cwg_defects.html#245">issue 245</A>.</P>

<P><B>5.1.1 [expr.prim.general] paragraph 7:</B></P>
<P>
This is only a note, and it is at least incomplete (and quite possibly
inaccurate), despite (or because of) its complexity.
I propose to delete it.
</P>
<BLOCKQUOTE>
...
[<I>Note:</I> a <I>typedef-name</I> that names a class is a
<I>class-name</I> (9.1 [class.name]).
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Except as the <I>identifier</I> in the declarator for a constructor
or destructor definition outside of a class
<I>member-specification</I> (12.1 [class.ctor],
12.4 [class.dtor]), a <I>typedef-name</I>
that names a class may be used in a <I>qualified-id</I> to refer to
a constructor or destructor.</SPAN> ]
</BLOCKQUOTE>

<P><B>7.1.3 [dcl.typedef] paragraph 4:</B></P>
<P>
My first choice would have been to make this the primary statement about
the equivalence of <I>typedef-name</I> and <I>class-name</I>,
since the equivalence comes about as a result of a typedef declaration.
Unfortunately, references to <I>class-name</I> point to
9.1 [class.name], so it
would seem that the primary statement should be there instead.
To avoid the possiblity of conflicts in the future, I propose to make
this a note.
</P>
<BLOCKQUOTE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I></SPAN>
A <I>typedef-name</I> that names a class <SPAN style="font-weight:bold;background-color:#A0FFA0">type, or a cv-qualified
version thereof,</SPAN> is <SPAN style="font-weight:bold;background-color:#A0FFA0">also</SPAN> a <I>class-name</I>
(9.1 [class.name]).
If a <I>typedef-name</I> is used <SPAN style="text-decoration:line-through;background-color:#FFA0A0">following the
<I>class-key</I> in an <I>elaborated-type-specifier</I>
(7.1.6.3 [dcl.type.elab]),
or in the <I>class-head</I> of a class declaration (9 [class]),
or is used as the <I>identifier</I> in the declarator for a
constructor or destructor declaration (12.1 [class.ctor],
12.4 [class.dtor]),</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">to identify the subject of an <I>elaborated-type-specifier</I>
(7.1.6.3 [dcl.type.elab]),
class declaration (clause 9 [class]),
constructor declaration (12.1 [class.ctor]),
or destructor declaration (12.4 [class.dtor]),</SPAN>
the program is ill-formed.
<SPAN style="font-weight:bold;background-color:#A0FFA0">]</SPAN>
[<I>Example:</I> ...
</BLOCKQUOTE>

<P><B>7.1.6.3 [dcl.type.elab] paragraph 2:</B></P>
<P>
This is the only remaining (normative) statement that a
<I>typedef-name</I> can't be used in an
<I>elaborated-type-specifier</I>.
The reference to template <I>type-parameter</I> is deleted by the
resolution of <A HREF="
     cwg_defects.html#283">issue 283</A>.
</P>
<BLOCKQUOTE>
...
If the <I>identifier</I> resolves to a <I>typedef-name</I>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">or a template <I>type-parameter</I></SPAN>, the
<I>elaborated-type-specifier</I> is ill-formed.
[<I>Note:</I> ...
</BLOCKQUOTE>

<P><B>8 [dcl.decl] grammar rule <I>declarator-id</I>:</B></P>
<P>
When I looked carefully into the statement of the rule prohibiting a
<I>typedef-name</I> in a constructor declaration, it appeared to me
that this grammar rule (inadvertently?) allows something that's always
forbidden semantically.
</P>
<BLOCKQUOTE>
<UL><I>declarator-id</I>:
<UL><I>id-expression</I>
<BR><TT>::</TT><I><SUB>opt</SUB> nested-name-specifier<SUB>opt</SUB>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">type-name</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">class-name</SPAN></I>
</UL>
</UL>
</BLOCKQUOTE>

<P><B>9.1 [class.name] paragraph 5:</B></P>
<P>
Unlike the prohibitions against appearing in an
<I>elaborated-type-specifier</I> or constructor or destructor
declarator, each of which was expressed more than once, the prohibition
against a <I>typedef-name</I> appearing in a <I>class-head</I>
was previously stated only in 7.1.3 [dcl.typedef].
It seems to me that that prohibition belongs here instead.
Also, it seems to me important to clarify that a <I>typedef-name</I>
that is a <I>class-name</I> is still a <I>typedef-name</I>. 
Otherwise, the various prohibitions can be argued around easily, if
perversely ("But that
isn't a <I>typedef-name</I>, it's a <I>class-name</I>; it says
so right there in 9.1 [class.name].")
</P>
<BLOCKQUOTE>
A <I>typedef-name</I> (7.1.3 [dcl.typedef])
that names a class <SPAN style="font-weight:bold;background-color:#A0FFA0">type or a
cv-qualified version thereof</SPAN> is
<SPAN style="font-weight:bold;background-color:#A0FFA0">also</SPAN> a <I>class-name</I>, but shall not be used
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">in an <I>elaborated-type-specifier</I>; see also
7.1.3 [dcl.typedef].</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">as the <I>identifier</I> in a <I>class-head</I>.</SPAN>
</BLOCKQUOTE>

<P><B>12.1 [class.ctor] paragraph 3:</B></P>
<P>
The new nonterminal references are needed to really nail down what we're
talking about here.
Otherwise, I'm just eliminating redundancy.
(A <I>typedef-name</I> that doesn't name a class type is no more
valid here than one that does.)
</P>
<BLOCKQUOTE>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A <I>typedef-name</I> that names a class is a
<I>class-name</I> (7.1.3 [dcl.typedef]); however, a</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">A</SPAN>
<I>typedef-name</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">that names a class</SPAN> shall not be
used as the <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>identifier</I></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>class-name</I></SPAN> in the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">declarator</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>declarator-id</I></SPAN> for a constructor declaration.
</BLOCKQUOTE>

<P><B>12.4 [class.dtor] paragraph 1:</B></P>
<P>
The same comments apply here as to 12.1 [class.ctor].
</P>
<BLOCKQUOTE>
...
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A <I>typedef-name</I> that names a class is a
<I>class-name</I> (7.1.3); however, a</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">A</SPAN>
<I>typedef-name</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">that names a class</SPAN> shall not be
used as the <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>identifier</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>class-name</I>
following the <TT>~</TT></SPAN> in the declarator for a destructor
declaration.
</BLOCKQUOTE>

<BR><BR><HR><A NAME="318"></A><H4>318.
  
<TT>struct A::A</TT> should not name the constructor of <TT>A</TT>
</H4><B>Section: </B>3.4.3.1&#160; [class.qual]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>18 Oct 2001<BR>


<P>[Voted into WP at April 2003 meeting.]</P>

<P>A use of an injected-class-name in an elaborated-type-specifier
should not name the constructor of the class, but rather the class itself,
because in that context we know that we're looking for a type.
See <A HREF="
     cwg_defects.html#147">issue 147</A>.</P>

<P><B>Proposed Resolution (revised October 2002):</B></P>

<P> This clarifies the changes made in the TC for issue 147.</P>

<P>In 3.4.3.1 [class.qual] paragraph 1a replace:</P>
<BLOCKQUOTE>
If the <I>nested-name-specifier</I> nominates a class C, and the name
specified after the <I>nested-name-specifier</I>, when looked up in C, is the
injected class name of C (clause 9 [class]), the name is instead
considered to name the constructor of class C.
</BLOCKQUOTE>
<P> with </P>
<BLOCKQUOTE>
In a lookup in which the constructor is an acceptable lookup result,
if the <I>nested-name-specifier</I> nominates a class C and the name
specified after the <I>nested-name-specifier</I>, when looked up in C, is the
injected class name of C (clause 9 [class]), the name is
instead considered to name the constructor of class C.
[Note: For example, the constructor is not an acceptable lookup result in an
elaborated type specifier so the constructor would not be used in place
of the injected class name.]
</BLOCKQUOTE>

<P>Note that <A HREF="
     cwg_defects.html#263">issue 263</A> updates a part of the
same paragraph.</P>

<P>Append to the example:</P>
<PRE>
  struct A::A a2;  // object of type A
</PRE>

<BR><BR><HR><A NAME="400"></A><H4>400.
  
Using-declarations and the "struct hack"
</H4><B>Section: </B>3.4.3.2&#160; [namespace.qual]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mark Mitchell
 &#160;&#160;&#160;

 <B>Date: </B>22 Jan 2003<BR>


<P>[Voted into WP at March 2004 meeting.]</P>

<P>Consider this code:</P>
<PRE>
  struct A { int i; struct i {}; };
  struct B { int i; struct i {}; };
  struct D : public A, public B { using A::i; void f (); };
  void D::f () { struct i x; }
</PRE>
<P>I can't find anything in the standard that says definitively what this 
means.  7.3.3 [namespace.udecl] says that a using-declaration shall
name "a member of a base class" -- but here we have two members, the
data member A::i and the class A::i.</P>

<P>Personally, I'd find it more attractive if this code did not work.  I'd 
like "using A::i" to mean "lookup A::i in the usual way and bind B::i to
that", which would mean that while "i = 3" would be valid in D::f,
"struct i x" would not be.  However, if there were no A::i data member,
then "A::i" would find the struct and the code in D::f would be valid.</P>

<P><U>John Spicer</U>:
I agree with you, but unfortunately the standard committee did not.</P>

<P>I remembered that this was discussed by the committee and that a
resolution was adopted that was different than what I hoped for, but I
had a hard time finding definitive wording in the standard.</P>

<P>I went back though my records and found the paper that proposed a
resolution and the associated committee motion that adopted the
proposed resolution The paper is N0905, and "option 1" from that paper
was adopted at the Stockholm meeting in July of 1996.  The resolution
is that "using A::i" brings in everything named i from A.</P>

<P>3.4.3.2 [namespace.qual] paragraph 2 was modified to
implement this resolution, but interestingly
that only covers the namespace case and not the class case.  I think
the class case was overlooked when the wording was drafted.  A core
issue should be opened to make sure the class case is handled
properly.</P>

<P><B>Notes from April 2003 meeting:</B></P>

<P>This is related to <A HREF="
     cwg_defects.html#11">issue 11</A>.
7.3.3 [namespace.udecl] paragraph 10 has an example
for namespaces.</P>

<P><B>Proposed resolution (October 2003):</B></P>

<P>Add a bullet to the end of 3.4.3.1 [class.qual]
paragraph 1:</P>
<UL>
<LI>the lookup for a name specified in a <I>using-declaration</I>
(7.3.3 [namespace.udecl])
also finds class or enumeration names hidden within the same scope
(3.3.10 [basic.scope.hiding]).
</LI>
</UL>
<P>Change the beginning of 7.3.3 [namespace.udecl] paragraph 4 from</P>
<BLOCKQUOTE>
A
<I>using-declaration</I>
used as a
<I>member-declaration</I>
shall refer to a member of a base class of the class being defined,
shall refer to a member of an anonymous union that is a member of a base class
of the class being defined, or
shall refer to an enumerator for an enumeration type that is a member of a base
class of the class being defined.
</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>
In a <I>using-declaration</I> used as a
<I>member-declaration</I>, the <I>nested-name-specifier</I>
shall name a base class of the class being defined.  Such a
<I>using-declaration</I> introduces the set of declarations found by member
name lookup (10.2 [class.member.lookup],
3.4.3.1 [class.qual]).
</BLOCKQUOTE>

<BR><BR><HR><A NAME="245"></A><H4>245.
  
Name lookup in <I>elaborated-type-specifier</I>s
</H4><B>Section: </B>3.4.4&#160; [basic.lookup.elab]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jack Rouse
 &#160;&#160;&#160;

 <B>Date: </B>14 Sep 2000<BR>


<P>[Voted into WP at April 2003 meeting.]</P>



<P>I have some concerns with the description of name lookup for
elaborated type specifiers in 3.4.4 [basic.lookup.elab]:</P>

<OL>

<LI>
<P>Paragraph 2 has some parodoxical statements concerning looking up
names that are simple identifers:</P>

<BLOCKQUOTE>
If the <I>elaborated-type-specifier</I> refers to an <I>enum-name</I>
and this lookup does not find a previously declared <I>enum-name</I>,
the <I>elaborated-type-specifier</I> is ill-formed. If the
<I>elaborated-type-specifier</I> refers to an <I>[sic]</I>
<I>class-name</I> and this lookup does not find a previously declared
<I>class-name</I>... the <I>elaborated-type-specifier</I> is a
declaration that introduces the <I>class-name</I> as described in
3.3.2 [basic.scope.pdecl]."
</BLOCKQUOTE>

<P>It is not clear how an <I>elaborated-type-specifier</I> can refer
to an <I>enum-name</I> or <I>class-name</I> given that the lookup does
not find such a name and that <I>class-name</I> and <I>enum-name</I>
are not part of the syntax of an <I>elaborated-type-specifier</I>.</P>
</LI>

<LI>
<P>The second sentence quoted above seems to suggest that the name found
will not be used if it is not a class name.  <I>typedef-name</I> names
are ill-formed due to the sentence preceding the quote.  If lookup
finds, for instance, an <I>enum-name</I> then a new declaration will
be created.  This differs from C, and from the enum case, and can have
surprising effects:</P>

<PRE>
    struct S {
       enum E {
           one = 1
       };
       class E* p;     // declares a global class E?
    };
</PRE>

<P>Was this really the intent?  If this is the case then some more
work is needed on 3.4.4 [basic.lookup.elab].  Note that the
section does not make finding a type template formal ill-formed, as is
done in 7.1.6.3 [dcl.type.elab].  I don't see anything that
makes a type template formal name a <I>class-name</I>.  So the example
in 7.1.6.3 [dcl.type.elab] of <TT>friend class T;</TT> where
<TT>T</TT> is a template type formal would no longer be ill-formed
with this interpretation because it would declare a new class
<TT>T</TT>.</P> </LI></OL>

<P>(See also <A HREF="
     cwg_defects.html#254">issue 254</A>.)</P>

<P><B>Notes from the 4/02 meeting:</B></P>

<P>This will be consolidated with the changes for
<A HREF="
     cwg_defects.html#254">issue 254</A>.
See also <A HREF="
     cwg_defects.html#298">issue 298</A>.</P>

<P><B>Proposed resolution (October 2002):</B></P>

<P>As given in N1376=02-0034.  Note that the inserts and strikeouts in
that document do not display
correctly in all browsers; &lt;del&gt; --&gt; &lt;strike&gt;
and &lt;ins&gt; --&gt; &lt;b&gt;, and the
similar changes for the closing delimiters,
seem to do the trick.</P>

<BR><BR><HR><A NAME="254"></A><H4>254.
  
Definitional problems with <I>elaborated-type-specifier</I>s
</H4><B>Section: </B>3.4.4&#160; [basic.lookup.elab]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Clark Nelson
 &#160;&#160;&#160;

 <B>Date: </B>26 Oct 2000<BR>


<P>[Voted into WP at April 2003 meeting.]</P>

<OL>

<LI><P>The text in 3.4.4 [basic.lookup.elab] paragraph 2 twice
refers to the possibility that an <I>elaborated-type-specifier</I>
might have the form</P>

<PRE>
        <I>class-key identifier</I> <TT>;</TT>
</PRE>

<P>However, the grammar for <I>elaborated-type-specifier</I> does
not include a semicolon.</P>
</LI>

<LI><P>In both 3.4.4 [basic.lookup.elab] and
7.1.6.3 [dcl.type.elab], the text asserts that an
<I>elaborated-type-specifier</I> that refers to a <I>typedef-name</I>
is ill-formed.  However, it is permissible for the form of
<I>elaborated-type-specifier</I> that begins with <TT>typename</TT>
to refer to a <I>typedef-name</I>.</P>

<P>This problem is the result of adding the <TT>typename</TT> form
to the <I>elaborated-type-name</I> grammar without changing the
verbiage correspondingly.  It could be fixed either by updating the
verbiage or by moving the <TT>typename</TT> syntax into its own
production and referring to both nonterminals when needed.</P>
</LI>

</OL>

<P>(See also <A HREF="
     cwg_defects.html#180">issue 180</A>.  If this
issue is resolved in favor of a separate nonterminal in the
grammar for the <TT>typename</TT> forms, the wording in that
issue's resolution must be changed accordingly.)</P>

<P><B>Notes from 04/01 meeting:</B></P>

<P>The consensus was in favor of moving the <TT>typename</TT>
forms out of the <I>elaborated-type-specifier</I> grammar.</P>

<P><B>Notes from the 4/02 meeting:</B></P>

<P>This will be consolidated with the changes for
<A HREF="
     cwg_defects.html#245">issue 245</A>.</P>

<P><B>Proposed resolution (October 2002):</B></P>

<P>As given in N1376=02-0034.</P>

<BR><BR><HR><A NAME="141"></A><H4>141.
  
Non-member function templates in member access expressions
</H4><B>Section: </B>3.4.5&#160; [basic.lookup.classref]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>fvali
 &#160;&#160;&#160;

 <B>Date: </B>31 July 1999<BR>



<P>[Voted into the WP at the June, 2008 meeting.]</P>

<P>3.4.5 [basic.lookup.classref]
 paragraph 1 says,</P>

<BLOCKQUOTE>
In a class member access expression
(5.2.5 [expr.ref]
), if the <TT>.</TT> or
<TT>-&gt;</TT> token is immediately followed by an <I>identifier</I>
followed by a <TT>&lt;</TT>, the identifier must be looked up to
determine whether the <TT>&lt;</TT> is the beginning of a template
argument list
(14.2 [temp.names]
) or a less-than
operator.  The identifier is first looked up in the class of the
object expression.  If the identifier is not found, it is then looked
up in the context of the entire <I>postfix-expression</I> and shall
name a class or function template.
</BLOCKQUOTE>

<P>There do not seem to be any circumstances in which use of a
non-member template function would be well-formed as the
<I>id-expression</I> of a class member access expression.</P>

<P><B>Proposed Resolution (November, 2006):</B></P>

<P>Change 3.4.5 [basic.lookup.classref] paragraph 1 as follows:</P>

<BLOCKQUOTE>

In a class member access expression (5.2.5 [expr.ref]), if
the <TT>.</TT> or <TT>-&gt;</TT> token is immediately followed by an
identifier followed by a <TT>&lt;</TT>, the identifier must be looked
up to determine whether the <TT>&lt;</TT> is the beginning of a
template argument list (14.2 [temp.names]) or a less-than
operator. The identifier is first looked up in the class of the object
expression. If the identifier is not found, it is then looked up in
the context of the entire <I>postfix-expression</I> and shall name a
class <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or function</SPAN> template...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="305"></A><H4>305.
  
Name lookup in destructor call
</H4><B>Section: </B>3.4.5&#160; [basic.lookup.classref]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mark Mitchell
 &#160;&#160;&#160;

 <B>Date: </B>19 May 2001<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>

<P>I believe this program is invalid:
<PRE>
    struct A {
    };

    struct C {
      struct A {};
      void f ();
    };

    void C::f () {
      ::A *a;
      a-&gt;~A ();
    }
</PRE>
The problem is that 3.4.5 [basic.lookup.classref] says that you have to look
up <TT>A</TT> in both the context of the pointed-to-type (i.e.,
<TT>::A</TT>), and
in the context of the postfix-expression (i.e., the body of <TT>C::f</TT>), and
that if the name is found in both places it must name the same type in
both places.</P>

<P>The EDG front end does not issue an error about this program, though.</P>

<P>Am I reading the standardese incorrectly?</P>

<P><U>John Spicer</U>: I think you are reading it correctly.  I think
I've been hoping that this would
get changed.  Unlike other dual lookup contexts, this is one in which the
compiler already knows the right answer (the type must match that of the left
hand of the <TT>-&gt;</TT> operator).  So I think that if either of the types
found matches
the one required, it should be sufficient.  You can't say <TT>a-&gt;~::A()</TT>,
which
means you are forced to say <TT>a-&gt;::A::~A()</TT>, which disables the virtual
mechanism.  So you would have to do something like create a local typedef
for the desired type.</P>

<P>See also issues <A HREF="
     cwg_defects.html#244">244</A>,
<A HREF="
     cwg_active.html#399">399</A>, and
<A HREF="
     cwg_defects.html#466">466</A>.</P>

<P><B>Proposed resolution (April, 2006):</B></P>

<OL>

<LI><P>Remove the indicated text from 3.4.5 [basic.lookup.classref]
paragraph 2:</P>

<BLOCKQUOTE>

If the <I>id-expression</I> in a class member access (5.2.5 [expr.ref]) is an <I>unqualified-id</I>, and the type of the
object expression is of a class type <TT>C</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">(or of pointer to a
class type <TT>C</TT>)</SPAN>, the <I>unqualified-id</I> is looked up in
the scope of class <TT>C</TT>...

</BLOCKQUOTE>

</LI>

<LI><P>Change 3.4.5 [basic.lookup.classref] paragraph 3 as indicated:</P>

<BLOCKQUOTE>

If the <I>unqualified-id</I> is <TT>~</TT><I>type-name</I>,
<SPAN style="font-weight:bold;background-color:#A0FFA0">the <I>type-name</I> is looked up in the context of the entire
<I>postfix-expression</I>.</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">and</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">If</SPAN> the
type <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>T</TT></SPAN> of the object expression is of a class
type <TT>C</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">(or of pointer to a class type <TT>C</TT>)</SPAN>,
the <I>type-name</I> is <SPAN style="font-weight:bold;background-color:#A0FFA0">also</SPAN> looked up <SPAN style="text-decoration:line-through;background-color:#FFA0A0">in the context of the
entire <I>postfix-expression</I> and</SPAN> in the scope of
class <TT>C</TT>. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The <I>type-name</I> shall refer to
a <I>class-name</I>. If <I>type-name</I> is found in both contexts,
the name shall refer to the same class type. If the type of the object
expression is of scalar type, the <I>type-name</I> is looked up in the
scope of the complete <I>postfix-expression</I>.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">At least one
of the lookups shall find a name that refers to (possibly
cv-qualified)
<TT>T</TT>.  [<I>Example:</I>

<PRE><SPAN style="font-weight:bold;background-color:#A0FFA0">
    struct A { };

    struct B {
      struct A { };
      void f(::A* a);
    };

    void B::f(::A* a) {
      a-&gt;~A();  //<SPAN style="font-family:Times;font-style:italic"> OK, lookup in </SPAN>*a<SPAN style="font-family:Times;font-style:italic"> finds the injected-class-name</SPAN>
    }
</SPAN></PRE>

&#8212;<I>end example</I>]</SPAN>

</BLOCKQUOTE>

</LI>
</OL>

<P><I>[Note: this change also resolves <A HREF="
     cwg_defects.html#414">issue 414</A>.]</I></P>

<BR><BR><HR><A NAME="381"></A><H4>381.
  
Incorrect example of base class member lookup
</H4><B>Section: </B>3.4.5&#160; [basic.lookup.classref]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>8 Nov 2002<BR>


<P>[Voted into WP at October 2004 meeting.]</P>

<P>The example in 3.4.5 [basic.lookup.classref] paragraph 4
is wrong (see 11.2 [class.access.base] paragraph 5; the cast to the
naming class can't be done) and needs to be corrected.
This was noted when the final version of the algorithm for
<A HREF="
     cwg_defects.html#39">issue 39</A> was checked against it.</P>

<P><B>Proposed Resolution (October 2003):</B></P>

<P>Remove the entire note at the end of
3.4.5 [basic.lookup.classref] paragraph 4, including the
entire example.</P>

<BR><BR><HR><A NAME="414"></A><H4>414.
  
Multiple types found on destructor lookup
</H4><B>Section: </B>3.4.5&#160; [basic.lookup.classref]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>1 May 2003<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>

<P>By 3.4.5 [basic.lookup.classref] paragraph 3, the following is
ill-formed because the two lookups of the destructor name (in
the scope of the class of the object and in the surrounding
context) find different Xs:</P>
<PRE>
  struct X {};
  int main() {
    X x;
    struct X {};
    x.~X();  // Error?
  }
</PRE>
<P>This is silly, because the compiler knows what the type has
to be, and one of the things found matches that.  The lookup
should require only that one of the lookups finds the required
class type.</P>

<P><B>Proposed resolution (April, 2005):</B></P>

<P>This issue is resolved by the resolution of <A HREF="
     cwg_defects.html#305">issue 305</A>.</P>

<BR><BR><HR><A NAME="216"></A><H4>216.
  
Linkage of nameless class-scope enumeration types
</H4><B>Section: </B>3.5&#160; [basic.link]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>13 Mar 2000<BR>


<P>[Moved to DR at 10/01 meeting.]</P>



3.5 [basic.link] paragraph 4 says (among other things):

<BLOCKQUOTE>
A name having namespace scope has external linkage if it is the name of
<UL>
<LI>[...]</LI>

<LI>a named enumeration (7.2 [dcl.enum]), or an
unnamed enumeration defined
in a typedef declaration in which the enumeration has the typedef
name for linkage purposes (7.1.3 [dcl.typedef]) </LI>
</UL>
</BLOCKQUOTE>

That prohibits for example:

<PRE>
    typedef enum { e1 } *PE;
    void f(PE) {}  // Cannot declare a function (with linkage) using a 
		   // type with no linkage.
</PRE>

<P>However, the same prohibition was not made for class scope types.  Indeed,
3.5 [basic.link] paragraph 5 says:</P>

<BLOCKQUOTE>
In addition, a member function, static data member, class or 
enumeration of class scope has external linkage if the name of the
class has external linkage.
</BLOCKQUOTE>

<P>That allows for:</P>

<PRE>
    struct S {
       typedef enum { e1 } *MPE;
       void mf(MPE) {}
    };
</PRE>

<P>My guess is that this is an unintentional consequence of
3.5 [basic.link] paragraph 5, but I would like confirmation
on that.</P>

<P><B>Proposed resolution:</B></P>

<P>Change text in 3.5 [basic.link] paragraph 5 from:</P>

<BLOCKQUOTE>

In addition, a member function, static data member, class or
enumeration of class scope has external linkage if the name of the
class has external linkage.

</BLOCKQUOTE>

to: 

<BLOCKQUOTE>

In addition, a member function, a static data member, a named class or
enumeration of class scope, or an unnamed class or enumeration defined
in a class-scope typedef declaration such that the class or
enumeration has the typedef name for linkage purposes
(7.1.3 [dcl.typedef]),
has external linkage if the name of the class has external linkage.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="319"></A><H4>319.
  
Use of names without linkage in declaring entities with linkage
</H4><B>Section: </B>3.5&#160; [basic.link]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Clark Nelson
 &#160;&#160;&#160;

 <B>Date: </B>29 Oct 2001<BR>


<P>[Voted into WP at October 2004 meeting.]</P>



<P>According to 3.5 [basic.link] paragraph 8,
"A name with no linkage ... shall not 
be used to declare an entity with linkage." This would appear to rule
out code such as:
<PRE>
  typedef struct {
    int i;
  } *PT;
  extern "C" void f(PT);
</PRE>
[likewise]
<PRE>
  static enum { a } e;
</PRE>
which seems rather harmless to me.</P>

<P>See <A HREF="
     cwg_closed.html#132">issue 132</A>, which dealt with a closely
related issue.</P>

<P><U>Andrei Iltchenko</U> submitted the same issue via comp.std.c++ on
17 Dec 2001:</P>

<P>Paragraph 8 of Section 3.5 [basic.link] contains the following
sentences: "A name with no linkage shall not be used to declare an
entity with linkage. If a declaration uses a typedef name, it is the
linkage of the type name to which the typedef refers that is
considered."</P>

<P>The problem with this wording is that it doesn't cover cases where the
type to which a typedef-name refers has no name. As a result it's not
clear whether, for example, the following program is well-formed:</P>
<PRE>
#include &lt;vector&gt;

int  main()
{
   enum  {   sz = 6u   };
   typedef int  (* aptr_type)[sz];
   typedef struct  data  {
      int   i,  j;
   }  * elem_type;
   std::vector&lt;aptr_type&gt;   vec1;
   std::vector&lt;elem_type&gt;   vec2;
}
</PRE>

<P><B>Suggested resolution:</B></P>

<P>My feeling is that the rules for whether or not a typedef-name used in
a declaration shall be treated as having or not having linkage ought
to be modelled after those for dependent types, which are explained in
14.6.2.1 [temp.dep.type].</P>

<P>Add the following text at the end of Paragraph 8 of Section
3.5 [basic.link] and replace the following example:</P>
<BLOCKQUOTE>
In case of the type referred to by a typedef declaration not having a name,
the newly declared typedef-name has linkage if and only if its referred type
comprises no names of no linkage excluding local names that are eligible for
appearance in an integral constant-expression (5.19 [expr.const]).
[Note: if the referred
type contains a typedef-name that does not denote an unnamed class, the
linkage of that name is established by the recursive application of this
rule for the purposes of using typedef names in declarations.] [Example:
<PRE>
  void f()
  {
     struct A { int x; };        // no linkage
     extern A a;                 // ill-formed
     typedef A Bl
     extern B b;                 // ill-formed

     enum  {   sz = 6u   };
     typedef int  (* C)[sz];     // C has linkage because sz can
                                 // appear in a constant expression
  }
</PRE>
--end example.]
</BLOCKQUOTE>

<P><B>Additional issue (13 Jan 2002, from Andrei Iltchenko):</B></P>
<P>Paragraph 2 of Section 14.3.1 [temp.arg.type] is inaccurate and
unnecessarily prohibits a few important cases; it says "A local type, a type
with no linkage, an unnamed type or a type compounded from any of these
types shall not be used as a template-argument for a template-parameter."
The inaccuracy stems from the fact that it is not a type but its name that
can have a linkage.</P>

<P>For example based on the current wording of 14.3.1 [temp.arg.type],
the following example is ill-formed.</P>
<PRE>
  #include &lt;vector&gt;
  struct  data  {
    int   i,  j;
  };
  int  main()
  {
    enum  {   sz = 6u   };
    std::vector&lt;int(*)[sz]&gt;   vec1; // The types 'int(*)[sz]' and 'data*'
    std::vector&lt;data*&gt;        vec2; // have no names and are thus illegal
                                    // as template type arguments.
  }
</PRE>

<P><B>Suggested resolution:</B></P>
<P>Replace the whole second paragraph of Section 14.3.1 [temp.arg.type]
with the following wording:</P>
<BLOCKQUOTE>
A type whose name does not have a linkage or a type compounded from any such
type shall not be used as a template-argument for a template-parameter. In
case of a type <TT>T</TT> used as a template type argument not having a name,
<TT>T</TT>
constitutes a valid template type argument if and only if the name of an
invented typedef declaration referring to <TT>T</TT> would have linkage;
see 3.5.
[Example:
<PRE>
  template &lt;class T&gt; class X { /* ... */ };
  void f()
  {
    struct S { /* ... */ };
    enum  {   sz = 6u   };

    X&lt;S&gt; x3;                     // error: a type name with no linkage
                                 // used as template-argument
    X&lt;S*&gt; x4;                    // error: pointer to a type name with
                                 // no linkage used as template-argument
    X&lt;int(*)[sz]&gt; x5;            // OK: since the name of typedef int
                                 // (*pname)[sz] would have linkage
  }
</PRE>
--end example] [Note: a template type argument may be an incomplete type
(3.9 [basic.types]).]
</BLOCKQUOTE>

<P><B>Proposed resolution:</B></P>

<P>This is resolved by the changes for
<A HREF="
     cwg_defects.html#389">issue 389</A>.  The present issue was moved back to
Review status in February 2004 because 389 was moved back to Review.</P>

<BR><BR><HR><A NAME="389"></A><H4>389.
  
Unnamed types in entities with linkage
</H4><B>Section: </B>3.5&#160; [basic.link]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>31 Oct 2002<BR>


<P>[Voted into WP at October 2004 meeting.]</P>



<P>3.5 [basic.link] paragraph 8 says (among other things):</P>
<BLOCKQUOTE>
A name with no linkage (notably, the name of a class or enumeration 
declared in a local scope (3.3.3 [basic.scope.block])) shall not
be used to declare an entity with linkage.
If a declaration uses a typedef name, it is the linkage of the type 
name to which the typedef refers that is considered.
</BLOCKQUOTE>

<P>I would expect this to catch situations such as the following:</P>
<PRE>
  // File 1:
  typedef struct {} *UP;
  void f(UP) {}

  // File 2:
  typedef struct {} *UP; // Or: typedef struct {} U, *UP;
  void f(UP);
</PRE>
<P>The problem here is that most implementations must generate the same 
mangled name
for "f" in two translation units.  The quote from the standard above 
isn't quite
clear, unfortunately: There is no type name to which the typedef refers.</P>

<P>A related situation is the following:
<PRE>
  enum { no, yes } answer;
</PRE>
The variable "answer" is declared as having external linkage, but it is 
declared
with an unnamed type.  Section 3.5 [basic.link]
talks about the linkage of <I>names</I>, however,
and does therefore not prohibit this.  There is no implementation issue 
for most
compilers because they do not ordinarily mangle variable names, but I 
believe
the intent was to allow that implementation technique.</P>

<P>Finally, these problems are much less relevant when declaring names 
with internal
linkage.  For example, I would expect there to be few problems with:</P>
<PRE>
  typedef struct {} *UP;
  static void g(UP);
</PRE>
<P>I recently tried to interpret 3.5 [basic.link] paragraph 8
with the assumption that types with no names
have no linkage.  Surprisingly, this resulted in many diagnostics on 
variable declarations (mostly like "answer" above).</P>

<P>I'm pretty sure the standard needs clarifying words in this matter, but 
which way should it go?</P>

<P>See also <A HREF="
     cwg_defects.html#319">issue 319</A>.</P>

<P><B>Notes from April 2003 meeting:</B></P>

<P>There was agreement that this check is not needed for variables
and functions with extern "C" linkage, and a change there is
desirable to allow use of legacy C headers.  The check is also not needed for
entities with internal linkage, but there was no strong sentiment
for changing that case.</P>

<P>We also considered relaxing this requirement for extern "C++"
variables but decided that we did not want to change that case.</P>

<P>We noted that if extern "C" functions are allowed an additional
check is needed when such functions are used as arguments in calls
of function templates.  Deduction will put the type of the extern "C"
function into the type of the template instance, i.e., there would
be a need to mangle the name of an unnamed type.  To plug that hole
we need an additional requirement on the template created in
such a case.</P>

<P><B>Proposed resolution (April 2003, revised slightly October 2003
and March 2004):</B></P>

<P>In 3.5 [basic.link] paragraph 8, change</P>
<BLOCKQUOTE>
A name with no linkage (notably, the name of a class or enumeration
declared in a local scope (3.3.3 [basic.scope.block]))
shall not be used to declare an
entity with linkage.  If a declaration uses a typedef name, it is
the linkage of the type name to which the typedef refers that is
considered.
</BLOCKQUOTE>
<P>to</P>
<BLOCKQUOTE>
A type is said to have linkage if and only if
<UL>
<LI>
it is a class or enumeration type that is named (or has a name for
linkage purposes (7.1.3 [dcl.typedef]))
and the name has linkage; or
</LI>
<LI>
it is a specialization of a class template (14 [temp])
[Footnote: a class template always has external linkage, and
the requirements of 14.3.1 [temp.arg.type]
and 14.3.2 [temp.arg.nontype]
ensure that the template arguments will also have appropriate linkage]; or
</LI>
<LI>
it is a fundamental type (3.9.1 [basic.fundamental]); or
</LI>
<LI>
it is a compound type (3.9.2 [basic.compound])
other than a class or enumeration,
compounded exclusively from types that have linkage; or
</LI>
<LI>
it is a cv-qualified (3.9.3 [basic.type.qualifier])
version of a type that has linkage.
</LI>
</UL>
A type without linkage shall not be used as the type of a variable or
function with linkage, unless the variable or function has extern "C"
linkage (7.5 [dcl.link]).
[<I>Note:</I> in other words, a type without linkage contains
a class or enumeration that cannot be named outside
of its translation unit.  An entity with external linkage
declared using such a type could not correspond to any other entity
in another translation unit of the program and is thus not permitted.
Also note that classes with linkage may contain members whose types do
not have linkage, and that typedef names are ignored in the determination of
whether a type has linkage.]
</BLOCKQUOTE>
<P>Change 14.3.1 [temp.arg.type] paragraph 2 from (note:
this is the wording as updated by <A HREF="
     cwg_defects.html#62">issue 62</A>)</P>
<BLOCKQUOTE>
The following types shall not be used as a <I>template-argument</I>
for a template <I>type-parameter</I>:

<UL>

<LI>a type whose name has no linkage</LI>

<LI>an unnamed class or enumeration type that has no name for
linkage purposes (7.1.3 [dcl.typedef])</LI>

<LI>a cv-qualified version of one of the types in this list</LI>

<LI>a type created by application of declarator operators to one
of the types in this list</LI>

<LI>a function type that uses one of the types in this list</LI>

</UL>
</BLOCKQUOTE>
<P>to</P>
<BLOCKQUOTE>
A type without linkage (3.5 [basic.link])
shall not be used as a <I>template-argument</I>
for a template <I>type-parameter</I>.
</BLOCKQUOTE>

<P>Once this issue is ready, <A HREF="
     cwg_defects.html#319">issue 319</A>
should be moved back to ready as well.</P>

<BR><BR><HR><A NAME="474"></A><H4>474.
  
Block-scope <TT>extern</TT> declarations in namespace members
</H4><B>Section: </B>3.5&#160; [basic.link]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>23 Jul 2004<BR>


<P>[Voted into WP at October 2005 meeting.]</P>



<P>Consider the following bit of code:</P>

<PRE>
    namespace N {
      struct S {
        void f();
      };
    }
    using namespace N;
    void S::f() {
      extern void g();  // ::g or N::g?
    }
</PRE>

<P>In 3.5 [basic.link] paragraph 7 the Standard says
(among other things),</P>

<BLOCKQUOTE>
When a block scope declaration of an entity with linkage is not
found to refer to some other declaration, then that entity is a
member of the innermost enclosing namespace.
</BLOCKQUOTE>

<P>The question then is whether <TT>N</TT> is an &#8220;enclosing
namespace&#8221; for the local declaration of <TT>g()</TT>?</P>

<P><B>Proposed resolution (October 2004):</B></P>

<P>Add the following text as a new paragraph at the end of
7.3.1 [namespace.def]:</P>

<BLOCKQUOTE>
The <I>enclosing namespaces</I> of a declaration are those
namespaces in which the declaration lexically appears, except for
a redeclaration of a namespace member outside its original
namespace (e.g., a definition as specified in 7.3.1.2 [namespace.memdef]). Such a redeclaration has the same enclosing
namespaces as the original declaration. [<I>Example:</I>

<PRE>
  namespace Q {
    namespace V {
      void f(); //<SPAN style="font-family:Times;font-style:italic"> enclosing namespaces are the global namespace, </SPAN>Q<SPAN style="font-family:Times;font-style:italic">, and </SPAN>Q::V
      class C { void m(); };
    }
    void V::f() { //<SPAN style="font-family:Times;font-style:italic"> enclosing namespaces are the global namespace, </SPAN>Q<SPAN style="font-family:Times;font-style:italic">, and </SPAN>Q::V
      extern void h(); //<SPAN style="font-family:Times;font-style:italic"> ... so this declares </SPAN>Q::V::h
    }
    void V::C::m() { //<SPAN style="font-family:Times;font-style:italic"> enclosing namespaces are the global namespace, </SPAN>Q<SPAN style="font-family:Times;font-style:italic">, and </SPAN>Q::V
    }
  }
</PRE>

<P>&#8212;<I>end example</I>]</P>
</BLOCKQUOTE>

<BR><BR><HR><A NAME="270"></A><H4>270.
  
Order of initialization of static data members of class templates
</H4><B>Section: </B>3.6.2&#160; [basic.start.init]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jonathan H. Lundquist
 &#160;&#160;&#160;

 <B>Date: </B>9 Feb 2001<BR>


<P>[Moved to DR at 4/02 meeting.]</P>

<P>The Standard does not appear to address how the rules for order
of initialization apply to static data members of class templates.</P>

<P><U>Suggested resolution</U>: Add the following verbiage to either
3.6.2 [basic.start.init] or 9.4.2 [class.static.data]:</P>

<BLOCKQUOTE>

Initialization of static data members of class templates shall be
performed during the initialization of static data members for the
first translation unit to have static initialization performed for
which the template member has been instantiated.  This requirement
shall apply to both the static and dynamic phases of initialization.

</BLOCKQUOTE>

<P><B>Notes from 04/01 meeting:</B></P>

<P>Enforcing an order of initialization on static data members of
class templates will result in substantial overhead on access to such
variables. The problem is that the initialization be required as the
result of instantiation in a function used in the initialization of a
variable in another translation unit. In current systems, the order of
initialization of static data data members of class templates is not
predictable. The proposed resolution is to state that the order of
initialization is undefined.</P>

<P><B>Proposed resolution (04/01, updated slightly 10/01):</B></P>

<P>Replace the following sentence in 3.6.2 [basic.start.init]
paragraph 1:</P>

<BLOCKQUOTE>

Objects with static storage duration defined in namespace scope in the
same translation unit and dynamically initialized shall be initialized
in the order in which their definition appears in the translation
unit.

</BLOCKQUOTE>

<P>with</P>

<BLOCKQUOTE>

Dynamic initialization of an object is either ordered or unordered.
Explicit specializations and definitions
of class template static data members have ordered
initialization. Other class template static data member instances have
unordered initialization. Other objects defined in namespace scope
have ordered initialization. Objects defined within a single
translation unit and with ordered initialization shall be initialized
in the order of their definitions in the translation unit. The order
of initialization is unspecified for objects with unordered
initialization and for objects defined in different translation units.

</BLOCKQUOTE>

<P><I>Note that this wording is further updated by
<A HREF="
     cwg_defects.html#362">issue 362</A>.</I></P>

<P><B>Note (07/01):</B></P>

<P><U>Brian McNamara</U> argues against the proposed
resolution.  The following excerpt captures the central point of
a long message on comp.std.c++:</P>

<BLOCKQUOTE>
I have a class for representing linked lists which looks something like
<PRE>
    template &lt;class T&gt;
    class List {
       ...  static List&lt;T&gt;* sentinel; ...
    };
 
    template &lt;class T&gt;
    List&lt;T&gt;* List&lt;T&gt;::sentinel( new List&lt;T&gt; ); // static member definition
</PRE>
<P>The sentinel list node is used to represent "nil" (the null pointer
cannot be used with my implementation, for reasons which are immaterial
to this discussion).  All of the List's non-static member functions and
constructors depend upon the value of the sentinel.  Under the proposed
resolution for issue #270, Lists cannot be safely instantiated before
main() begins, as the sentinel's initialization is "unordered".</P>

<P>(Some readers may propose that I should use the "singleton pattern" in the
List class.  This is undesirable, for reasons I shall describe at the
end of this post at the location marked "[*]".  For the moment, indulge
me by assuming that "singleton" is not an adequate solution.)</P>

<P>Though this is a particular example from my own experience, I believe it
is representative of a general class of examples.  It is common to use
static data members of a class to represent the "distinguished values"
which are important to instances of that class.  It is imperative that
these values be initialized before any instances of the class are
created, as the instances depend on the values.</P>
</BLOCKQUOTE>

<P>In a comp.std.c++ posting on 28 Jul 2001, Brian McNamara proposes
the following alternative resolution:</P>

<P>Replace the following sentence in 3.6.2 [basic.start.init]
paragraph 1:</P>
<BLOCKQUOTE>
Objects with static storage duration defined in namespace scope in
the same translation unit and dynamically initialized shall be
initialized in the order in which their definition appears in the
translation unit.
</BLOCKQUOTE>
with
<BLOCKQUOTE>
Objects with static storage duration defined in namespace scope 
shall be initialized in the order described below.
</BLOCKQUOTE>
and then after paragraph 1, add this text:
<BLOCKQUOTE>
Dynamic initialization is either ordered or quasi-ordered. Explicit
specializations of class template static data members have ordered
initialization. Other class template static data member instances have
quasi-ordered initialization. All other objects defined in namespace
scope have ordered initialization.  The order of initialization is
specified as follows:
<UL>
<LI>
Objects that are defined within a single translation unit and 
that have ordered initialization shall be initialized in the
order of their definitions in the translation unit.
</LI>
<LI>
Objects that are defined only within a single translation unit 
and that have quasi-ordered initialization shall also be
initialized in the order of their definitions in the translation
unit -- that is, as though these objects had ordered initialization.
</LI>
<LI>
Objects that are defined within multiple translation units (which,
therefore, must have quasi-ordered initialization) shall be
initialized as follows: in exactly one translation unit
(<I>which</I> one is unspecified), the object shall be treated as
though it has ordered initialization; in the other translation
units which define the object, the object will be initialized
before all other objects that have ordered initialization in
those translation units.
</LI>
<LI>
For any two objects, "X" and "Y", with static storage duration 
and defined in namespace scope, if the previous bullets do not
imply a relationship for the initialization ordering between "X"
and "Y", then the relative initialization order of these objects
is unspecified.
</LI>
</UL>
</BLOCKQUOTE>
along with a non-normative note along the lines of
<BLOCKQUOTE>
[ Note: The intention is that translation units can each be compiled
separately with no knowledge of what objects may be re-defined in
other translation units.  Each translation unit can contain a method
which initializes all objects (both quasi-ordered and ordered) as
though they were ordered.  When these translation units are linked
together to create an executable program, all of these objects can
be initialized by simply calling the initialization methods (one
from each translation unit) in any order.  Quasi-ordered objects
require some kind of guard to ensure that they are not initialized
more than once (the first attempt to initialize such an object
should succeed; any subsequent attempts should simply be ignored). ]
</BLOCKQUOTE>

<P><U>Erwin Unruh</U> replies:
There is a point which is not mentioned with this posting.
It is the cost for implementing the scheme. It requires that each
static template variable is instantiated in ALL translation units
where it is used. There has to be a flag for each of these variables
and this flag has to be checked in each TU where the instantiation
took place.</P>

<P>I would reject this idea and stand with the proposed resolution of
issue 270.</P>

<P>There just is no portable way to ensure the "right" ordering of
construction.</P>

<P><B>Notes from 10/01 meeting:</B></P>

<P>The Core Working Group reaffirmed its previous decision.</P>

<BR><BR><HR><A NAME="441"></A><H4>441.
  
Ordering of static reference initialization
</H4><B>Section: </B>3.6.2&#160; [basic.start.init]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>1 Dec 2003<BR>


<P>[Voted into WP at April 2005 meeting.]</P>



<P>
I have a couple of questions about 3.6.2 [basic.start.init],
"Initialization of
non-local objects."  I believe I recall some discussion of
related topics, but I can't find anything relevant in the issues
list.
</P>

<P>The first question arose when I discovered that different
implementations treat reference initialization differently.
Consider, for example, the following (namespace-scope) code:
<PRE>
  int i;
  int&amp; ir = i;
  int* ip = &amp;i;
</PRE>
Both initializers, "i" and "&amp;i", are constant expressions, per
5.19 [expr.const] paragraph 4-5 (a reference constant expression and
an address constant
expression, respectively).  Thus, both initializations are
categorized as static initialization, according to
3.6.2 [basic.start.init] paragraph 1:
<BLOCKQUOTE>
    Zero-initialization and initialization with a constant
    expression are collectively called static initialization; all
    other initialization is dynamic initialization.
</BLOCKQUOTE>
</P>
<P>However, that does not mean that both ir and ip must be
initialized at the same time:
<BLOCKQUOTE>
    Objects of POD types (3.9) with static storage duration
    initialized with constant expressions (5.19) shall be
    initialized before any dynamic initialization takes place.
</BLOCKQUOTE>
</P>
<P>Because "int&amp;" is not a POD type, there is no requirement that it
be initialized before dynamic initialization is performed, and
implementations differ in this regard.  Using a function called
during dynamic initialization to print the values of "ip" and
"&amp;ir", I found that g++, Sun, HP, and Intel compilers initialize
ir before dynamic initialization and the Microsoft compiler does
not.  All initialize ip before dynamic initialization.  I believe
this is conforming (albeit inconvenient :-) behavior.
</P>

<P>So, my first question is whether it is intentional that a
reference of static duration, initialized with a reference
constant expression, need not be initialized before dynamic
initialization takes place, and if so, why?</P>

<P>The second question is somewhat broader.  As
3.6.2 [basic.start.init] is currently
worded, it appears that there are <U>no</U> requirements on when ir is
initialized.  In fact, there is a whole category of objects --
non-POD objects initialized with a constant expression -- for
which no ordering is specified.  Because they are categorized as
part of "static initialization," they are not subject to the
requirement that they "shall be initialized in the order in which
their definition appears in the translation unit."  Because they
are not POD types, they are not required to be initialized before
dynamic initialization occurs.  Am I reading this right?</P>

<P>My preference would be to change
3.6.2 [basic.start.init] paragraph 1 so that 1) references
are treated like POD objects with respect to initialization, and
2) "static initialization" applies only to POD objects and
references.  Here's some sample wording to illustrate:</P>

<P><B>Suggested resolution:</B></P>
<BLOCKQUOTE>
    Objects with static storage duration (3.7.1) shall be
    zero-initialized (8.5) before any other initialization takes
    place.  Initializing a reference, or an object of POD
    type, of static storage duration with a constant expression
    (5.19) is called constant initialization.  Together,
    zero-initialization and constant initialization are called
    static initialization; all other initialization is dynamic
    initialization.  Static initialization shall be performed
    before any dynamic initialization takes place.  [Remainder
    unchanged.]
</BLOCKQUOTE>

<P><B>Proposed Resolution:</B></P>

<P>Change 3.6.2 [basic.start.init] paragraph 1 as follows:
</P>
<BLOCKQUOTE>
Objects with static storage duration (3.7.1) shall be
zero-initialized (8.5) before any other initialization takes
place. <SPAN style="font-weight:bold;background-color:#A0FFA0">Initializing a reference, or an object of POD type, of
static storage duration with a constant expression (5.19) is
called <I>constant initialization</I>.  Together,
zero-initialization and constant initialization are
</SPAN><SPAN style="text-decoration:line-through;background-color:#FFA0A0">Zero-initialization and initialization with a
constant expression are collectively</SPAN> called <I>static
initialization</I>; all other initialization is <I>dynamic
initialization</I>. <SPAN style="font-weight:bold;background-color:#A0FFA0">Static initialization shall be performed
</SPAN><SPAN style="text-decoration:line-through;background-color:#FFA0A0">Objects of POD types (3.9) with static storage
duration initialized with constant expressions (5.19) shall be
initialized</SPAN> before any dynamic initialization takes
place.
</BLOCKQUOTE>

<BR><BR><HR><A NAME="688"></A><H4>688.
  
Constexpr constructors and static initialization
</H4><B>Section: </B>3.6.2&#160; [basic.start.init]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Peter Dimov
 &#160;&#160;&#160;

 <B>Date: </B>26 March, 2008<BR>


<P>[Voted into the WP at the September, 2008 meeting (resolution
in paper N2757).]</P>



<P>Given this literal type,</P>

<PRE>
    struct X {
        constexpr X() { }
    };
</PRE>

<P>and this definition,</P>

<PRE>
    static X x;
</PRE>

<P>the current specification does not require that <TT>x</TT> be
statically initialized because it is not &#8220;initialized with
a constant expression&#8221; (3.6.1 [basic.start.main]
paragraph 1).</P>

<P><U>Lawrence Crowl</U>:</P>

<P>This guarantee is essential for atomics.</P>

<P><U>Jens Maurer</U>:</P>

<P>Suggestion:</P>

<BLOCKQUOTE>

A reference with static storage duration or an object of literal
type with static storage duration can be initialized with a
constant expression (5.19 [expr.const]) or with a
constexpr constructor; this is called constant initialization.

</BLOCKQUOTE>

<P>(Not spelling out &#8220;default constructor&#8221; makes it
easier to handle multiple-parameter constexpr constructors, where
there isn't &#8220;a&#8221; constant expression but several.)</P>

<P><U>Peter Dimov</U>:</P>

<P>In addition, there is a need to enforce static initialization
for non-literal types: <TT>std::shared_ptr</TT>,
<TT>std::once_flag</TT>, and <TT>std::atomic_*</TT> all have
nontrivial copy constructors, making them non-literal types.
However, we need a way to ensure that a constexpr constructor
called with constant expressions will guarantee static
initialization, regardless of the nontriviality of the copy
constructor.</P>

<P><B>Proposed resolution (April, 2008):</B></P>

<OL>
<LI><P>Change 3.6.2 [basic.start.init] paragraph 1 as follows:
</P></LI>

<BLOCKQUOTE>

...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A reference with static storage duration and an object of
trivial or literal type with static storage duration can be
initialized with a constant expression (5.19 [expr.const]); this</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">If a reference with static storage
duration is initialized with a constant expression (5.19 [expr.const]) or if the initialization of an object with static
storage duration satisfies the requirements for the object being
declared with <TT>constexpr</TT> (7.1.5 [dcl.constexpr]),
that initialization</SPAN> is called <I>constant
initialization</I>...

</BLOCKQUOTE>

<LI><P>Change 6.7 [stmt.dcl] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A local object of trivial or literal type (3.9 [basic.types]) with static storage duration initialized with
<I>constant-expression</I>s is initialized</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Constant
initialization (3.6.2 [basic.start.init]) of a local entity
with static storage duration is performed</SPAN> before its block is
first entered...

</BLOCKQUOTE>

<LI><P>Change 7.1.5 [dcl.constexpr] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

A <TT>constexpr</TT> specifier used in an object declaration
declares the object as <TT>const</TT>. Such an object shall be
initialized, and every expression that appears in its initializer
(8.5 [dcl.init]) shall be a constant expression. Every
implicit conversion used in converting the initializer
expressions <SPAN style="font-weight:bold;background-color:#A0FFA0">and every constructor call used for the
initialization</SPAN> shall be one of those allowed in a constant
expression (5.19 [expr.const])...

</BLOCKQUOTE>

<LI><P>Replace 8.5.1 [dcl.init.aggr] paragraph 14 as
follows:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">When an aggregate with static storage duration is initialized
with a brace-enclosed <I>initializer-list</I>, if all the member
initializer expressions are constant expressions, and the
aggregate is a trivial type, the initialization shall be done
during the static phase of initialization (3.6.2 [basic.start.init]); 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.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> The order of initialization
for aggregates with static storage duration is specified in
3.6.2 [basic.start.init] and 6.7 [stmt.dcl].
&#8212;<I>end note</I>]</SPAN>

</BLOCKQUOTE>

</OL>

<P>(Note: the change to 3.6.2 [basic.start.init] paragraph 1
needs to be reconciled with the conflicting change in
<A HREF="
     cwg_defects.html#684">issue 684</A>.)</P>

<BR><BR><HR><A NAME="28"></A><H4>28.
  
'exit', 'signal' and static object destruction
</H4><B>Section: </B>3.6.3&#160; [basic.start.term]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Martin J. O'Riordan
 &#160;&#160;&#160;

 <B>Date: </B>19 Oct 1997<BR>


<P>[Voted into the WP at the June, 2008 meeting.]</P>



<P>The C++ standard has inherited the definition of the 'exit' function
more or less unchanged from ISO C.</P>

<P>However, when the 'exit' function is called, objects of static extent
which have been initialised, will be destructed if their types posses a
destructor.</P>

<P>In addition, the C++ standard has inherited the definition of the 'signal'
function and its handlers from ISO C, also pretty much unchanged.</P>

<P>The C standard says that the only standard library functions that may
be called while a signal handler is executing, are the functions 'abort',
'signal' and 'exit'.</P>

<P>This introduces a bit of a nasty turn, as it is not at all unusual for
the destruction of static objects to have fairly complex destruction semantics,
often associated with resource release. These quite commonly involve apparently
simple actions such as calling 'fclose' for a FILE handle.</P>

<P>Having observed some very strange behaviour in a program recently which
in handling a SIGTERM signal, called the 'exit' function as indicated by
the C standard.</P>

<P>But unknown to the programmer, a library static object performed some
complicated resource deallocation activities, and the program crashed.</P>

<P>The C++ standard says nothing about the interaction between signals,
exit and static objects. My observations, was that in effect, because the
destructor called a standard library function other than 'abort', 'exit'
or 'signal', while transitively in the execution context of the signal
handler, it was in fact non-compliant, and the behaviour was undefined
anyway.</P>

<P>This is I believe a plausible judgement, but given the prevalence of
this common programming technique, it seems to me that we need to say something
a lot more positive about this interaction.</P>

<P>Curiously enough, the C standard fails to say anything about the analogous
interaction with functions registered with 'atexit' ;-)</P>



<P><B>Proposed Resolution (10/98):</B></P>

<P>The current Committee Draft of the next version of the ISO C standard
specifies that the only standard library function that may be called while
a signal handler is executing is 'abort'. This would solve the above problem.</P>

<P>[This issue should remain open until it has been decided that the next
version of the C++ standard will use the next version of the C standard
as the basis for the behavior of 'signal'.]</P>

<P><B>Notes (November, 2006):</B></P>

<P>C89 is slightly contradictory here: It allows any signal handler to
<I>terminate</I> by calling <TT>abort</TT>, <TT>exit</TT>,
<TT>longjmp</TT>, but (for asynchronous signals, i.e. not those
produced by <TT>abort</TT> or <TT>raise</TT>) then makes calling any
library function other than <TT>signal</TT> with the current signal
undefined behavior (C89 7.7.1.1). For synchronous signals, C99 forbids
calls to <TT>raise</TT>, but imposes no other restrictions. For
asynchronous signals, C99 allows only calls
to <TT>abort</TT>, <TT>_Exit</TT>, and <TT>signal</TT> with the
current signal (C99 7.14.1.1). The current C++ WP refers to
&#8220;plain old functions&#8221; and &#8220;conforming C
programs&#8221; (18.10 [support.runtime] paragraph 6). </P>

<P><B>Proposed Resolution (November, 2006):</B></P>

<P>Change the footnote in 18.10 [support.runtime] paragraph 6 as
follows:</P>

<BLOCKQUOTE>

In particular, a signal handler using exception handling is very
likely to have problems.  <SPAN style="font-weight:bold;background-color:#A0FFA0">Also, invoking <TT>std::exit</TT> may
cause destruction of objects, including those of the standard library
implementation, which, in general, yields undefined behavior in a
signal handler (see 1.9 [intro.execution]).</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="521"></A><H4>521.
  
Requirements for exceptions thrown by allocation functions
</H4><B>Section: </B>3.7.4.1&#160; [basic.stc.dynamic.allocation]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>22 May 2005<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>

<P>According to 3.7.4.1 [basic.stc.dynamic.allocation] paragraph 3,</P>

<BLOCKQUOTE>

Any other allocation function that fails to allocate storage shall
only indicate failure by throwing an exception of
class <TT>std::bad_alloc</TT> (18.6.2.1 [bad.alloc]) or a
class derived from <TT>std::bad_alloc</TT>.

</BLOCKQUOTE>

<P>Shouldn't this statement have the usual requirements for an
unambiguous and accessible base class?</P>

<P><B>Proposed resolution (April, 2006):</B></P>

<P>Change the last sentence of 3.7.4.1 [basic.stc.dynamic.allocation]
paragraph 3 as indicated:</P>

<BLOCKQUOTE>

Any other allocation function that fails to allocate storage shall
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">only</SPAN> indicate failure <SPAN style="font-weight:bold;background-color:#A0FFA0">only</SPAN> by throwing an exception of
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">class <TT>std::bad_alloc</TT> (18.6.2.1 [bad.alloc]) or a
class derived from <TT>std::bad_alloc</TT></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">a type that would
match a handler (15.3 [except.handle]) of type
<TT>std::bad_alloc</TT> (18.6.2.1 [bad.alloc])</SPAN>.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="220"></A><H4>220.
  
All deallocation functions should be required not to throw
</H4><B>Section: </B>3.7.4.2&#160; [basic.stc.dynamic.deallocation]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Herb Sutter
 &#160;&#160;&#160;

 <B>Date: </B>31 Mar 2000<BR>


<P>[Voted into the WP at the September, 2008 meeting (resolution
in paper N2757).]</P>

<P>[Picked up by evolution group at October 2002 meeting.]</P>



<P>The default global operators <TT>delete</TT> are specified to not
throw, but there is no requirement that replacement global, or
class-specific, operators <TT>delete</TT> must not throw. That ought
to be required.</P>

<P>In particular:</P>

<UL>

<LI>3.7.4.2 [basic.stc.dynamic.deallocation] paragraph 2, at the end of the
first sentence, should also require that no exceptions be thrown.</LI>

<LI>12.5 [class.free], including its examples, should require
nonthrowing class-specific <TT>operator delete</TT>.</LI>

<LI>17.6.4.6 [replacement.functions] paragraph 2 should append
<TT>throw()</TT> to the signature of each of the four operators
<TT>delete</TT>.</LI>

</UL>

<P>We already require that all versions of an allocator's deallocate()
must not throw, so that part is okay.</P>

<P><B>Rationale (04/00):</B></P>

<OL>

<LI>Replacement deallocation functions are already required not to
throw an exception (cf 17.6.4.8 [res.on.functions] paragraph 2,
as applied to 18.6.1.1 [new.delete.single] paragraph 12 and
18.6.1.2 [new.delete.array] paragraph 11).</LI>

<LI>Section 17.6.4.6 [replacement.functions] is describing the
signatures of the functions to be replaced; exception specfications
are not part of the signature.</LI>

<LI>There does not appear to be any pressing need to require that
class member deallocation functions not throw.</LI>

</OL>

<P><B>Note (March, 2008):</B></P>

<P>The Evolution Working Group has accepted the intent of this issue
and referred it to CWG for action for C++0x (see paper
J16/07-0033 = WG21 N2173).</P>

<P><B>Proposed resolution (March, 2008):</B></P>

<P>Change 3.7.4.2 [basic.stc.dynamic.deallocation] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<SPAN style="font-weight:bold;background-color:#A0FFA0">A deallocation function shall not terminate by throwing an
exception.</SPAN>
The value of the first argument supplied to a deallocation function...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="348"></A><H4>348.
  
<TT>delete</TT> and user-written deallocation functions
</H4><B>Section: </B>3.7.4.2&#160; [basic.stc.dynamic.deallocation]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Ruslan Abdikeev
 &#160;&#160;&#160;

 <B>Date: </B>1 April 2002<BR>


<P>[Voted into WP at October 2005 meeting.]</P>

<P>Standard is clear on behaviour of default allocation/deallocation
functions.
However, it is surpisingly vague on requirements to the behaviour
of user-defined deallocation function and an interaction between
delete-expression and deallocation function.
This caused a heated argument on fido7.su.c-cpp newsgroup.</P>

<P>Resume:</P>

<P>It is not clear if user-supplied deallocation function is called from
delete-expr when the operand of delete-expr is the null
pointer (5.3.5 [expr.delete]).
If it is, standard does not specify what user-supplied
deallocation function shall do with
the null pointer operand (18.6.1 [new.delete]).
Instead, Standard uses the term "has no effect", which meaning
is too vague in context given (5.3.5 [expr.delete]).</P>

<P>Description:</P>

<P>Consider statements
<PRE>
   char* p= 0; //result of failed non-throwing ::new char[]
   ::delete[] p;
</PRE>
Argument passed to delete-expression is valid - it is the result
of a call to the non-throwing version of ::new, which has been failed.
5.3.5 [expr.delete] paragraph 1 explicitly prohibit us to pass 0
without having the ::new failure.</P>

<P>Standard does NOT specify whether user-defined deallocation function
should be called in this case, or not.</P>

<P>Specifically, standard says in 5.3.5 [expr.delete] paragraph 2:
<BLOCKQUOTE>
   ...if the value of the operand of delete is the null pointer the operation
   has no effect.
</BLOCKQUOTE>
Standard doesn't specify term "has no effect".
It is not clear from this context, whether the called deallocation function
is required to have no effect, or delete-expression shall not call
the deallocation function.</P>
<P>Furthermore, in para 4 standard says on default deallocation function:
<BLOCKQUOTE>
   If the delete-expression calls the implementation deallocation
   function (3.7.4.2 [basic.stc.dynamic.deallocation]),
   if the operand of the delete expression is not
   the null pointer constant, ...
</BLOCKQUOTE>
Why it is so specific on interaction of default deallocation function
and delete-expr?</P>

<P>If "has no effect" is a requirement to the deallocation function,
then it should be stated in 3.7.4.2 [basic.stc.dynamic.deallocation],
or in 18.6.1.1 [new.delete.single] and
18.6.1.2 [new.delete.array],
and it should be stated explicitly.</P>

<P>Furthermore, standard does NOT specify what actions shall
be performed by user-supplied deallocation function if NULL
is given (18.6.1.1 [new.delete.single] paragraph 12):</P>
<BLOCKQUOTE>
   Required behaviour: accept a value of ptr that is null or that was
   returned by an earlier call to the default
<TT>operator new(std::size_t)</TT>
   or <TT>operator new(std::size_t, const std::nothrow_t&amp;)</TT>.
</BLOCKQUOTE>

<P>The same corresponds to ::delete[] case.</P>

<P>Expected solution:</P>

<OL>
<LI>
Make it clear that delete-expr will not call deallocation function
if null pointer is given (in 5.3.5 [expr.delete]).
</LI>
<LI>
Specify what user deallocation function shall do when null is given
(either in 3.7.4.2 [basic.stc.dynamic.deallocation], or
in 18.6.1.1 [new.delete.single], and
18.6.1.2 [new.delete.array]).
</LI>
</OL>

<P><B>Notes from October 2002 meeting:</B></P>

<P>We believe that study of 18.6.1.1 [new.delete.single] paragraphs
12 and 13, 18.6.1.2 [new.delete.array] paragraphs 11 and 12, and
3.7.4.2 [basic.stc.dynamic.deallocation] paragraph 3 shows that the
system-provided operator delete functions must accept a null pointer and
ignore it.  Those sections also show that a user-written replacement
for the system-provided operator delete functions must accept a
null pointer.  There is no requirement that such functions ignore
a null pointer, which is okay -- perhaps the reason for replacing the
system-provided functions is to do something special
with null pointer values (e.g., log such calls and return).</P>

<P>We believe that the standard should not require an implementation
to call a delete function with a null pointer, but it must allow
that.  For the system-provided delete functions or replacements
thereof, the standard already makes it clear that the delete
function must accept a null pointer.  For class-specific delete
functions, we believe the standard should require that such
functions accept a null pointer, though it should not mandate
what they do with null pointers.</P>

<P>5.3.5 [expr.delete] needs to be updated to say that
it is unspecified whether or not the operator delete function is
called with a null pointer, and 3.7.4.2 [basic.stc.dynamic.deallocation]
needs to be updated to say that any deallocation function must
accept a null pointer.</P>

<P><B>Proposed resolution (October, 2004):</B></P>

<OL>

<LI><P>Change 5.3.5 [expr.delete] paragraph 2 as
indicated:</P>

<BLOCKQUOTE>

If the operand has a class type, the operand is converted to a
pointer type by calling the above-mentioned conversion function,
and the converted operand is used in place of the original
operand for the remainder of this section. In either alternative,
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">if</SPAN> the value of the operand of <TT>delete</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">is the
null pointer the operation has no effect</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">may be a null
pointer value. If it is not a null pointer value, in</SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">In</SPAN> the first alternative (<I>delete object</I>), the value
of the operand of <TT>delete</TT> shall be a pointer to a
non-array object or a pointer to a sub-object (1.8 [intro.object]) representing a base class of such an object
(clause 10 [class.derived])...

</BLOCKQUOTE>

</LI>

<LI><P>Change 5.3.5 [expr.delete] paragraph 4 as
follows (note that the old wording reflects the changes proposed
by <A HREF="
     cwg_defects.html#442">issue 442</A>:</P>

<BLOCKQUOTE>

<P>The <I>cast-expression</I> in a <I>delete-expression</I> shall
be evaluated exactly once. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">If the delete-expression calls the
implementation deallocation function (3.7.4.2 [basic.stc.dynamic.deallocation]), and if the value of the operand of the
delete expression is not a null pointer, the deallocation
function will deallocate the storage referenced by the pointer
thus rendering the pointer invalid. [<I>Note:</I> the value of a
pointer that refers to deallocated storage is
indeterminate. &#8212;<I>end note</I>]</SPAN>
</P>

</BLOCKQUOTE>

</LI>

<LI><P>Change 5.3.5 [expr.delete] paragraphs 6-7 as
follows:</P>

<BLOCKQUOTE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">The</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">If the value of the operand of the
<I>delete-expression</I> is not a null pointer value, the</SPAN>
<I>delete-expression</I> will invoke the destructor (if any) for
the object or the elements of the array being deleted. In the
case of an array, the elements will be destroyed in order of
decreasing address (that is, in reverse order of the completion
of their constructor; see 12.6.2 [class.base.init]).</P>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">The</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">If the value of the operand of the <I>delete-expression</I> is not a
null pointer value, the</SPAN> <I>delete-expression</I> will call a
deallocation function (3.7.4.2 [basic.stc.dynamic.deallocation]). <SPAN style="font-weight:bold;background-color:#A0FFA0">Otherwise, it is unspecified
whether the deallocation function will be called.</SPAN> [<I>Note:</I> The
deallocation function is called regardless of whether the
destructor for the object or some element of the array throws an
exception. &#8212;<I>end note</I>]</P>

</BLOCKQUOTE>

</LI>

<LI><P>Change 3.7.4.2 [basic.stc.dynamic.deallocation] paragraph 3 as
indicated:</P>

<BLOCKQUOTE>

The value of the first argument supplied to <SPAN style="text-decoration:line-through;background-color:#FFA0A0">one of the</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">a</SPAN>
deallocation function<SPAN style="text-decoration:line-through;background-color:#FFA0A0">s provided in the standard library</SPAN> may be a
null pointer value; if so, <SPAN style="font-weight:bold;background-color:#A0FFA0">and if the deallocation function is
one supplied in the standard library,</SPAN> the call <SPAN style="text-decoration:line-through;background-color:#FFA0A0">to the
deallocation function</SPAN> has no effect. Otherwise, the value
supplied to <TT>operator delete(void*)</TT> in the standard library shall
be one of the values returned by a previous invocation of either
<TT>operator new(std::size_t)</TT> or <TT>operator new(std::size_t, const
std::nothrow_t&amp;)</TT> in the standard library, and the value supplied
to <TT>operator delete[](void*)</TT> in the standard library shall be one
of the values returned by a previous invocation of either
<TT>operator new[](std::size_t)</TT> or <TT>operator new[](std::size_t, const
std::nothrow_t&amp;)</TT> in the standard library.

</BLOCKQUOTE>

</LI>

</OL>

<P><I>[Note: this resolution also resolves
<A HREF="
     cwg_defects.html#442">issue 442</A>.]</I></P>

<BR><BR><HR><A NAME="119"></A><H4>119.
  
Object lifetime and aggregate initialization
</H4><B>Section: </B>3.8&#160; [basic.life]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jack Rouse
 &#160;&#160;&#160;

 <B>Date: </B>20 May 1999<BR>



<P>[Moved to DR at 4/02 meeting.]</P>



<P><B>Jack Rouse:</B>
3.8 [basic.life]
 paragraph 1
includes:</P>
<BLOCKQUOTE>
The lifetime of an object is a runtime property of the object. The
lifetime of an object of type <TT>T</TT> begins when:
<UL>
<LI>storage with the proper alignment and size for type <TT>T</TT>
is obtained, and</LI>

<LI>if <TT>T</TT> is a class type with a non-trivial constructor
(12.1 [class.ctor]
), the
constructor call has completed.</LI>
</UL>
</BLOCKQUOTE>

Consider the code:
<PRE>
    struct B {
        B( int = 0 );
        ~B();
    };

    struct S {
        B b1;
    };

    int main()
    {
        S s = { 1 };
        return 0;
    }
</PRE>

In the code above, class <TT>S</TT> does have a non-trivial constructor, the
default constructor generated by the compiler.  According the text
above, the lifetime of the auto <TT>s</TT> would never begin because a
constructor for <TT>S</TT> is never called.  I think the second case in the
text needs to include aggregate initialization.

<P><B>Mike Miller:</B>
I see a couple of ways of fixing the problem.  One way would be
to change "the constructor call has completed" to "the object's
initialization is complete."</P>

<P>Another would be to add following "a class type with a non-trivial
constructor" the phrase "that is not initialized with the brace
notation (8.5.1 [dcl.init.aggr]
)."</P>

<P>The first formulation treats aggregate initialization like a
constructor call; even POD-type members of an aggregate could
not be accessed before the aggregate initialization completed.
The second is less restrictive; the POD-type members of the
aggregate would be usable before the initialization, and the
members with non-trivial constructors (the only way an
aggregate can acquire a non-trivial constructor) would be
protected by recursive application of the lifetime rule.</P>

<P><B>Proposed resolution (04/01):</B> </P>

<P>In 3.8 [basic.life] paragraph 1, change</P>

<BLOCKQUOTE>

If <TT>T</TT> is a class type with a non-trivial constructor
(12.1 [class.ctor]), the constructor call has
completed.

</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>

If <TT>T</TT> is a class type with a non-trivial constructor
(12.1 [class.ctor]), the initialization is complete.
[<I>Note:</I> the initialization can be performed by a
constructor call or, in the case of an aggregate with an
implicitly-declared non-trivial default constructor, an
aggregate initialization (8.5.1 [dcl.init.aggr]).]

</BLOCKQUOTE>

<BR><BR><HR><A NAME="274"></A><H4>274.
  
Cv-qualification and char-alias access to out-of-lifetime objects
</H4><B>Section: </B>3.8&#160; [basic.life]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>14 Mar 2001<BR>


<P>[Voted into WP at April 2003 meeting.]</P>

<P>The wording in 3.8 [basic.life] paragraph 6 allows an
lvalue designating an out-of-lifetime object to be used as the
operand of a <TT>static_cast</TT> only if the conversion is
ultimately to "<TT>char&amp;</TT>" or "<TT>unsigned char&amp;</TT>".
This description excludes the possibility of using a cv-qualified
version of these types for no apparent reason.</P>

<P><B>Notes on 04/01 meeting:</B></P>

<P>The wording should be changed to allow cv-qualified char
types.</P>

<P><B>Proposed resolution (04/01):</B></P>

<P>In 3.8 [basic.life] paragraph 6 change the third bullet:
<UL>
<LI>
the lvalue is used as the operand of a <TT>static_cast</TT>
(5.2.9 [expr.static.cast])
(except when the conversion is ultimately to <TT>char&amp;</TT> or <TT>unsigned
char&amp;</TT>), or
</LI>
</UL>
to read:
<UL>
<LI>
the lvalue is used as the operand of a <TT>static_cast</TT>
(5.2.9 [expr.static.cast])
except when the conversion is ultimately to <TT><I>cv</I> char&amp;</TT> or
<TT><I>cv</I> unsigned char&amp;</TT>, or
</LI>
</UL>
</P>

<BR><BR><HR><A NAME="404"></A><H4>404.
  
Unclear reference to construction with non-trivial constructor
</H4><B>Section: </B>3.8&#160; [basic.life]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>8 Apr 2003<BR>


<P>[Voted into WP at March 2004 meeting.]</P>

<P>3.8 [basic.life] paragraph 1 second bullet says:</P>
<BLOCKQUOTE>
if T is a class type with a non-trivial constructor (12.1),
the constructor call has completed.
</BLOCKQUOTE>

<P>This is confusing; what was intended is probably something like</P>
<BLOCKQUOTE>
if T is a class type and the constructor invoked to create the
object is non-trivial (12.1), the constructor call has completed.
</BLOCKQUOTE>

<P><B>Proposed Resolution (October 2003):</B></P>

<P>As given above.</P>

<BR><BR><HR><A NAME="594"></A><H4>594.
  
Coordinating issues 119 and 404 with delegating constructors
</H4><B>Section: </B>3.8&#160; [basic.life]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Tom Plum
 &#160;&#160;&#160;

 <B>Date: </B>30 August 2006<BR>


<P>[Voted into the WP at the September, 2008 meeting.]</P>

<P>In ISO/IEC 14882:2003, the second bullet of 3.8 [basic.life] paragraph 1 reads,</P>

<BLOCKQUOTE>

if <TT>T</TT> is a class type with a non-trivial constructor
(12.1 [class.ctor]), the constructor call has completed.

</BLOCKQUOTE>

<P><A HREF="
     cwg_defects.html#119">Issue 119</A> pointed out that
aggregate initialization can be used with some classes with a
non-trivial implicitly-declared default constructor, and that
in such cases there is no call to the object's constructor.
The resolution for that issue was to change the previously-cited
wording to read,</P>

<BLOCKQUOTE>

If <TT>T</TT> is a class type with a non-trivial constructor
(12.1 [class.ctor], <SPAN style="font-weight:bold;background-color:#A0FFA0">the initialization is complete</SPAN>.

</BLOCKQUOTE>

<P>Later (but before the WP was revised with the wording from
the resolution of <A HREF="
     cwg_defects.html#119">issue 119</A>),
<A HREF="
     cwg_defects.html#404">issue 404</A> changed the 2003 wording to
read,</P>

<BLOCKQUOTE>

If <TT>T</TT> is a class type <SPAN style="font-weight:bold;background-color:#A0FFA0">and the constructor invoked to
create the object is non-trivial</SPAN> (12.1 [class.ctor]),
the constructor call has completed.

</BLOCKQUOTE>

<P>thus reversing the effect of <A HREF="
     cwg_defects.html#119">issue 119</A>,
whose whole purpose was to cover objects with non-trivial constructors
that are <I>not</I> invoked.</P>

<P>Through an editorial error, the post-Redmond draft (N1905)
still contained the original 2003 wording that should have been
replaced by the resolution of <A HREF="
     cwg_defects.html#119">issue 119</A>, <I>in addition to</I> the new wording from the
resolution:</P>

<BLOCKQUOTE>

if <TT>T</TT> is a class type and the constructor invoked to
create the object is non-trivial (12.1 [class.ctor]),
the constructor call has completed. the initialization is
complete.

</BLOCKQUOTE>

<P>Finally, during the application of the edits for delegating
constructors (N1986), this editing error was &#8220;fixed&#8221;
by retaining the original 2003 wording (which was needed for the
application of the change specified in N1986), so that the
current draft (N2009) reads,</P>

<BLOCKQUOTE>

if <TT>T</TT> is a class type and the constructor invoked to
create the object is non-trivial (12.1 [class.ctor]),
the principal constructor call 12.6.2 [class.base.init]) has
completed.

</BLOCKQUOTE>

<P>Because the completion of the call to the principal constructor
corresponds to the point at which the object is &#8220;fully
constructed&#8221; (15.2 [except.ctor] paragraph 2), i.e.,
its initialization is complete, I believe that the exact wording
of the <A HREF="
     cwg_defects.html#119">issue 119</A> resolution would be
correct and should be restored verbatim.</P>

<P><B>Proposed resolution (June, 2008):</B></P>

<P>Change 3.8 [basic.life] paragraph 1 as follows:</P>

<BLOCKQUOTE>

<P>The <I>lifetime</I> of an object is a runtime property of the
object. <SPAN style="font-weight:bold;background-color:#A0FFA0">An object is said to have non-trivial initialization if it
is of a class or aggregate type and it or one of its members is
initialized by a constructor other than a trivial default
constructor. [<I>Note:</I> Initialization by a trivial copy
constructor is non-trivial initialization. &#8212;<I>end note</I>]</SPAN>
The lifetime of an object <SPAN style="text-decoration:line-through;background-color:#FFA0A0">of type <TT>T</TT></SPAN> begins when:</P>

<UL><LI><P>storage with the proper alignment and size <SPAN style="text-decoration:line-through;background-color:#FFA0A0">for type
<TT>T</TT></SPAN> is obtained, and</P></LI>

<LI><P>if <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>T</TT> is a class type and the constructor invoked to
create the object is non-trivial (12.1 [class.ctor]), the
principal constructor call (12.6.2 [class.base.init]) has
completed. [<I>Note:</I> the initialization can be performed by a
constructor call or, in the case of an aggregate with an
implicitly-declared non-trivial default constructor, an aggregate
initialization 8.5.1 [dcl.init.aggr]. &#8212;<I>end note</I>]</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">the object has non-trivial initialization, its initialization is
complete.</SPAN></P></LI>

</UL>

<P>The lifetime of an object of type <TT>T</TT> ends when...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="644"></A><H4>644.
  
Should a trivial class type be a literal type?
</H4><B>Section: </B>3.9&#160; [basic.types]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>8 Aug 2007<BR>


<P>[Voted into the WP at the June, 2008 meeting.]</P>



<P>The original proposed wording for 3.9 [basic.types]
paragraph 11 required a constexpr constructor for a literal class
only &#8220;if the class has at least one user-declared
constructor.&#8221;  This wording was dropped during the
review by CWG out of a desire to ensure that literal types not
have any uninitialized members.  Thus, a class like</P>

<PRE>
    struct pixel {
        int x, y;
    };
</PRE>

<P>is not a literal type.  However, if an object of that type is
aggregate-initialized or value-initialized, there can be no
uninitialized members; the missing wording should be restored in
order to permit use of expressions like <TT>pixel().x</TT> as
constant expressions.</P>

<P><B>Proposed resolution (February, 2008):</B></P>

<P>Change 3.9 [basic.types] paragraph 10 as follows:</P>

<BLOCKQUOTE>

A type is a <I>literal type</I> if it is:
<UL>
<LI>a scalar type; or</LI>
<LI>a class type (clause 9 [class]) with</LI>
<UL>
<LI>a trivial copy constructor,</LI>
<LI>a trivial destructor,</LI>
<LI><SPAN style="font-weight:bold;background-color:#A0FFA0">a trivial default constructor or</SPAN> at least one constexpr
constructor other than the copy constructor,</LI>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><LI>no virtual base classes, and</LI></SPAN>
<LI>all non-static data members and base classes of literal types; or</LI>
</UL>
<LI>an array of literal type.</LI>
</UL>

</BLOCKQUOTE>
<BR><BR><HR><A NAME="158"></A><H4>158.
  
Aliasing and qualification conversions
</H4><B>Section: </B>3.10&#160; [basic.lval]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Stump
 &#160;&#160;&#160;

 <B>Date: </B>20 Aug 1999<BR>



<P>[Moved to DR at 4/02 meeting.]</P>

<P>3.10 [basic.lval] paragraph 15 lists the types via which
an lvalue can be used to access the stored value of an object; using
an lvalue type that is not listed results in undefined behavior.  It
is permitted to add cv-qualification to the actual type of the object
in this access, but only at the top level of the type ("a cv-qualified
version of the dynamic type of the object").</P>

<P>However, 4.4 [conv.qual] paragraph 4 permits a
"conversion [to] add cv-qualifiers at levels other than the first in
multi-level pointers."  The combination of these two rules
allows creation of pointers that cannot be dereferenced without
causing undefined behavior.  For instance:</P>

<PRE>
    int* jp;
    const int * const * p1 = &amp;jp;
    *p1;    // undefined behavior!
</PRE>

<P>The reason that <TT>*p1</TT> results in undefined behavior
is that the type of the lvalue is <TT>const int * const"</TT>,
which is <I>not</I> "a cv-qualified version of" <TT>int*</TT>.</P>

<P>Since the conversion is permitted, we must give it defined
semantics, hence we need to fix the wording in 3.10 [basic.lval] to include all possible conversions of the type via
4.4 [conv.qual].</P>

<P><B>Proposed resolution (04/01):</B></P>

<P>Add a new bullet to 3.10 [basic.lval] paragraph 15,
following "a cv-qualified version of the dynamic type of the
object:"</P>

<UL>
<LI>A type similar (as defined in 4.4 [conv.qual]) to
the dynamic type of the object,</LI>
</UL>

<BR><BR><HR><A NAME="649"></A><H4>649.
  
Optionally ill-formed extended alignment requests
</H4><B>Section: </B>3.11&#160; [basic.align]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>12 Aug 2007<BR>


<P>[Voted into the WP at the September, 2008 meeting.]</P>



<P>The requirements on an implementation when presented with an
<I>alignment-specifier</I> not supported by that implementation in
that context are contradictory: 3.11 [basic.align] paragraph 9
says,</P>

<BLOCKQUOTE>

If a request for a specific extended alignment in a specific context
is not supported by an implementation, the implementation may reject
the request as ill-formed. The implementation may also silently ignore
the requested alignment.

</BLOCKQUOTE>

<P>In contrast, 7.6.2 [dcl.align] paragraph 2, bullet 4
says simply,</P>

<BLOCKQUOTE>

<UL>
<LI>if the constant expression evaluates to an extended alignment and
the implementation does not support that alignment in the context of
the declaration, the program is ill-formed</LI>
</UL>

</BLOCKQUOTE>

<P>with no provision to &#8220;silently ignore&#8221; the requested
alignment.  These two passages need to be reconciled.</P>

<P>If the outcome of the reconciliation is to grant implementations
the license to accept and ignore extended alignment requests, the
specification should be framed in terms of mechanisms that already
exist in the Standard, such as undefined behavior and/or
conditionally-supported constructs; &#8220;ill-formed&#8221; is a
category that is defined by the Standard, not something that an
implementation can decide.</P>

<P><B>Notes from the February, 2008 meeting:</B></P>

<P>The consensus was that such requests should be ill-formed and
require a diagnostic.  However, it was also observed that an
implementation need not reject an ill-formed program; the only
requirement is that it issue a diagnostic.  It would thus be
permissible for an implementation to &#8220;noisily ignore&#8221;
(as opposed to &#8220;silently ignoring&#8221;) an unsupported
alignment request.</P>

<P><B>Proposed resolution (June, 2008):</B></P>

<P>Change 3.11 [basic.align] paragraph 9 as follows:</P>

<BLOCKQUOTE>

If a request for a specific extended alignment in a specific context
is not supported by an implementation, the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">implementation may
reject the request as</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">program is</SPAN> ill-formed. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The
implementation may also silently ignore the requested
alignment. [Note: a</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">A</SPAN>dditionally, a request for runtime
allocation of dynamic <SPAN style="text-decoration:line-through;background-color:#FFA0A0">memory</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">storage</SPAN> for which the
requested alignment cannot be honored <SPAN style="text-decoration:line-through;background-color:#FFA0A0">may</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">shall</SPAN> be
treated as an allocation failure. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">&#8212;<I>end note</I>]</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="519"></A><H4>519.
  
Null pointer preservation in <TT>void*</TT> conversions
</H4><B>Section: </B>4.10&#160; [conv.ptr]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>comp.std.c++
 &#160;&#160;&#160;

 <B>Date: </B>19 May 2005<BR>


<P>[Voted into WP at April, 2006 meeting.]</P>

<P>The C standard says in 6.3.2.3, paragraph 4:</P>

<BLOCKQUOTE>

Conversion of a null pointer to another pointer type yields a null
pointer of that type. Any two null pointers shall compare equal.

</BLOCKQUOTE>

<P>C++ appears to be incompatible with the first sentence in only two
areas:</P>

<PRE>
    A *a = 0;
    void *v = a;
</PRE>

<P>C++ (4.10 [conv.ptr] paragraph 2) says nothing about the
value of <TT>v</TT>.</P>

<PRE>
    void *v = 0;
    A *b = (A*)v; // aka static_cast&lt;A*&gt;(v)
</PRE>

<P>C++ (5.2.9 [expr.static.cast] paragraph 10) says nothing about
the value of <TT>b</TT>.</P>

<P><U>Suggested changes</U>:</P>

<OL>

<LI><P>Add the following sentence to 4.10 [conv.ptr]
paragraph 2:</P></LI>

<BLOCKQUOTE>

The null pointer value is converted to the null pointer value of the
destination type.

</BLOCKQUOTE>

<LI><P>Add the following sentence to 5.2.9 [expr.static.cast]
paragraph 10:</P></LI>

<BLOCKQUOTE>

The null pointer value (4.10 [conv.ptr]) is converted
to the null pointer value of the destination type.

</BLOCKQUOTE>

</OL>

<P><B>Proposed resolution (October, 2005):</B></P>

<OL><LI><P>Add the indicated words to 4.10 [conv.ptr]
paragraph 2:</P></LI>

<BLOCKQUOTE>

An rvalue of type &#8220;pointer to <I>cv</I> <TT>T</TT>,&#8221; where
<TT>T</TT> is an object type, can be converted to an rvalue of type &#8220;pointer to
<I>cv</I> <TT>void</TT>&#8221;. The result of converting a &#8220;pointer to
<I>cv</I> <TT>T</TT>&#8221; to a &#8220;pointer
to <I>cv</I> <TT>void</TT>&#8221; points to the start of the storage
location where the object of type <TT>T</TT> resides, as if the object
is a most derived object (1.8 [intro.object]) of
type <TT>T</TT> (that is, not a base class subobject). <SPAN style="font-weight:bold;background-color:#A0FFA0">The null
pointer value is converted to the null pointer value of the
destination type.</SPAN>

</BLOCKQUOTE>

<LI><P>Add the indicated words to 5.2.9 [expr.static.cast]
paragraph 11:</P></LI>

<BLOCKQUOTE>

An rvalue of type &#8220;pointer to <I>cv1</I> <TT>void</TT>&#8221;
can be converted to an rvalue of type &#8220;pointer
to <I>cv2</I> <TT>T</TT>,&#8221; where <TT>T</TT> is an object type
and <i>cv2</i> is the same cv-qualification as, or greater
cv-qualification than, <I>cv1</I>. <SPAN style="font-weight:bold;background-color:#A0FFA0">The null pointer value is
converted to the null pointer value of the destination type.</SPAN> A
value of type pointer to object converted to &#8220;pointer
to <I>cv</I> <TT>void</TT>&#8221; and back, possibly with different
cv-qualification, shall have its original value...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="654"></A><H4>654.
  
Conversions to and from <TT>nullptr_t</TT>
</H4><B>Section: </B>4.10&#160; [conv.ptr]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>7 October 2007<BR>


<P>[Voted into the WP at the June, 2008 meeting as paper N2656.]</P>



<P>In the interest of promoting use of <TT>nullptr</TT> instead of the
integer literal 0 as the null pointer constant, the proposal accepted
by the Committee does not provide for converting a zero-valued integral
constant to type <TT>std::nullptr_t</TT>.  However, this omission reduces
the utility of the feature for use in the library for smart pointers.
In particular, the addition of that conversion (along with a converting
constructor accepting a <TT>std::nullptr_t</TT>) would allow smart
pointers to be used just like ordinary pointers in expressions like:</P>

<PRE>
    if (p == 0) { }
    if (0 == p) { }
    if (p != 0) { }
    if (0 != p) { }
    p = 0;
</PRE>

<P>The existing use of the &#8220;unspecified bool type&#8221; idiom
supports this usage, but being able to use <TT>std::nullptr_t</TT>
instead would be simpler and more elegant.</P>

<P><U>Jason Merrill</U>: I have another reason to support the
conversion as well: it seems to me very odd for <TT>nullptr_t</TT> to
be more restrictive than <TT>void*</TT>.  Anything we can do with an
arbitrary pointer, we ought to be able to do with <TT>nullptr_t</TT>
as well.  Specifically, since there is a standard conversion from
literal 0 to <TT>void*</TT>, and there is a standard conversion
from <TT>void*</TT> to <TT>bool</TT>, <TT>nullptr_t</TT> should
support the same conversions.
</P>

<P>This changes two of the example lines in the proposal as
adopted:</P>

<PRE>
    if (nullptr) ;      //<SPAN style="font-family:Times;font-style:italic"> error, no conversion to </SPAN>bool
    if (nullptr == 0) ; //<SPAN style="font-family:Times;font-style:italic"> error</SPAN>
</PRE>

<P>become</P>

<PRE>
    if (nullptr) ;      //<SPAN style="font-family:Times;font-style:italic"> evaluates to </SPAN>false
    if( nullptr == 0 ); //<SPAN style="font-family:Times;font-style:italic"> evaluates to </SPAN>true
</PRE>

<P>And later,</P>

<PRE>
    char* ch3 = expr ? nullptr : nullptr; //<SPAN style="font-family:Times;font-style:italic"> </SPAN>ch3<SPAN style="font-family:Times;font-style:italic"> is the null pointer value</SPAN>
    char* ch4 = expr ? 0 : nullptr;       //<SPAN style="font-family:Times;font-style:italic"> </SPAN>ch4<SPAN style="font-family:Times;font-style:italic"> is the null pointer value</SPAN>
    int n3 = expr ? nullptr : nullptr;    //<SPAN style="font-family:Times;font-style:italic"> error, </SPAN>nullptr_t<SPAN style="font-family:Times;font-style:italic"> can't be converted to </SPAN>int
    int n4 = expr ? 0 : nullptr;          //<SPAN style="font-family:Times;font-style:italic"> error, </SPAN>nullptr_t<SPAN style="font-family:Times;font-style:italic"> can't be converted to </SPAN>int
</PRE>

<P>I would also allow <TT>reinterpret_cast</TT>
from <TT>nullptr_t</TT> to integral type, with the same semantics as a
<TT>reinterpret_cast</TT> from the null pointer value to integral type.</P>

<P>Basically, I would like <TT>nullptr_t</TT> to act like
a <TT>void*</TT> which is constrained to always
be <TT>(void*)0</TT>.</P>

<BR><BR><HR><A NAME="480"></A><H4>480.
  
Is a base of a virtual base also virtual?
</H4><B>Section: </B>4.11&#160; [conv.mem]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mark Mitchell
 &#160;&#160;&#160;

 <B>Date: </B>18 Oct 2004<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>

<P>When the Standard refers to a virtual base class, it should be
understood to include base classes of virtual bases.  However,
the Standard doesn't actually say this anywhere, so when
4.11 [conv.mem] (for example) forbids casting to a
derived class member pointer from a virtual base class member
pointer, it could be read as meaning:</P>

<PRE>
  struct B {};
  struct D : public B {};
  struct D2 : virtual public D {};

  int B::*p;
  int D::*q;

  void f() {
    static_cast&lt;int D2::*&gt;(p);  // <SPAN style="font-family:Times;font-style:italic">permitted</SPAN>
    static_cast&lt;int D2::*&gt;(q);  // <SPAN style="font-family:Times;font-style:italic">forbidden</SPAN>
  }
</PRE>

<P><B>Proposed resolution (October, 2005):</B></P>

<OL><LI><P>Change 4.11 [conv.mem] paragraph 2 as indicated:</P></LI>

<BLOCKQUOTE>

...If <TT>B</TT> is an inaccessible (clause 11 [class.access]),
ambiguous (10.2 [class.member.lookup]) or virtual (10.1 [class.mi]) base class of <TT>D</TT>, <SPAN style="font-weight:bold;background-color:#A0FFA0">or a base class of a
virtual base class of <TT>D</TT>,</SPAN> a program that necessitates this
conversion is ill-formed...

</BLOCKQUOTE>

<LI><P>Change 5.2.9 [expr.static.cast] paragraph 2 as indicated:</P></LI>

<BLOCKQUOTE>

...and <TT>B</TT> is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">not</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">neither</SPAN> a virtual base class
of <TT>D</TT> <SPAN style="font-weight:bold;background-color:#A0FFA0">nor a base class of a virtual base class
of <TT>D</TT></SPAN>...

</BLOCKQUOTE>

<LI><P>Change 5.2.9 [expr.static.cast] paragraph 9 as indicated:</P></LI>

<BLOCKQUOTE>

...and <TT>B</TT> is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">not</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">neither</SPAN> a virtual base class
of <TT>D</TT> <SPAN style="font-weight:bold;background-color:#A0FFA0">nor a base class of a virtual base class of
<TT>D</TT></SPAN>...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="222"></A><H4>222.
  
Sequence points and lvalue-returning operators
</H4><B>Section: </B>5&#160; [expr]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Andrew Koenig
 &#160;&#160;&#160;

 <B>Date: </B>20 Dec 1999<BR>


<P>[Voted into the WP at the September, 2008 meeting.]</P>



<P>I believe that the committee has neglected to take into
account one of the differences between C and C++ when defining
sequence points.  As an example, consider</P>

<PRE>
    (a += b) += c;
</PRE>

<P>where <TT>a</TT>, <TT>b</TT>, and <TT>c</TT> all have type
<TT>int</TT>.  I believe that this expression has undefined behavior,
even though it is well-formed.  It is not well-formed in C, because +=
returns an rvalue there.  The reason for the undefined behavior is
that it modifies the value of `<TT>a</TT>' twice between sequence
points.</P>

<P>Expressions such as this one are sometimes genuinely useful.
Of course, we could write this particular example as</P>

<PRE>
    a += b; a += c;
</PRE>

<P>but what about</P>

<PRE>
    void scale(double* p, int n, double x, double y) {
        for (int i = 0; i &lt; n; ++i) {
            (p[i] *= x) += y;
        }
    }
</PRE>

<P>All of the potential rewrites involve multiply-evaluating
<TT>p[i]</TT> or unobvious circumlocations like creating references
to the array element.</P>

<P>One way to deal with this issue would be to include built-in operators
in the rule that puts a sequence point between evaluating a function's
arguments and evaluating the function itself.  However, that might
be overkill:  I see no reason to require that in</P>

<PRE>
    x[i++] = y;
</PRE>

<P>the contents of `<TT>i</TT>' must be incremented before the
assignment.</P>

<P>A less stringent alternative might be to say that when a built-in
operator yields an lvalue, the implementation shall not subsequently
change the value of that object as a consequence of that operator.</P>

<P>I find it hard to imagine an implementation that does not do this
already.  Am I wrong?  Is there any implementation out there that
does not `do the right thing' already for <TT>(a += b) += c</TT>?</P>

<P>5.17 [expr.ass] paragraph 1 says,</P>

<BLOCKQUOTE>

The result of the assignment operation is the value stored in the left
operand after the assignment has taken place; the result is an lvalue.

</BLOCKQUOTE>

<P>What is the normative effect of the words "after the assignment has
taken place"?  I think that phrase ought to mean that in addition to
whatever constraints the rules about sequence points might impose on
the implementation, assignment operators on built-in types have the
additional constraint that they must store the left-hand side's new
value before returning a reference to that object as their result.</P>

<P>One could argue that as the C++ standard currently stands, the
effect of <TT>x = y = 0;</TT> is undefined.  The reason is that it
both fetches and stores the value of <TT>y</TT>, and does not fetch
the value of <TT>y</TT> in order to compute its new value.</P>

<P>I'm suggesting that the phrase "after the assignment has taken
place" should be read as constraining the implementation to set
<TT>y</TT> to 0 before yielding the value of <TT>y</TT> as the result
of the subexpression <TT>y = 0</TT>.</P>

<T>Note that this suggestion is different from asking that there be a
sequence point after evaluation of an assignment.  In particular, I am
not suggesting that an order constraint be imposed on any side effects
other than the assignment itself.</T>

<P><U>Francis Glassborow</U>:</P>

<P>My understanding is
that for a single variable:</P>

<OL>
<LI>Multiple read accesses without a write are OK</LI>

<LI>A single read access followed by a single write (of a value
dependant on the read, so that the read MUST happen first) is OK</LI>

<LI>A write followed by an actual read is undefined behaviour</LI>

<LI>Multiple writes have undefined behaviour</LI>
</OL>

<P>It is the 3) that is often ignored because in practice the compiler
hardly ever codes for the read because it already has that value but
in complicated evaluations with a shortage of registers, that is not
always the case. Without getting too close to the hardware, I think we
both know that a read too close to a write can be problematical on
some hardware.</P>

<P>So, in <TT>x = y = 0;</TT>, the implementation must NOT fetch a
value from <TT>y</TT>, instead it has to "know" what that value will
be (easy because it has just computed that in order to know what it
must, at some time, store in <TT>y</TT>).  From this I deduce that
computing the lvalue (to know where to store) and the rvalue to know
what is stored are two entirely independent actions that can occur in
any order commensurate with the overall requirements that both
operands for an operator be evaluated before the operator is.</P>

<P><U>Erwin Unruh</U>:</P>

<P>C
distinguishes between the resulting value of an assignment and putting the
value in store. So in C a compiler might implement the statement
<TT>x=y=0;</TT>
either as <TT>x=0;y=0;</TT> or as <TT>y=0;x=0;</TT>
In C the statement <TT>(x += 5) += 7;</TT> is not allowed because the first <TT>+=</TT> yields
an rvalue which is not allowed as left operand to <TT>+=</TT>.
So in C an assignment is not a sequence of write/read because the result is
not really "read".</P>

<P>In C++ we decided to make the result of assignment an lvalue. In
this case we do not have the option to specify the "value" of the
result. That is just the variable itself (or its address in a
different view). So in C++, strictly speaking, the statement
<TT>x=y=0;</TT> must be implemented as <TT>y=0;x=y;</TT> which makes a
big difference if <TT>y</TT> is declared <TT>volatile</TT>.</P>

<P>Furthermore, I think undefined behaviour should not be the result of a
single mentioning of a variable within an expression. So the statement
<TT>(x +=5) += 7;</TT> should NOT have undefined behaviour.</P>

<P>In my view the semantics could be:</P>

<OL>

<LI>if the result of an assignment is used as an rvalue, its value is that of
the variable after assignment. The actual store takes place before the next
sequence point, but may be before the value is used. This is consistent with
C usage.</LI>

<LI>if the result of an assignment is used as an lvalue to store another
value, then the new value will be stored in the variable before the next
sequence point. It is unspecified whether the first assigned value is stored
intermediately.</LI>

<LI>if the result of an assignment is used as an lvalue to take an address,
that address is given (it doesn't change). The actual store of the new value
takes place before the next sequence point.</LI>

</OL>

<P><U>Jerry Schwarz</U>:</P>

<P>My recollection is different from Erwin's. I am confident that the
intention when we decided to make assignments lvalues was not to
change the semantics of evaluation of assignments. The semantics was
supposed to remain the same as C's.</P>

<P>Ervin seems to assume that because assignments are lvalues, an
assignment's value must be determined by a read of the location. But
that was definitely not our intention. As he notes this has a
significant impact on the semantics of assignment to a volatile
variable.  If Erwin's interpretation were correct we would have no way
to write a volatile variable without also reading it. </P>

<P><U>Lawrence Crowl</U>:</P>

<P>For <TT>x=y=0</TT>, lvalue semantics implies an lvalue to rvalue
conversion on the result of <TT>y=0</TT>, which in turn implies a
read.  If <TT>y</TT> is <TT>volatile</TT>, lvalue semantics implies
both a read and a write on <TT>y</TT>.</P>

<P>The standard apparently doesn't state whether there is a value
dependence of the lvalue result on the completion of the assignment.
Such a statement in the standard would solve the non-volatile C
compatibility issue, and would be consistent with a user-implemented
<TT>operator=</TT>.</P>

<P>Another possible approach is to state that primitive assignment
operators have two results, an lvalue and a corresponding
"after-store" rvalue.  The rvalue result would be used when an rvalue
is required, while the lvalue result would be used when an lvalue is
required.  However, this semantics is unsupportable for user-defined
assignment operators, or at least inconsistent with all
implementations that I know of.  I would not enjoy trying to write
such two-faced semantics.</P>

<P><U>Erwin Unruh</U>:</P>

<P>The intent was for assignments to behave the
same as in C. Unfortunately the change of the result to lvalue did not keep
that. An "lvalue of type int" has no "int" value! So there is a difference
between intent and the standard's wording.</P>

<P>So we have one of several choices:</P>

<UL>
<LI>live with the incompatibility (and the problems it has for volatile
variables)</LI>

<LI>make the result of assignment an rvalue (only builtin-assignment, maybe
only for builtin types), which makes some presently valid programs
invalid</LI>

<LI>introduce "two-face semantics" for builtin assignments, and clarify the
sequence problematics</LI>

<LI>make a special rule for assignment to a volatile lvalue of builtin
type</LI>

</UL>

<P>I think the last one has the least impact on existing programs, but it is an
ugly solution.</P>

<P><U>Andrew Koenig</U>:</P>
<P>Whatever we may have intended, I do not think that there is any clean
way of making
<PRE>
    volatile int v;
    int i;

    i = v = 42;
</PRE>
have the same semantics in C++ as it does in C.  Like it or not, the
subexpression <TT>v = 42</TT> has the type ``reference to volatile int,''
so if this statement has any meaning at all, the meaning must be to store 42
in <TT>v</TT> and then fetch the value of <TT>v</TT> to assign it to i.</P>

<P>Indeed, if <TT>v</TT> is volatile, I cannot imagine a
conscientious programmer
writing a statement such as this one.  Instead, I would expect to see
<PRE>
    v = 42;
    i = v;
</PRE>
if the intent is to store 42 in <TT>v</TT> and then fetch the (possibly
changed) value of <TT>v</TT>, or
<PRE>
    v = 42;
    i = 42;
</PRE>
if the intent is to store 42 in both <TT>v</TT> and <TT>i</TT>.</P>

<P>What I do want is to ensure that expressions such as ``<TT>i = v = 42</TT>''
have well-defined semantics, as well as expressions such as
<TT>(i = v) = 42</TT> or, more realistically, <TT>(i += v) += 42</TT> .</P>

<P>I wonder if the following resolution is sufficient:</P>

<P>Append to 5.17 [expr.ass] paragraph 1:</P>
<BLOCKQUOTE>
There is a sequence point between assigning the new value to
the left operand and yielding the result of the assignment
expression.
</BLOCKQUOTE>

<P>I believe that this proposal achieves my desired effect of not
constraining when <TT>j</TT> is incremented in <TT>x[j++] = y</TT>,
because I don't
think there is a constraint on the relative order of incrementing <TT>j</TT>
and executing the assignment.  However, I do think it allows expressions
such as <TT>(i += v) += 42</TT>, although with different semantics from C if
<TT>v</TT> is volatile.</P>

<P><B>Notes on 10/01 meeting:</B></P>

<P>There was agreement that adding a sequence point is probably the
right solution.</P>

<P><B>Notes from the 4/02 meeting:</B></P>

<P>The working group reaffirmed the sequence-point solution, but
we will look for any counter-examples where efficiency would be harmed.</P>

<P>For drafting, we note that <TT>++x</TT> is defined in 5.3.2 [expr.pre.incr] as equivalent to <TT>x+=1</TT> and is therefore
affected by this change.  <TT>x++</TT> is not affected. Also, we
should update any list of all sequence points.</P>

<P><B>Notes from October 2004 meeting:</B></P>

<P>Discussion centered around whether a sequence point &#8220;between
assigning the new value to the left operand and yielding the result of
the expression&#8221; would require completion of all side effects of
the operand expressions before the value of the assignment expression
was used in another expression.  The consensus opinion was that it
would, that this is the definition of a sequence point.  Jason Merrill
pointed out that adding a sequence point after the assignment is
essentially the same as rewriting</P>

<PRE>
    b += a
</PRE>

<P>as</P>

<PRE>
    b += a, b
</PRE>

<P>Clark Nelson expressed a desire for something like a
&#8220;weak&#8221; sequence point that would force the assignment to
occur but that would leave the side effects of the operands
unconstrained.  In support of this position, he cited the following
expression:</P>

<PRE>
    j = (i = j++)
</PRE>

<P>With the proposed addition of a full sequence point after the
assignment to <TT>i</TT>, the net effect is no change to <TT>j</TT>.
However, both g++ and MSVC++ behave differently: if the previous value
of <TT>j</TT> is 5, the value of the expression is 5 but <TT>j</TT>
gets the value 6.</P>

<P>Clark Nelson will investigate alternative approaches and report
back to the working group.</P>

<P><B>Proposed resolution (March, 2008):</B></P>

<P>See <A HREF="
     cwg_defects.html#637">issue 637</A>.</P>

<BR><BR><HR><A NAME="351"></A><H4>351.
  
Sequence point error: unspecified or undefined?
</H4><B>Section: </B>5&#160; [expr]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Andrew Koenig
 &#160;&#160;&#160;

 <B>Date: </B>23 April 2002<BR>


<P>[Voted into WP at March 2004 meeting.]</P>



<P>I have found what looks like a bug in clause 5 [expr],
paragraph 4:</P>
<BLOCKQUOTE>
   Between the previous and next sequence point a scalar object shall
   have its stored value modified at most once by the evaluation of an
   expression.  Furthermore, the prior value shall be accessed only to
   determine the value to be stored.  The requirements of this
   paragraph shall be met for each allowable ordering of the
   subexpressions of a full expression; otherwise the behavior is
   undefined.  Example:
<PRE>
        i = v[i++];                     // the behavior is unspecified
        i = 7, i++, i++;                // i becomes 9

        i = ++i + 1;                    // the behavior is unspecified
        i = i + 1;                      // the value of i is incremented
</PRE>
   --end example]
</BLOCKQUOTE>

<P>So which is it, unspecified or undefined?</P>

<P><B>Notes from October 2002 meeting:</B></P>

<P>We should find out what C99 says and do the same thing.</P>

<P><B>Proposed resolution (April 2003):</B></P>

<P>Change the example in clause 5 [expr], paragraph 4 from</P>

<BLOCKQUOTE>
[<I>Example:</I>
<PRE>
i = v[i++];                     //<I>  the behavior is unspecified</I>
i = 7, i++, i++;                //<I>   </I>i<I>  becomes  </I>9

i = ++i + 1;                    //<I>  the behavior is unspecified</I>
i = i + 1;                      //<I>  the value of  </I>i<I>  is incremented</I>
</PRE>
--- end example]
</BLOCKQUOTE>

<P>to (changing "unspecified" to "undefined" twice)</P>

<BLOCKQUOTE>
[<I>Example:</I>
<PRE>
i = v[i++];                     //<I>  the behavior is undefined</I>
i = 7, i++, i++;                //<I>   </I>i<I>  becomes  </I>9

i = ++i + 1;                    //<I>  the behavior is undefined</I>
i = i + 1;                      //<I>  the value of  </I>i<I>  is incremented</I>
</PRE>
--- end example]
</BLOCKQUOTE>

<BR><BR><HR><A NAME="451"></A><H4>451.
  
Expressions with invalid results and ill-formedness
</H4><B>Section: </B>5&#160; [expr]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Gennaro Prota
 &#160;&#160;&#160;

 <B>Date: </B>19 Jan 2004<BR>


<P>[Voted into WP at October 2005 meeting.]</P>

<P>Clause 5 [expr] par. 5 of the standard says:
<BLOCKQUOTE>
If during the evaluation
of an expression, the result is not mathematically defined or not in
the range of representable values for its type, the behavior is
undefined, unless such an expression is a constant expression (5.19),
in which case the program is ill-formed.
</BLOCKQUOTE>

<P>Well, we do know that except in some contexts (e.g. controlling
expression of a #if, array bounds), a compiler is not required to
evaluate constant-expressions in compile time, right?</P>

<P>Now, let us consider, the following simple snippet:</P>
<PRE>
  if (a &amp;&amp; 1/0)
      ...
</PRE>
with a, to fix our attention, being *not* a constant expression. The
quote above seems to say that since 1/0 is a constant
(sub-)expression, the program is ill-formed. So, is it the intent that
such ill-formedness is diagnosable at run-time? Or is it the intent
that the above gives undefined behavior (if 1/0 is evaluated) and is
not ill-formed?</P>

<P>I think the intent is actually the latter, so I propose the following
rewording of the quoted section:</P>
<BLOCKQUOTE>
  If an expression is evaluated but its result is not mathematically
   defined or not in the range of representable values
   for its type the behavior is undefined, unless such an expression
   is a constant expression (5.19) <SPAN style="font-weight:bold;background-color:#A0FFA0">that shall be evaluated during
   program translation</SPAN>, in which case the program is ill-formed.
</BLOCKQUOTE>

<P><B>Rationale (March, 2004):</B></P>

<P>We feel the standard is clear enough.  The quoted sentence
does begin "If during the evaluation of an expression, ..."
so the rest of the sentence does not apply to an expression
that is not evaluated.</P>

<P><B>Note (September, 2004):</B></P>

<P>Gennaro Prota feels that the CWG missed the point of his
original comment: unless a constant expression appears in a
context that <I>requires</I> a constant expression, an
implementation is permitted to defer its evaluation to runtime.
An evaluation that fails at runtime cannot affect the
well-formedness of the program; only expressions that are
evaluated at compile time can make a program ill-formed.</P>

<P>The status has been reset to &#8220;open&#8221; to allow
further discussion.</P>

<P><B>Proposed resolution (October, 2004):</B></P>

<P>Change paragraph 5 of 5 [expr] as
indicated:</P>

<BLOCKQUOTE>

If during the evaluation of an expression, the result is not
mathematically defined or not in the range of representable
values for its type, the behavior is undefined, unless such an
expression <SPAN style="text-decoration:line-through;background-color:#FFA0A0">is a constant expression</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">appears where an
integral constant expression is required</SPAN> (5.19 [expr.const]), in which case the program is ill-formed.

</BLOCKQUOTE>
<BR><BR><HR><A NAME="122"></A><H4>122.
  
<I>template-id</I>s as <I>unqualified-id</I>s
</H4><B>Section: </B>5.1.1&#160; [expr.prim.general]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>3 June 1999<BR>



<P>[Moved to DR at 10/01 meeting.]</P>



<P>5.1.1 [expr.prim.general]
 paragraph 11 reads,</P>

<BLOCKQUOTE>
A <I>template-id</I> shall be used as an <I>unqualified-id</I> only
as specified in
14.7.2 [temp.explicit]
,
14.7 [temp.spec]
, and
14.5.5 [temp.class.spec]
.
</BLOCKQUOTE>

<P>What uses of <I>template-id</I>s
as <I>unqualified-id</I>s is this supposed to prevent?  And is the
list of referenced sections correct/complete?  For instance,
what about 14.8.1 [temp.arg.explicit],
"Explicit template argument specification?"
Does its absence from the list in
5.1.1 [expr.prim.general] paragraph 11 mean that
"<TT>f&lt;int&gt;()</TT>" is ill-formed?</P>

<P>This is even more confusing when you recall that <I>unqualified-id</I>s
are contained in <I>qualified-id</I>s:</P>

<BLOCKQUOTE>
    <I>qualified-id</I>:
        <TT>::</TT><SUB>opt</SUB>&#160;<I>nested-name-specifier</I>&#160;<TT>template</TT><SUB>opt</SUB>&#160;<I>unqualified-id</I>
</BLOCKQUOTE>

<P>Is the wording intending to say "used as an <I>unqualified-id</I>
that is not part of a <I>qualified-id</I>?"  Or something else?</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>Remove the referenced sentence altogether.</P>

<BR><BR><HR><A NAME="125"></A><H4>125.
  
Ambiguity in <TT>friend</TT> declaration syntax
</H4><B>Section: </B>5.1.1&#160; [expr.prim.general]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Martin von Loewis
 &#160;&#160;&#160;

 <B>Date: </B>7 June 1999<BR>



<P>[Voted into WP at March 2004 meeting.]</P>

<P>The example below is ambiguous.</P>

<PRE>
    struct A{
      struct B{};
    };

    A::B C();

    namespace B{
      A C();
    }

    struct Test {
      friend A::B ::C();
    };
</PRE>

Here, it is not clear whether the friend declaration denotes
<TT>A B::C()</TT> or <TT>A::B C()</TT>, yet the standard does not resolve this
ambiguity.

<P>The ambiguity arises since both the <I>simple-type-specifier</I>
(7.1.6.2 [dcl.type.simple]
 paragra 1) and an
<I>init-declararator</I>
(8 [dcl.decl]
 paragraph 1)
contain an optional <TT>::</TT> and an optional
<I>nested-name-specifier</I>
(5.1.1 [expr.prim.general]
 paragraph 1).
Therefore, two different ways to analyse this code are
possible:</P>

<BLOCKQUOTE>
<I>simple-type-specifier</I> = <TT>A::B</TT><BR>
<I>init-declarator</I> = <TT>::C()</TT><BR>
<I>simple-declaration</I> = <TT>friend A::B ::C();</TT>
</BLOCKQUOTE>

or

<BLOCKQUOTE>
<I>simple-type-specifier</I> = <TT>A</TT><BR>
<I>init-declarator</I> = <TT>::B::C()</TT><BR>
<I>simple-declaration</I> = <TT>friend A ::B::C();</TT>
</BLOCKQUOTE>

Since it is a friend declaration, the init-declarator may be
qualified, and start with a global scope.

<P>Suggested Resolution: In the definition of
<I>nested-name-specifier</I>, add a
sentence saying that a <TT>::</TT> token immediately following a
<I>nested-name-specifier</I> is always considered as part of the
<I>nested-name-specifier</I>. Under this interpretation, the example is
ill-formed, and should be corrected as either</P>

<PRE>
    friend A (::B::C)();   //or
    friend A::B (::C)();
</PRE>

<P>An alternate suggestion &#8212; changing
7.1 [dcl.spec]
 to say that</P>

<BLOCKQUOTE>
The longest sequence of <B>tokens</B> that could possibly be a type
name is taken as the <I>decl-specifier-seq</I> of a <I>declaration</I>.
</BLOCKQUOTE>

<P>&#8212; is undesirable because it would make the example well-formed
rather than requiring the user to disambiguate the declaration
explicitly.</P>

<P><B>Proposed resolution (04/01):</B></P>

<P><B>(See below for problem with this, from 10/01 meeting.)</B></P>

<P>In 5.1.1 [expr.prim.general] paragraph 7,</P>

<OL>

<LI><P>Before the grammar for <I>qualified-id</I>, start a new
paragraph 7a with the text </P>

<BLOCKQUOTE>

A <I>qualified-id</I> is an <I>id-expression</I> that contains the
scope resolution operator <TT>::</TT>.

</BLOCKQUOTE>

</LI>

<LI><P>Following the grammar fragment, insert the following:</P>

<BLOCKQUOTE>

<P>The longest sequence of tokens that could form a <I>qualified-id</I>
constitutes a single <I>qualified-id</I>.  [<I>Example:</I></P>

<PRE>
    // classes C, D; functions F, G, namespace N; non-class type T
    friend C ::D::F();   // ill-formed, means friend (C::D::F)();
    friend C (::D::F)(); // well-formed
    friend N::T ::G();   // ill-formed, means friend (N::T::G)();
    friend N::T (::G)(); // well-formed
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

</LI>

<LI><P>Start a new paragraph 7b following the example.</P></LI>

</OL>

<P>(This resolution depends on that of
<A HREF="
     cwg_defects.html#215">issue 215</A>.)</P>

<P><B>Notes from 10/01 meeting:</B></P>

<P>It was pointed out that the proposed resolution does not deal with
cases like <TT>X::Y</TT> where <TT>X</TT> is a type but not a class type.
The working group reaffirmed its decision that the disambiguation should
be syntactic only, i.e., it should depend only on whether or not the name is a
type.</P>

<U>Jason Merrill</U>
:

<P>At the Seattle meeting, I suggested that a solution might be to change the
<I>class-or-namespace-name</I> in the <I>nested-name-specifier</I>
rule to just be
"identifier"; there was some resistance to this idea.  FWIW, I've tried
this in g++.  I had to revise the idea so that only the second and
subsequent names were open to being any identifier, but that seems to work
just fine.</P>

<P>So, instead of</P>

<UL><I>nested-name-specifier</I>:
<UL><I>class-or-namespace-name</I> <TT>::</TT> <I>nested-name-specifier</I><SUB>opt</SUB>
<BR><I>class-or-namespace-name</I> <TT>::</TT> <I>template nested-name-specifier</I>
</UL>
</UL>

<P>it would be</P>

<UL><I>nested-name-specifier</I>:
<UL><I>type-or-namespace-name</I> <TT>::</TT> (per issue 215)
<BR><I>nested-name-specifier</I> <I>identifier</I> <TT>::</TT>
<BR><I>nested-name-specifier</I> <TT>template</TT> <I>template-id</I> <TT>::</TT>
</UL>
</UL>

<P>Or some equivalent but right-associative formulation, if people feel that's
important, but it seems irrelevant to me.</P>

<P><U>Clark Nelson</U>
:</P>

<P>Personally, I prefer the left-associative rule. I think it makes it easier
to understand. I was thinking about this production a lot at the meeting,
considering also some issues related to <A HREF="
     cwg_defects.html#301">301</A>.
My formulation was getting kind
of ugly, but with a left-associative rule, it gets a lot nicer.</P>

<P>Your proposal isn't complete, however, as it doesn't allow template
arguments without an explicit template keyword. You probably want to add an
alternative for:</P>

<UL><I>nested-name-specifier type-or-namespace-name</I> <TT>::</TT>
</UL>

<P>There is admittedly overlap between this alternative and</P>

<UL><I>nested-name-specifier identifier</I> <TT>::</TT>
</UL>

<P>but I think they're both necessary.</P>

<P><B>Notes from the 4/02 meeting:</B></P>

<P>The changes look good.  Clark Nelson will merge the two proposals
to produce a single proposed resolution.</P>

<P><B>Proposed resolution (April 2003):</B></P>

<P><I>nested-name-specifier</I> is currently defined in
5.1.1 [expr.prim.general] paragraph 7 as:
</P>

<UL>
<I>nested-name-specifier:</I>
<UL>
<I>class-or-namespace-name</I> <TT>::</TT> <I>nested-name-specifier<sub>opt</sub></I><BR>
<I>class-or-namespace-name</I> <TT>:: template</TT> <I>nested-name-specifier</I>
</UL>
<I>class-or-namespace-name:</I>
<UL>
<I>class-name</I><BR>
<I>namespace-name</I>
</UL>
</UL>

<P>
The proposed definition is instead:
</P>

<UL>
<I>nested-name-specifier:</I>
<UL>
<I>type-name</I> <TT>::</TT><BR>
<I>namespace-name</I> <TT>::</TT><BR>
<I>nested-name-specifier</I> <I>identifier</I> <TT>::</TT><BR>
<I>nested-name-specifier</I> <TT>template</TT><I><sub>opt</sub> template-id</I> <TT>::</TT>
</UL>
</UL>
<P>
<A HREF="
     cwg_defects.html#215">Issue 215</A>
is addressed by using <I>type-name</I> instead of <I>class-name</I> in the first alternative.
Issue 125 (this issue)
is addressed by using <I>identifier</I> instead of anything more specific in the third alternative.
Using left association instead of right association helps eliminate the need for <I>class-or-namespace-name</I> (or <I>type-or-namespace-name</I>, as suggested for <A HREF="
     cwg_defects.html#215">issue 215</A>).
</P>

<P>
It should be noted that this formulation also rules out the possibility of <TT>A::template B::</TT>, i.e. using the <TT>template</TT> keyword without any template arguments.
I think this is according to the purpose of the <TT>template</TT> keyword, and that the former rule allowed such a construct only because of the difficulty of formulation of a right-associative rule that would disallow it.
But I wanted to be sure to point out this implication.
</P>

<P><B>Notes from April 2003 meeting:</B></P>

<P>See also <A HREF="
     cwg_defects.html#96">issue 96</A>.</P>

<P>The proposed change resolves only part of
<A HREF="
     cwg_defects.html#215">issue 215</A>.</P>

<BR><BR><HR><A NAME="113"></A><H4>113.
  
Visibility of called function
</H4><B>Section: </B>5.2.2&#160; [expr.call]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Christophe de Dinechin
 &#160;&#160;&#160;

 <B>Date: </B>5 May 1999<BR>



<P>[Moved to DR at 10/01 meeting.]</P>



<P><B>Christophe de Dinechin:</B>
In 5.2.2 [expr.call]
, paragraph 2 reads:</P>

<BLOCKQUOTE>
If no declaration of the called function is visible from the scope  of
the call the program is ill-formed.
</BLOCKQUOTE>

I think nothing there or in the previous paragraph indicates that  
this does not apply to calls through pointer or virtual calls.

<P><B>Mike Miller:</B>
"The called function" is unfortunate phraseology; it makes it
sound as if it's referring to the function actually called, as
opposed to the identifier in the postfix expression.  It's
wrong with respect to Koenig lookup, too (the declaration need
not be visible if it can be found in a class or namespace
associated with one or more of the arguments).</P>

<P>In fact, this paragraph should be a note.  There's a general
rule that says you have to find an unambiguous declaration of
any name that is used
(3.4 [basic.lookup]
 paragraph 1);
the only reason this paragraph
is here is to contrast with C's implicit declaration of called
functions.</P>

<P><B>Proposed resolution:</B></P>
Change section 5.2.2 [expr.call] paragraph 2 from:
<BLOCKQUOTE>If no declaration of the called function is visible from the
scope of the call the program is ill-formed.</BLOCKQUOTE>
to:
<BLOCKQUOTE>[<I>Note:</I> if a function or member function name is used,
and name lookup (3.4 [basic.lookup]) does not find a
declaration of that name,
the program is ill-formed. No function is implicitly declared by such
a call. ]</BLOCKQUOTE>

<P>(See also <A HREF="
     cwg_defects.html#218">issue 218</A>.)</P>

<BR><BR><HR><A NAME="118"></A><H4>118.
  
Calls via pointers to virtual member functions
</H4><B>Section: </B>5.2.2&#160; [expr.call]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Martin O'Riordan
 &#160;&#160;&#160;

 <B>Date: </B>17 May 1999<BR>



<P>[Voted into the WP at the June, 2008 meeting.]</P>



<P><U>Martin O'Riordan:</U>
Having gone through all the relevant references in the IS, it is not
conclusive that a call via a pointer to a virtual member function
is polymorphic at all, and could legitimately be
interpreted as being static.</P>

<P>Consider 5.2.2 [expr.call]
 paragraph 1:</P>
<BLOCKQUOTE>

The function called in a member function call is normally selected
according to the static type of the object expression (clause
10 [class.derived]
), but if that function is
<TT>virtual</TT> and is not specified using a <I>qualified-id</I> then
the function actually called will be the final overrider
(10.3 [class.virtual]
) of the selected
function in the dynamic type of the object expression.

</BLOCKQUOTE>
Here it is quite specific that you get the polymorphic call only if you use
the unqualified syntax.  But, the address of a member function is "always"
taken using the qualified syntax, which by inference would indicate that
call with a PMF is static and not polymorphic!  Not what was intended.

<P>Yet other references such as
5.5 [expr.mptr.oper]
 paragraph 4:</P>
<BLOCKQUOTE>

If the dynamic type of the object does not contain the member to which
the pointer refers, the behavior is undefined.

</BLOCKQUOTE>
indicate that the opposite may have been intended, by stating that it is the
dynamic type and not the static type that matters.  Also,
5.5 [expr.mptr.oper]
 paragraph 6:
<BLOCKQUOTE>

If the result of <TT>.*</TT> or <TT>-&gt;*</TT> is a function,
then that result can be used
only as the operand for the function
call operator (). [<I>Example:</I>
<PRE>
        (ptr_to_obj-&gt;*ptr_to_mfct)(10);
</PRE>
calls the member function denoted by <TT>ptr_to_mfct</TT>
for the object pointed
to by <TT>ptr_to_obj</TT>. ]

</BLOCKQUOTE>

which also implies that it is the object pointed to that determines both the
validity of the expression (the static type of '<TT>ptr_to_obj</TT>'
may not have a
compatible function) and the implicit (polymorphic) meaning.   Note too,
that this is stated in the non-normative example text.

<P><U>Andy Sawyer:</U>
Assuming the resolution is what I've assumed it is for the
last umpteen years (i.e. it does the polymorphic thing), then
the follow on to that is "Should there also be a way of selecting
the non-polymorphic behaviour"?</P>

<P><U>Mike Miller:</U>
It might be argued that the current wording of
5.2.2 [expr.call]
 paragraph 1 does give
polymorphic behavior to simple calls via pointers to members.
(There is no <I>qualified-id</I> in <TT>obj.*pmf</TT>, and the IS says
that if the function is not specified using a <I>qualified-id</I>, the
final overrider will be called.)  However, it clearly says the wrong
thing when the pointer-to-member itself is specified using a
<I>qualified-id</I> (<TT>obj.*X::pmf</TT>).</P>

<P><U>Bill Gibbons:</U>
The phrase <I>qualified-id</I> in
5.2.2 [expr.call]
 paragraph 1 refers to the
<I>id-expression</I> and not to the "pointer-to-member expression"
earlier in the paragraph:</P>

<BLOCKQUOTE>
For a member function call, the postfix expression shall be an
implicit (9.3.1 [class.mfct.non-static]
,
9.4 [class.static]
) or explicit class member
access (5.2.5 [expr.ref]
) whose
<I>id-expression</I> is a function member name, or a pointer-to-member
expression (5.5 [expr.mptr.oper]
) selecting
a function member.
</BLOCKQUOTE>

<P><U>Mike Miller:</U>
To be clear, here's an example:</P>

<PRE>
    struct S {
	virtual void f();
    };
    void (S::*pmf)();
    void g(S* sp) {
	sp-&gt;f();         // 1: polymorphic
	sp-&gt;S::f();      // 2: non-polymorphic
	(sp-&gt;S::f)();    // 3: non-polymorphic
	(sp-&gt;*pmf)();    // 4: polymorphic
	(sp-&gt;*&amp;S::f)();  // 5: polymorphic
    }
</PRE>

<P><B>Notes from October 2002 meeting:</B></P>

<P>This was moved back to open for lack of a champion.  Martin O'Riordan
is not expected to be attending meetings.</P>

<P><B>Proposed resolution (February, 2008):</B></P>

<OL><LI><P>Change 5.2.2 [expr.call] paragraph 1 as follows:</P>

<BLOCKQUOTE>

... For a member function call, the postfix expression shall be an
implicit (9.3.1 [class.mfct.non-static], 9.4 [class.static]) or
explicit class member access (5.2.5 [expr.ref]) whose
<I>id-expression</I> is a function member name, or a pointer-to-member
expression (5.5 [expr.mptr.oper]) selecting a function member<SPAN style="text-decoration:line-through;background-color:#FFA0A0">.
The first expression in the postfix expression is then called the
<I>object expression</I>, and</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">;</SPAN> the call is as a member of
the object pointed to or referred to <SPAN style="font-weight:bold;background-color:#A0FFA0">by the object expression
(5.2.5 [expr.ref], 5.5 [expr.mptr.oper])</SPAN>. In the
case of an implicit class member access, the implied object is the one
pointed to by <TT>this</TT>.  [<I>Note:</I> a member function call of
the form <TT>f()</TT> is interpreted as <TT>(*this).f()</TT> (see
9.3.1 [class.mfct.non-static]). &#8212;<I>end note</I>] If a function or
member function name is used, the name can be overloaded (clause
13 [over]), in which case the appropriate function shall
be selected according to the rules in 13.3 [over.match]. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The function called in a member function call is
normally selected according to the static type of the object
expression (clause 10 [class.derived]), but if that function
is <TT>virtual</TT> and is not specified using a <I>qualified-id</I>
then the function actually called will be the final overrider
(10.3 [class.virtual]) of the selected function in the dynamic
type of the object expression</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">If the selected function is
non-virtual, or if the <I>id-expression</I> in the class member access
expression is a <I>qualified-id</I>, that function is called.
Otherwise, its final overrider (10.3 [class.virtual]) in the
dynamic type of the object expression is called.</SPAN> ...

</BLOCKQUOTE>
</LI>

<LI><P>Change 5.5 [expr.mptr.oper] paragraph 4 as follows:</P>

<BLOCKQUOTE>

<SPAN style="font-weight:bold;background-color:#A0FFA0">The first operand is called the <I>object expression</I>.</SPAN> If
the dynamic type of the object <SPAN style="font-weight:bold;background-color:#A0FFA0">expression</SPAN> does not contain the
member to which the pointer refers, the behavior is undefined.

</BLOCKQUOTE>
</LI>
</OL>

<BR><BR><HR><A NAME="506"></A><H4>506.
  
Conditionally-supported behavior for non-POD objects passed to ellipsis
</H4><B>Section: </B>5.2.2&#160; [expr.call]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>14 Apr 2005<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>

<P>The current wording of 5.2.2 [expr.call] paragraph 7
states:</P>

<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 <TT>va_arg</TT>
(18.10 [support.runtime]).  The lvalue-to-rvalue
(4.1 [conv.lval]), array-to-pointer
(4.2 [conv.array]), and function-to-pointer
(4.3 [conv.func]) 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 [class]), the behavior is undefined.

</BLOCKQUOTE>

<P>Paper J16/04-0167=WG21 N1727 suggests that passing a non-POD
object to ellipsis be ill-formed.  In discussions at the
Lillehammer meeting, however, the CWG felt that the newly-approved
category of conditionally-supported behavior would be more
appropriate.</P>

<P><B>Proposed resolution (October, 2005):</B></P>

<P>Change 5.2.2 [expr.call] paragraph 7 as indicated:</P>

<BLOCKQUOTE>

...After these conversions, if the argument does not have arithmetic,
enumeration, pointer, pointer to member, or class type, the program is
ill-formed. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">If the argument has a non-POD class type (clause 9),
the behavior is undefined.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Passing an argument of non-POD class
type (clause 9) with no corresponding parameter is
conditionally-supported, with implementation-defined semantics.</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="634"></A><H4>634.
  
Conditionally-supported behavior for non-POD objects passed to ellipsis redux
</H4><B>Section: </B>5.2.2&#160; [expr.call]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Howard Hinnant
 &#160;&#160;&#160;

 <B>Date: </B>6 Jun 2007<BR>


<P>[Voted into the WP at the September, 2008 meeting.]</P>



<P><A HREF="
     cwg_defects.html#506">Issue 506</A> changed passing a non-POD
class type to an ellipsis from undefined behavior to
conditionally-supported behavior.  As a result, an implementation could
conceivably reject code like the following:</P>

<PRE>
    struct two {char _[2];};

    template &lt;class From, class To&gt;
    struct is_convertible
    {
    private:
            static From f;

            template &lt;class U&gt; static char test(const U&amp;);
            template &lt;class U&gt; static two test(...);
    public:
            static const bool value = sizeof(test&lt;To&gt;(f)) == 1;
    };

    struct A
    {
         A();
    };

    int main()
    {
         const bool b = is_convertible&lt;A,int&gt;::value;  // b == false
    }
</PRE>

<P>This technique has become popular in template metaprogramming,
and no non-POD object is actually passed at runtime.  Concepts
will eliminate much (perhaps not all) of the need for this
kind of programming, but legacy code will persist.</P>

<P>Perhaps this technique should be officially supported by allowing
implementations to reject passing a non-POD type to ellipsis only if
it appears in a potentially-evaluated expression?</P>

<P><B>Notes from the July, 2007 meeting:</B></P>

<P>The CWG agreed with the suggestion to allow such calls in
unevaluated contexts.</P>

<P><B>Proposed resolution (September, 2007):</B></P>

<P>Change 5.2.2 [expr.call] paragraph 7 as follows:</P>

<BLOCKQUOTE>

...Passing <SPAN style="text-decoration:line-through;background-color:#FFA0A0">an</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">a potentially-evaluated</SPAN> argument of
non-trivial class type (clause 9 [class]) with no
corresponding parameter is conditionally-supported, with
implementation-defined semantics...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="466"></A><H4>466.
  
cv-qualifiers on pseudo-destructor type
</H4><B>Section: </B>5.2.4&#160; [expr.pseudo]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mark Mitchell
 &#160;&#160;&#160;

 <B>Date: </B>18 Mar 2004<BR>


<P>[Voted into WP at April, 2006 meeting.]</P>

<P>5.2.4 [expr.pseudo] paragraph 2 says both:
<BLOCKQUOTE>
  The type designated by the pseudo-destructor-name shall be the same
  as the object type.
</BLOCKQUOTE>
and also:
<BLOCKQUOTE>
  The cv-unqualified versions of the object type and of the type
  designated by the pseudo-destructor-name shall be the same type.
</BLOCKQUOTE>
Which is it?  "The same" or "the same up to cv-qualifiers"?  The
second sentence is more generous than the first.  Most compilers seem
to implement the less restrictive form, so I guess that's what I think
we should do.</P>

<P>See also issues <A HREF="
     cwg_defects.html#305">305</A> and
<A HREF="
     cwg_active.html#399">399</A>.</P>

<P><B>Proposed resolution (October, 2005):</B></P>

<P>Change 5.2.4 [expr.pseudo] paragraph 2 as follows:</P>

<BLOCKQUOTE>

The left-hand side of the dot operator shall be of scalar type. The
left-hand side of the arrow operator shall be of pointer to scalar
type. This scalar type is the object type. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The type designated by the
<I>pseudo-destructor-name</I> shall be the same as the object
type.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">The cv-unqualified versions of
the object type and of the type designated by the
<I>pseudo-destructor-name</I> shall be the same type.</SPAN> Furthermore,
the two <I>type-name</I>s in a <I>pseudo-destructor-name</I> of the
form

<UL>
<TT>::</TT><I><SUB>opt</SUB> nested-name-specifier<SUB>opt</SUB> type-name </I><TT>::~</TT><I> type-name</I>
</UL>

shall designate the same scalar type. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The cv-unqualified versions of
the object type and of the type designated by the
<I>pseudo-destructor-name</I> shall be the same type.</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="421"></A><H4>421.
  
Is rvalue.field an rvalue?
</H4><B>Section: </B>5.2.5&#160; [expr.ref]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Gabriel Dos Reis
 &#160;&#160;&#160;

 <B>Date: </B>15 June 2003<BR>


<P>[Voted into WP at March 2004 meeting.]</P>



<P>Consider</P>
<PRE>
  typedef
    struct {
      int a;
    } A;

  A f(void)
  {
    A a;
    return a;
  }

  int main(void)
  {
    int* p = &amp;f().a;   // #1
  }
</PRE>
<P>Should #1 be rejected?  The standard is currently silent.</P>

<P><U>Mike Miller:</U>
I don't believe the Standard is silent on this.  I will agree that the
wording of 5.2.5 [expr.ref] paragraph 4 bullet 2 is
unfortunate, as it is subject to misinterpretation.  It reads,
<BLOCKQUOTE>
    If E1 is an lvalue, then E1.E2 is an lvalue.
</BLOCKQUOTE>
The intent is, "and not otherwise." </P>

<P><B>Notes from October 2003 meeting:</B></P>

<P>We agree the reference should be an rvalue, and a change along
the lines of that recommended by Mike Miller is reasonable.</P>

<P><B>Proposed Resolution (October 2003):</B></P>

<P>Change the second bullet of 5.2.5 [expr.ref]
paragraph 4 to read: </P>
<BLOCKQUOTE>
If E1 is an lvalue, then E1.E2 is an lvalue<SPAN style="font-weight:bold;background-color:#A0FFA0">; otherwise, it is an rvalue</SPAN>.
</BLOCKQUOTE>

<BR><BR><HR><A NAME="492"></A><H4>492.
  
<TT>typeid</TT> constness inconsistent with example
</H4><B>Section: </B>5.2.8&#160; [expr.typeid]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Ron Natalie
 &#160;&#160;&#160;

 <B>Date: </B>15 Dec 2004<BR>


<P>[Voted into WP at April, 2006 meeting.]</P>

<P>There is an inconsistency between the normative text in
section 5.2.8 [expr.typeid] and
the example that follows.</P>

<P>Here is the relevant passage (starting with paragraph 4):</P>

<BLOCKQUOTE>

<P>
When <TT>typeid</TT> is applied to a <I>type-id</I>, the result
refers to a <TT>std::type_info</TT> object representing the type of the
<I>type-id</I>. If the type of the <I>type-id</I> is a reference
type, the result of the <TT>typeid</TT> expression refers to a
<TT>std::type_info</TT> object representing the referenced type.
</P>

<P>
The top-level cv-qualifiers of the lvalue expression or the
<I>type-id</I> that is the operand of <TT>typeid</TT> are always
ignored.
</P>

</BLOCKQUOTE>

<P>and the example:</P>

<PRE>
    typeid(D) == typeid(const D&amp;); // yields true
</PRE>

<P>
The second paragraph above says the &#8220;<I>type-id</I> that is
the operand&#8221;.  This would be <TT>const D&amp;</TT>.  In
this case, the <TT>const</TT> is not at the top-level (i.e.,
applied to the operand itself).
</P>

<P>By a strict reading, the above should yield <TT>false</TT>.</P>

<P>
My proposal is that the strict reading of the normative test is correct.
The example is wrong.   Different compilers here give different
answers.
</P>

<P><B>Proposed resolution (April, 2005):</B></P>

<P>Change the second sentence of 5.2.8 [expr.typeid]
paragraph 4 as follows:</P>

<BLOCKQUOTE>

If the type of the <I>type-id</I> is a reference <SPAN style="font-weight:bold;background-color:#A0FFA0">to a possibly
cv-qualified</SPAN> type, the result of the <TT>typeid</TT> expression
refers to a <TT>std::type_info</TT> object representing the
<SPAN style="font-weight:bold;background-color:#A0FFA0">cv-unqualified</SPAN> referenced type.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="54"></A><H4>54.
  
Static_cast from private base to derived class
</H4><B>Section: </B>5.2.9&#160; [expr.static.cast]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>13 Oct 1998<BR>



<P>[Voted into WP at October 2004 meeting.]</P>

<P>Is it okay to use a <TT>static_cast</TT> to cast from a private base
class to a derived class? That depends on what the words "valid standard
conversion" in paragraph 8 mean &#8212; do they mean the conversion exists,
or that it would not get an error if it were done? I think the former
was intended &#8212; and therefore a <TT>static_cast</TT> from a private base
to a derived class would be allowed.</P>

<P><B>Rationale (04/99):</B> A <TT>static_cast</TT> from a private
base to a derived class is not allowed outside a member from the
derived class, because 4.10 [conv.ptr]

paragraph 3 implies that the conversion is not valid. (Classic style
casts work.)</P>

<P><B>Reopened September 2003:</B></P>

<P><U>Steve Adamczyk:</U>
It makes some sense to disallow the inverse conversion that is
pointer-to-member of derived to pointer-to-member of private base.
There's less justification for the pointer-to-private-base to
pointer-to-derived case.  EDG, g++ 3.2, and MSVC++ 7.1 allow
the pointer case and disallow the pointer-to-member case.
Sun disallows the pointer case as well.</P>

<PRE>
  struct B {};
  struct D : private B {};
  int main() {
    B *p = 0;
    static_cast&lt;D *&gt;(p);  // Pointer case: should be allowed
    int D::*pm = 0;
    static_cast&lt;int B::*&gt;(pm);  // Pointer-to-member case: should get error
  }
</PRE>

<P>There's a tricky case with old-style casts: because the
static_cast interpretation is tried first, you want a case
like the above to be considered a static_cast, but then issue
an error, not be rejected as not a static cast; if you did the
latter, you would then try the cast as a reinterpret_cast.</P>

<P>Ambiguity and casting to a virtual base should likewise be
errors after the static_cast interpretation is selected.</P>

<P><B>Notes from the October 2003 meeting:</B></P>

<P>There was lots of sentiment for making things symmetrical:
the pointer case should be the same as the pointer-to-member case.
g++ 3.3 now issues errors on both cases.</P>

<P>We decided an error should be issued on both cases.
The access part of the check should be done later; by some
definition of the word the static_cast is valid, and then
later an access error is issued.
This is similar to the way standard conversions work.</P>

<P><B>Proposed Resolution (October 2003):</B></P>

<P>Replace paragraph 5.2.9 [expr.static.cast]/6:</P>

<BLOCKQUOTE>
The inverse of any standard conversion sequence (clause
4 [conv]), other than the
lvalue-to-rvalue (4.1 [conv.lval]),
array-to-pointer (4.2 [conv.array]),
function-to-pointer (4.3 [conv.func]), and
boolean (4.12 [conv.bool]) conversions, can be performed
explicitly using <TT>static_cast</TT>.
The lvalue-to-rvalue (4.1 [conv.lval]),
array-to-pointer (4.2 [conv.array]), and
function-to-pointer (4.3 [conv.func])
conversions are applied to the operand.
Such a
<TT>static_cast</TT>
is subject to the restriction that the explicit conversion does not
cast away constness (5.2.11 [expr.const.cast]), and the following
additional rules for specific cases:
</BLOCKQUOTE>

<P>with two paragraphs:</P>

<BLOCKQUOTE>
The inverse of any standard conversion sequence (clause
4 [conv]), other than the
lvalue-to-rvalue (4.1 [conv.lval]),
array-to-pointer (4.2 [conv.array]),
function-to-pointer (4.3 [conv.func]), and
boolean (4.12 [conv.bool]) conversions, can be performed
explicitly using <TT>static_cast</TT>.
<SPAN style="font-weight:bold;background-color:#A0FFA0">A program is ill-formed if it
uses <TT>static_cast</TT> to perform the inverse of an ill-formed
standard conversion sequence.[<I>Example:</I> 

<BLOCKQUOTE>
<PRE><SPAN style="font-weight:bold;background-color:#A0FFA0">
struct B {};
struct D : private B {};
void f() {
  static_cast&lt;D*&gt;((B*)0); // Error: B is a private base of D.
  static_cast&lt;int B::*&gt;((int D::*)0); // Error: B is a private base of D.
}
</SPAN></PRE>
</BLOCKQUOTE>
--- end example]
</SPAN>

<P>
The lvalue-to-rvalue (4.1 [conv.lval]),
array-to-pointer (4.2 [conv.array]), and
function-to-pointer (4.3 [conv.func])
conversions are applied to the operand.
Such a
<TT>static_cast</TT>
is subject to the restriction that the explicit conversion does not
cast away constness (5.2.11 [expr.const.cast]), and the following
additional rules for specific cases:
</P>
</BLOCKQUOTE>

<P>In addition, modify the second sentence of
5.4 [expr.cast]/5.  The first two
sentences of 5.4 [expr.cast]/5 presently read:</P>

<BLOCKQUOTE>
The conversions performed by
<UL><LI>
a <TT>const_cast</TT> (5.2.11),
</LI>
<LI>
a <TT>static_cast</TT> (5.2.9),
</LI>
<LI>
a <TT>static_cast</TT> followed by a <TT>const_cast</TT>,
</LI>
<LI>
a <TT>reinterpret_cast</TT> (5.2.10), or
</LI>
<LI>
a <TT>reinterpret_cast</TT> followed by a <TT>const_cast</TT>,
</LI>
</UL>
can be performed using the cast notation of explicit type conversion.
The same semantic restrictions and behaviors apply.
</BLOCKQUOTE>

<P>Change the second sentence to read:</P>

<BLOCKQUOTE>
The same semantic restrictions and behaviors apply<SPAN style="font-weight:bold;background-color:#A0FFA0">, with the exception
that in performing a <TT>static_cast</TT> in the following situations
the conversion is valid even if the base class is inaccessible:

<UL><LI><SPAN style="font-weight:bold;background-color:#A0FFA0">a pointer to an object of derived class type or an lvalue of
derived class type may be explicitly converted to a pointer or
reference to an unambiguous base class type, respectively; </SPAN></LI>

<LI><SPAN style="font-weight:bold;background-color:#A0FFA0">a pointer to member of derived class type may be explicitly
converted to a pointer to member of an unambiguous non-virtual base
class type; </SPAN></LI>

<LI><SPAN style="font-weight:bold;background-color:#A0FFA0">a pointer to an object of an unambiguous non-virtual
base class type, an lvalue of an unambiguous non-virtual base
class type, or a pointer to member of an unambiguous
non-virtual base class type may be explicitly converted to a pointer,
a reference, or a pointer to member of a derived class type,
respectively.</SPAN></LI>
</UL>
</SPAN>
</BLOCKQUOTE>

<P>Remove paragraph 5.4 [expr.cast]/7, which presently reads:</P>

<BLOCKQUOTE>
In addition to
those conversions,
the following
<TT>static_cast</TT>
and
<TT>reinterpret_cast</TT>
operations
(optionally followed by a
<TT>const_cast</TT>
operation)
may be performed using the cast notation of explicit type conversion,
even if the base class type is not accessible:
<UL><LI>
a pointer to an object of derived class type or an lvalue of derived class
type may be explicitly converted
to a pointer or reference to an unambiguous base class type, respectively;
</LI>
<LI>
a pointer to member of derived class type may be explicitly converted
to a pointer to member of an unambiguous non-virtual base class type;
</LI>
<LI>
a pointer to an object of non-virtual base class type, an lvalue
of non-virtual base class type, or a pointer to member of non-virtual
base class type may be explicitly converted to a pointer, a reference,
or a pointer to member of a derived class type, respectively.
</LI>
</UL>
</BLOCKQUOTE>

<BR><BR><HR><A NAME="427"></A><H4>427.
  
<TT>static_cast</TT> ambiguity: conversion versus cast to derived
</H4><B>Section: </B>5.2.9&#160; [expr.static.cast]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mark Mitchell
 &#160;&#160;&#160;

 <B>Date: </B>5 July 2003<BR>


<P>[Voted into WP at October 2004 meeting.]</P>

<P>Consider this code:</P>
<PRE>
  struct B {};

  struct D : public B { 
    D(const B&amp;);
  };

  extern B&amp; b;

  void f() {
    static_cast&lt;const D&amp;&gt;(b);
  }
</PRE>
<P>The rules for <TT>static_cast</TT> permit the conversion to
"const D&amp;" in two ways: </P>
<OL>
<LI>
D is derived from B, and b is an lvalue, so a cast to D&amp; is OK.
</LI>
<LI>
const D&amp; t = b is valid, using the constructor for D. [Ed. note:
actually, this should be parenthesized initialization.]
</LI>
</OL>
<P>The first alternative is 5.2.9 [expr.static.cast]/5; the second is
5.2.9 [expr.static.cast]/2.</P>

<P>Presumably the first alternative is better -- it's the "simpler"
conversion.  The standard does not seem to make that clear.</P>

<P><U>Steve Adamczyk:</U>
I take the "Otherwise" at the beginning of
5.2.9 [expr.static.cast]/3 as meaning that
the paragraph 2 interpretation is used if available, which means in
your example above interpretation 2 would be used.  However, that's
not what EDG's compiler does, and I agree that it's not the "simpler"
conversion.</P>

<P><B>Proposed Resolution (October 2003):</B></P>

<P>Move paragraph 5.2.9/5:</P>

<BLOCKQUOTE>
<P>
An lvalue of type
``<I>cv1</I>
<TT>B</TT>'',
where
<TT>B</TT>
is a class type, can be cast to type ``reference to
<I>cv2</I>
<TT>D</TT>'',
where
<TT>D</TT>
is a class derived (clause
10 [class.derived]) from
<TT>B</TT>,
if a valid standard conversion from ``pointer to
<TT>D</TT>''
to ``pointer to
<TT>B</TT>''
exists (4.10 [conv.ptr]),
<I>cv2</I>
is the same cv-qualification as, or greater cv-qualification than,
<I>cv1</I>,
and
<TT>B</TT>
is not a virtual base class of
<TT>D</TT>.
The result is an lvalue of type
``<I>cv2</I> <TT>D</TT>.''
If the lvalue of type
``<I>cv1</I>
<TT>B</TT>''
is actually a sub-object of an object of type
<TT>D</TT>,
the lvalue refers to the enclosing object of type
<TT>D</TT>.
Otherwise, the result of the cast is undefined.
[<I>Example:</I>
<PRE>
  struct B {};
  struct D : public B {};
  D d;
  B &amp;br = d;

  static_cast&lt;D&amp;&gt;(br);            //<I>  produces lvalue to the original  </I>d<I>  object</I>
</PRE>
--- end example]
</P>
</BLOCKQUOTE>

<P>before paragraph 5.2.9 [expr.static.cast]/2.</P>

<P>Insert <SPAN style="font-weight:bold;background-color:#A0FFA0">Otherwise,</SPAN> before the text of paragraph
5.2.9 [expr.static.cast]/2
(which will become 5.2.9 [expr.static.cast]/3
after the above insertion), so that it
reads:</P>
<BLOCKQUOTE>
<P>
<SPAN style="font-weight:bold;background-color:#A0FFA0">Otherwise</SPAN>, an expression
<TT>e</TT>
can be explicitly converted to a type
<TT>T</TT>
using a
<TT>static_cast</TT>
of the form
<TT>static_cast&lt;T&gt;(e)</TT>
if the declaration
<TT>"T t(e);"</TT>
is well-formed, for some invented temporary variable
<TT>t</TT>
(8.5 [dcl.init]).
The effect of such an explicit conversion is the same as performing the
declaration and initialization and then using the temporary variable
as the result of the conversion.
The result is an lvalue if
<TT>T</TT>
is a reference type (8.3.2 [dcl.ref]), and an rvalue otherwise.
The expression
<TT>e</TT>
is used as an lvalue if and only if the initialization uses it as an lvalue.
</P>
</BLOCKQUOTE>

<BR><BR><HR><A NAME="439"></A><H4>439.
  
Guarantees on casting pointer back to cv-qualified version of original type
</H4><B>Section: </B>5.2.9&#160; [expr.static.cast]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mark Mitchell
 &#160;&#160;&#160;

 <B>Date: </B>30 Oct 2003<BR>


<P>[Voted into WP at April 2005 meeting.]</P>

<P>Paragraph 5.2.9 [expr.static.cast] paragraph 10 says that:</P>

<BLOCKQUOTE>
A value of type pointer to object converted to
"pointer to <I>cv</I> <TT>void</TT>" and back to the
original pointer type will have its original value.
</BLOCKQUOTE>

<P>That guarantee should be stronger.  In particular, given:
<PRE>
  T* p1 = new T;
  const T* p2 = static_cast&lt;const T*&gt;(static_cast&lt;void *&gt;(p1));
  if (p1 != p2)
    abort ();
</PRE>
there should be no call to "abort".  The last sentence of Paragraph
5.2.9 [expr.static.cast] paragraph 10 should be changed to read:</P>

<BLOCKQUOTE>
 A value of type pointer to object converted to "pointer to
<I>cv</I> <TT>void</TT>" and back to the original pointer type
(or a variant of the original pointer type that differs only in the
<I>cv</I>-qualifiers applied to the object type) will have its
original value.
[<I>Example:</I>
<BLOCKQUOTE>
<PRE>
T* p1 = new T;
const T* p2 = static_cast&lt;const T*&gt;(static_cast&lt;void *&gt;(p1));
bool b = p1 == p2; // b <I>will have the value true.</I>
</PRE>
</BLOCKQUOTE>
<I>---end example.</I>]
</BLOCKQUOTE>

<P><B>Proposed resolution:</B></P>

<P>Change 5.2.9 [expr.static.cast] paragraph 10 as indicated:</P>
<BLOCKQUOTE>
A value of type pointer to object converted to "pointer to
<I>cv</I> <TT>void</TT>" and back to the original pointer
type<SPAN style="font-weight:bold;background-color:#A0FFA0">, possibly with different cv-qualification,</SPAN> will have
its original value.  <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Example:</I></SPAN>
<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">
  T* p1 = new T;
  const T* p2 = static_cast&lt;const T*&gt;(static_cast&lt;void *&gt;(p1));
  bool b = p1 == p2; // b<I> will have the value </I>true.
</SPAN>
</PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">---<I>end example</I>]</SPAN>
</BLOCKQUOTE>

<P><B>Rationale:</B> The wording "possibly with different
cv-qualification" was chosen over the suggested wording to
allow for changes in cv-qualification at different levels in a
multi-level pointer, rather than only at the object type level.
</P>

<BR><BR><HR><A NAME="671"></A><H4>671.
  
Explicit conversion from a scoped enumeration type to integral type
</H4><B>Section: </B>5.2.9&#160; [expr.static.cast]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>22 December 2007<BR>


<P>[Voted into the WP at the September, 2008 meeting.]</P>

<P>There appears to be no provision in the Standard for explicit
conversion of a value of a scoped enumeration type to an integral
type, even though the inverse conversion is permitted.  That is,</P>

<PRE>
    enum class E { e };
    static_cast&lt;E&gt;(0);       //<SPAN style="font-family:Times;font-style:italic"> #1: OK</SPAN>
    static_cast&lt;int&gt;(E::e);  //<SPAN style="font-family:Times;font-style:italic"> #2: error</SPAN>
</PRE>

<P>This is because values of scope enumeration types (intentionally)
cannot be implicitly converted to integral types (4.5 [conv.prom]
and 4.7 [conv.integral]) and 5.2.9 [expr.static.cast] was not
updated to permit #2, although #1 is covered by paragraph 8.</P>

<P><B>Proposed resolution (June, 2008):</B></P>

<P>Add the following as a new paragraph following 5.2.9 [expr.static.cast] paragraph 8:</P>

<BLOCKQUOTE>

A value of a scoped enumeration type (7.2 [dcl.enum]) can be
explicitly converted to an integral type.  The value is unchanged if
the original value can be represented by the specified
type. Otherwise, the resulting value is unspecified.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="195"></A><H4>195.
  
Converting between function and object pointers
</H4><B>Section: </B>5.2.10&#160; [expr.reinterpret.cast]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Clamage
 &#160;&#160;&#160;

 <B>Date: </B>12 Jan 2000<BR>



<P>[Voted into WP at April 2005 meeting.]</P>



<P>It is currently not permitted to cast directly between a pointer to
function type and a pointer to object type.  This conversion is not
listed in 5.2.9 [expr.static.cast]
 and
5.2.10 [expr.reinterpret.cast]
 and thus
requires a diagnostic to be issued.  However, if a sufficiently long
integral type exists (as is the case in many implementations), it is
permitted to cast between pointer to function types and pointer to
object types using that integral type as an intermediary.</P>

<P>In C the cast results in undefined behavior and thus does not
require a diagnostic, and Unix C compilers generally do not issue
one.  This fact is used in the definition of the standard Unix
function <TT>dlsym</TT>, which is declared to return <TT>void*</TT>
but in fact may return either a pointer to a function or a pointer to
an object.  The fact that C++ compilers are required to issue a
diagnostic is viewed as a "competitive disadvantage" for the language.</P>

<P><B>Suggested resolution:</B> Add wording to
5.2.10 [expr.reinterpret.cast]
 allowing
conversions between pointer to function and pointer to object types,
if the implementation has an integral data type that can be used as an
intermediary.</P>

<P>Several points were raised in opposition to this suggestion:</P>

<BR><OL>
<LI>Early C++ supported this conversion and it was deliberately
removed during the standardization process.</LI>

<LI>The existence of an appropriate integral type is irrelevant to
whether the conversion is "safe."  The condition should be on whether
information is lost in the conversion or not.</LI>

<LI>There are numerous ways to address the problem at an
implementation level rather than changing the language.  For example,
the compiler could recognize the specific case of <TT>dlsym</TT> and
omit the diagnostic, or the C++ binding to <TT>dlsym</TT> could be
changed (using templates, for instance) to circumvent the violation.</LI>

<LI>The conversion is, in fact, not supported by C; the <TT>dlsym</TT>
function is simply relying on non-mandated characteristics of C
implementations, and we would be going beyond the requirements of C
compatibility in requiring (some) implementations to support the
conversion.</LI>

<LI>This issue is in fact not a defect (omitted or self-contradictory
requirements) in the current Standard; the proposed change would
actually be an extension and should not be considered until the full
review of the IS.</LI>

<LI><TT>dlsym</TT> appears not to be used very widely, and the
declaration in the header file is not problematic, only calls to it.
Since C code generally requires some porting to be valid C++ anyway,
this should be considered one of those items that requires porting.</LI>

</OL>

<P>Martin O'Riordan suggested an alternative approach:</P>

<BR><UL>
<LI>Do not allow the conversions to be performed via old-style casts.</LI>

<LI>Allow <TT>reinterpret_cast</TT> to perform the conversions with
the C-style semantics (undefined behavior if not supported).</LI>

<LI>Allow <TT>dynamic_cast</TT> to perform the conversions with
well-defined behavior: the result would be a null pointer if the
implementation could not support the requested conversion.</LI>
</UL>

<P>The advantage of this approach is that it would permit writing
portable, well-defined programs involving such conversions.  However,
it breaks the current degree of compatibility between old and new
casts, and it adds functionality to <TT>dynamic_cast</TT> which is not
obviously related to its current meaning.</P>

<P><U>Notes from 04/00 meeting:</U></P>

<P>Andrew Koenig suggested yet another approach: specify that "no
diagnostic is required" if the implementation supports the conversion.</P>

<P><B>Later note:</B></P>

<P>It was observed that conversion between function and data pointers
is listed as a "common extension" in C99.  </P>

<P><B>Notes on the 10/01 meeting:</B></P>

<P>It was decided that we want the conversion defined in such a way that
it always exists but is always undefined (as opposed to existing only
when the size relationship is appropriate, and being implementation-defined
in that case).  This would allow an implementation to issue an error
at compile time if the conversion does not make sense.</P>

<P>Bill Gibbons notes that the definitions of the other similar casts are
inconsistent in this regard.  Perhaps they should be updated as well.</P>

<P><B>Proposed resolution (April 2003):</B></P>

<P>After 5.2.10 [expr.reinterpret.cast]
paragraph 6, insert:</P>
<BLOCKQUOTE>
A pointer to a 
function can be explicitly converted to a pointer to a function of a different 
type. The effect of calling a function through a pointer to a function
type (8.3.5 [dcl.fct]) 
that is not the same as the type used in the definition of the function is 
undefined. Except that converting an rvalue of type ``pointer to <TT>T1</TT>'' 
to the type ``pointer to <TT>T2</TT>'' (where <TT>T1</TT> and <TT>T2</TT> are 
function types) and back to its original type yields the original pointer 
value, the result of such a pointer conversion is unspecified. [Note: see
also 4.10 [conv.ptr] for more details of pointer conversions. ]
<SPAN style="font-weight:bold;background-color:#A0FFA0">It is implementation defined whether a conversion from pointer to object to 
pointer to function and/or a conversion from pointer to function to pointer to 
object exist. </SPAN>
</BLOCKQUOTE>
and in paragraph 10:
<BLOCKQUOTE>
An lvalue expression of type <TT>T1</TT> can be cast to the type
``reference to <TT>T2</TT>'' 
if <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>T1</TT> and <TT>T2</TT> are object types and</SPAN> an expression of 
type ``pointer to <TT>T1</TT>'' can be explicitly converted to the type 
``pointer to <TT>T2</TT>'' using a reinterpret_cast. That is, a reference
cast <TT>reinterpret_cast&lt; T&amp; &gt;(x)</TT> has the same effect
as the conversion <TT>*reinterpret_cast&lt; T* &gt;(&amp;x)</TT> with
the built-in <TT>&amp;</TT> and <TT>*</TT> operators. 
The result is an lvalue that refers to the same object as the source lvalue, 
but with a different type. No temporary is created, no copy is made, and 
constructors (12.1 [class.ctor]) or conversion functions
(12.3 [class.conv]) are not called.
</BLOCKQUOTE>
<P><I>Drafting Note:</I></P>
<P>If either conversion exists, the implementation already has to define the 
behavior (paragraph 3).</P>

<P><B>Notes from April 2003 meeting:</B></P>

<P>The new consensus is that if the implementation allows
this cast, pointer-to-function converted to pointer-to-object converted
back to the original pointer-to-function should work; anything else
is undefined behavior.  If the implementation does not allow the cast,
it should be ill-formed.</P>

<P>Tom Plum is investigating a new concept, that of a
"conditionally-defined" feature, which may be applicable here.</P>

<P><B>Proposed Resolution (October, 2004):</B></P>

<P>(See paper J16/04-0067 = WG21 N1627 for background material and
rationale for this resolution.  The resolution proposed here differs
only editorially from the one in the paper.)</P>

<OL>

<LI><P>Insert the following into 1.3 [intro.defs] and renumber
all following definitions accordingly:</P>

<BLOCKQUOTE>
<P><B>1.3.2&#160;&#160;conditionally-supported behavior</B></P>

<P>behavior evoked by a program construct that is not a mandatory
requirement of this International Standard. If a given implementation
supports the construct, the behavior shall be as described herein;
otherwise, the implementation shall document that the construct is not
supported and shall treat a program containing an occurrence of the
construct as ill-formed (1.3 [intro.defs]).</P>

</BLOCKQUOTE>

</LI>

<LI>

<P>Add the indicated words to 1.4 [intro.compliance] paragraph 2,
bullet 2:</P>

<UL><LI><P>If a program contains a violation of any diagnosable
rule,<SPAN style="font-weight:bold;background-color:#A0FFA0"> or an occurrence of a construct described herein as
&#8220;conditionally-supported&#8221; or as resulting in
&#8220;conditionally-supported behavior&#8221; when the implementation
does not in fact support that construct</SPAN>, a conforming
implementation shall issue at least one diagnostic message, except
that</P></LI></UL>

</LI>

<LI><P>Insert the following as a new paragraph following 5.2.10 [expr.reinterpret.cast] paragraph 7:</P>

<BLOCKQUOTE>

Converting a pointer to a function to a pointer to an object type or
vice versa evokes conditionally-supported behavior. In any such
conversion supported by an implementation, converting from an rvalue
of one type to the other and back (possibly with different
cv-qualification) shall yield the original pointer value; mappings
between pointers to functions and pointers to objects are otherwise
implementation-defined.

</BLOCKQUOTE>

</LI>

<LI><P>Change 7.4 [dcl.asm] paragraph 1 as indicated:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The meaning of an</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">An</SPAN> <TT>asm</TT> declaration <SPAN style="font-weight:bold;background-color:#A0FFA0">evokes
conditionally-supported behavior.  If supported, its meaning</SPAN> is
implementation-defined.

</BLOCKQUOTE>

</LI>

<LI><P>Change 7.5 [dcl.link] paragraph 2 as indicated:</P>

<BLOCKQUOTE>

The <I>string-literal</I> indicates the required language linkage. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The meaning of the
string-literal is implementation-defined. A linkage-specification with a string that
is unknown to the implementation is ill-formed.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">This International Standard
specifies the semantics of C and C++ language linkage. Other values of the
<I>string-literal</I> evoke conditionally-supported behavior, with
implementation-defined semantics. [<I>Note:</I> Therefore, a
<I>linkage-specification</I> with a <I>string-literal</I> that is
unknown to the implementation requires a diagnostic.</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">When the
string-literal in a linkage-specification names a programming
language, the spelling of the programming language's name is
implementation-defined. [Note:</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">It</SPAN> is recommended that the
spelling be taken from the document defining that language, for
example <TT>Ada</TT> (not <TT>ADA</TT>) and <TT>Fortran</TT> or
<TT>FORTRAN</TT> (depending on the vintage). <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The semantics of a
language linkage other than C++ or C are implementation-defined.</SPAN> ]

</BLOCKQUOTE>

</LI>

<LI><P>Change 14 [temp] paragraph 4 as indicated:</P>

<BLOCKQUOTE>

A template, a template explicit specialization (14.7.3 [temp.expl.spec]), or a class template partial specialization shall
not have C linkage. If the linkage of one of these is something other
than C or C++, the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">behavior is implementation-defined</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">result
is conditionally-supported behavior, with implementation-defined
semantics</SPAN>.

</BLOCKQUOTE>

</LI>

</OL>

<BR><BR><HR><A NAME="463"></A><H4>463.
  
<TT>reinterpret_cast&lt;T*&gt;(0)</TT>
</H4><B>Section: </B>5.2.10&#160; [expr.reinterpret.cast]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Gennaro Prota
 &#160;&#160;&#160;

 <B>Date: </B>14 Feb 2004<BR>


<P>[Voted into WP at April, 2006 meeting.]</P>

<P>Is <TT>reinterpret_cast&lt;T*&gt;(</TT><I>null_pointer_constant</I><TT>)</TT>
guaranteed to yield the
null pointer value of type T*?</P>

<P>I think a committee clarification is needed. Here's why:
5.2.10 [expr.reinterpret.cast]
par. 8 talks of "null pointer value", not
"null pointer constant", so it would seem that
<PRE>
  reinterpret_cast&lt;T*&gt;(0)
</PRE>
is a normal int-&gt;T* conversion, with an implementation-defined result.</P>

<P>However a little note to
5.2.10 [expr.reinterpret.cast] par. 5 says:
<BLOCKQUOTE>
   Converting an integral constant expression (5.19) with value zero
   always yields a null pointer (4.10), but converting other
   expressions that happen to have value zero need not yield a null
   pointer.
</BLOCKQUOTE>
Where is this supported in normative text? It seems that either the
footnote or paragraph 8 doesn't reflect the intent.</P>

<P>SUGGESTED RESOLUTION: I think it would be better to drop the footnote
#64 (and thus the special case for ICEs), for two reasons:</P>

<P>a) it's not normative anyway; so I doubt anyone is relying on the
guarantee it hints at, unless that guarantee is given elsewhere in a
normative part</P>

<P>b) users expect reinterpret_casts to be almost always implementation
dependent, so this special case is a surprise. After all, if one wants
a null pointer there's static_cast. And if one wants reinterpret_cast
semantics the special case requires doing some explicit cheat, such as
using a non-const variable as intermediary:</P>
<PRE>
   int v = 0;
   reinterpret_cast&lt;T*&gt;(v); // implementation defined

   reinterpret_cast&lt;T*&gt;(0); // null pointer value of type T*
   const int w = 0;
   reinterpret_cast&lt;T*&gt;(w); // null pointer value of type T*
</PRE>

<P>It seems that not only that's providing a duplicate functionality, but
also at the cost to hide what seems the more natural one.</P>

<P><B>Notes from October 2004 meeting:</B></P>

<P>This footnote was added in 1996, after the invention of
<TT>reinterpret_cast</TT>, so the presumption must be that it was
intentional.  At this time, however, the CWG feels that there is
no reason to require that <TT>reinterpret_cast&lt;T*&gt;(0)</TT>
produce a null pointer value as its result.</P>

<P><B>Proposed resolution (April, 2005):</B></P>

<OL><LI><P>Delete the footnote in 5.2.10 [expr.reinterpret.cast]
paragraph 5 reading,</P>

<BLOCKQUOTE>

Converting an integral constant expression
(5.19 [expr.const]) with value zero always yields a null
pointer (4.10 [conv.ptr]), but converting other expressions
that happen to have value zero need not yield a null pointer.

</BLOCKQUOTE>

</LI>

<LI><P>Add the indicated note to 5.2.10 [expr.reinterpret.cast] paragraph
8:</P>

<BLOCKQUOTE>

The null pointer value (4.10 [conv.ptr]) is converted to
the null pointer value of the destination type.  <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I>
A null pointer constant, which has integral type, is not necessarily
converted to a null pointer value. &#8212;<I>end note</I>]</SPAN>

</BLOCKQUOTE>
</LI>

</OL>

<BR><BR><HR><A NAME="324"></A><H4>324.
  
Can "<TT>&amp;</TT>" be applied to assignment to bit-field?
</H4><B>Section: </B>5.3.1&#160; [expr.unary.op]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Alasdair Grant
 &#160;&#160;&#160;

 <B>Date: </B>27 Nov 2001<BR>


<P>[Voted into WP at October 2003 meeting.]</P>

<P>An assignment returns an lvalue for its left operand.  If that
operand refers to a bit field, can the "<TT>&amp;</TT>" operator be
applied to the assignment?  Can a reference be bound to it?</P>
<PRE>
  struct S { int a:3; int b:3; int c:3; };

  void f()
  {
    struct S s;
    const int *p = &amp;(s.b = 0);     // (a)
    const int &amp;r = (s.b = 0);      // (b)
          int &amp;r2 = (s.b = 0);     // (c)
  }
</PRE>

<P><B>Notes from the 4/02 meeting:</B></P>

<P>The working group agreed that this should be an error.</P>

<P><B>Proposed resolution (October 2002):</B></P>

<P>
In 5.3.2 [expr.pre.incr]
paragraph 1 (prefix "<TT>++</TT>" and "<TT>--</TT>" operators), change
<BLOCKQUOTE>
The value is the new value of the operand; it is an lvalue.
</BLOCKQUOTE>
to
<BLOCKQUOTE>
The result is the updated operand; it is an lvalue, and it is a
bit-field if the operand is a bit-field.
</BLOCKQUOTE>
</P>

<P>
In 5.16 [expr.cond]
paragraph 4 ("<TT>?</TT>" operator), add the indicated text:
<BLOCKQUOTE>
If the second and third operands are lvalues and have
the same type, the result is of that type and is an lvalue<SPAN style="font-weight:bold;background-color:#A0FFA0">
and it is a bit-field if the second or the third
operand is a bit-field, or if both are bit-fields.</SPAN>
</BLOCKQUOTE>
</P>

<P>
In 5.17 [expr.ass] paragraph 1 (assignment operators)
add the indicated text (the original text is
as updated by issue 221, which is DR but not in TC1):
<BLOCKQUOTE>
The assignment operator (<TT>=</TT>) and the compound assignment
operators all group right-to-left.  All require a modifiable lvalue as
their left operand and return an lvalue with the type and value of
the left operand after the assignment has taken place. <SPAN style="font-weight:bold;background-color:#A0FFA0">The result
in all cases is a bit-field if the left operand is a bit-field.</SPAN>
</BLOCKQUOTE>
</P>

<P>
Note that issue 222 adds (non-conflicting) text at the end of
this same paragraph (5.17 [expr.ass] paragraph 1).
</P>

<P>
In 5.18 [expr.comma] paragraph 1 (comma operator), change:
<BLOCKQUOTE>
The type and value of the result are the type and value of the right
operand; the result is an lvalue if its right operand is.
</BLOCKQUOTE>
to
<BLOCKQUOTE>
The type and value of the result are the type and value of the right
operand; the result is an lvalue if the right operand is an lvalue,
and is a bit-field if the right operand is an lvalue and a bit-field.
</BLOCKQUOTE>
</P>

<P>Relevant related text (no changes required):</P>

<P>
5.3.1 [expr.unary.op] paragraph 4:
<BLOCKQUOTE>
The operand of <TT>&amp;</TT> shall not be a bit-field.
</BLOCKQUOTE>
</P>

<P>
8.5.3 [dcl.init.ref]
paragraph 5, bullet 1, sub-bullet 1 (regarding binding
a reference to an lvalue):
<BLOCKQUOTE>
... is an lvalue (but is not a bit-field) ...
</BLOCKQUOTE>
</P>

<BR><BR><HR><A NAME="256"></A><H4>256.
  
Overflow in size calculations
</H4><B>Section: </B>5.3.4&#160; [expr.new]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>James Kanze
 &#160;&#160;&#160;

 <B>Date: </B>15 Oct 2000<BR>


<P>[Voted into the WP at the September, 2008 meeting.]</P>

<P>[Picked up by evolution group at October 2002 meeting.]</P>

<P>(See also <A HREF="
     cwg_closed.html#476">issue 476</A>.)</P>



<P>The size requested by an array allocation is computed by multiplying
the number of elements requested by the size of each element and adding
an implementation-specific amount for overhead.  It is possible for this
calculation to overflow.  Is an implementation required to detect this
situation and, for instance, throw <TT>std::bad_alloc</TT>?</P>

<P>On one hand, the maximum allocation size is one of the implementation
limits specifically mentioned in Annex B [implimits], and,
according to 1.4 [intro.compliance] paragraph 2, an implementation
is only required to "accept and correctly execute" programs that do
not violate its resource limits.</P>

<P>On the other hand, it is difficult or impossible for user code
to detect such overflows in a portable fashion, especially given that
the array allocation overhead is not fixed, and it would be a
service to the user to handle this situation gracefully.</P>

<P><B>Rationale (04/01):</B></P>

<P>Each implementation is required to document the maximum size
of an object (Annex B [implimits]).  It is not
difficult for a program to check array allocations to ensure
that they are smaller than this quantity.  Implementations
can provide a mechanism in which users concerned with this
problem can request extra checking before array allocations,
just as some implementations provide checking for array index
and pointer validity.  However, it would not be appropriate to
require this overhead for every array allocation in every
program.</P>

<P>(See <A HREF="
     cwg_defects.html#624">issue 624</A> for a request to
reconsider this resolution.)</P>

<P><B>Note (March, 2008):</B></P>

<P>The Evolution Working Group has accepted the intent of this
issue and referred it to CWG for action for C++0x (see paper
J16/07-0033 = WG21 N2173).</P>

<P><B>Proposed resolution (September, 2008):</B></P>

<P>This issue is resolved by the resolution of <A HREF="
     cwg_defects.html#624">issue 624</A>, given in paper N2757.</P>

<BR><BR><HR><A NAME="299"></A><H4>299.
  
Conversion on array bound expression in <TT>new</TT>
</H4><B>Section: </B>5.3.4&#160; [expr.new]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mark Mitchell
 &#160;&#160;&#160;

 <B>Date: </B>19 Jul 2001<BR>


<P>[Voted into WP at October 2005 meeting.]</P>



<P>In 5.3.4 [expr.new], the standard says that the
expression in an array-new has to 
have integral type.  There's already a DR (<A HREF="
     cwg_defects.html#74">issue 74</A>)
that says it should also be allowed to have enumeration type.  But, it should
probably also say that it can have a class type with a single
conversion to integral type; in other words the same thing as in
6.4.2 [stmt.switch] paragraph 2.</P>

<P><B>Suggested resolution:</B></P>

<P>In 5.3.4 [expr.new] paragraph 6, replace
"integral or enumeration type (3.9.1 [basic.fundamental])" with
"integral or enumeration type (3.9.1 [basic.fundamental]), or a class
type for which a single conversion function to
integral or enumeration type exists".</P>

<P><B>Proposed resolution (October, 2004):</B></P>

<P>Change 5.3.4 [expr.new] paragraph 6 as
follows:</P>

<BLOCKQUOTE>

Every <I>constant-expression</I> in a
<I>direct-new-declarator</I> shall be an integral constant
expression (5.19 [expr.const]) and evaluate to a
strictly positive value. The <I>expression</I> in a
<I>direct-new-declarator</I> shall <SPAN style="text-decoration:line-through;background-color:#FFA0A0">have</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">be of</SPAN>
integral type, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN> enumeration type<SPAN style="text-decoration:line-through;background-color:#FFA0A0"> (3.9.1)</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">, or a
class type for which a single conversion function to integral or
enumeration type exists (12.3 [class.conv]). If the
expression is of class type, the expression is converted by
calling the conversion function, and the result of the conversion
is used in place of the original expression. The value of the
expression shall be</SPAN><SPAN style="text-decoration:line-through;background-color:#FFA0A0">with a</SPAN> non-negative<SPAN style="text-decoration:line-through;background-color:#FFA0A0">
value</SPAN>. [<I>Example:</I> ...

</BLOCKQUOTE>

<P><B>Proposed resolution (April, 2005):</B></P>

<P>Change 5.3.4 [expr.new] paragraph 6 as
follows:</P>

<BLOCKQUOTE>

Every <I>constant-expression</I> in a
<I>direct-new-declarator</I> shall be an integral constant
expression (5.19 [expr.const]) and evaluate to a
strictly positive value. The <I>expression</I> in a
<I>direct-new-declarator</I> shall <SPAN style="text-decoration:line-through;background-color:#FFA0A0">have integral or enumeration
type (3.9.1 [basic.fundamental]) with a non-negative
value</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">be of integral type, enumeration type, or a class type for
which a single conversion function to integral or enumeration type
exists (12.3 [class.conv]). If the expression is of class
type, the expression is converted by calling that conversion function,
and the result of the conversion is used in place of the original
expression. If the value of the expression is negative, the behavior
is undefined</SPAN>. [<I>Example:</I> ...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="429"></A><H4>429.
  
Matching deallocation function chosen based on syntax or signature?
</H4><B>Section: </B>5.3.4&#160; [expr.new]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Wilkinson
 &#160;&#160;&#160;

 <B>Date: </B>18  July 2003<BR>


<P>[Voted into WP at October 2004 meeting.]</P>

<P>What does this example do?</P>
<PRE>
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;

  struct A {
        void* operator new(size_t alloc_size, size_t dummy=0) {
                printf("A::operator new()\n");
                return malloc(alloc_size);
        };

        void operator delete(void* p, size_t s) {
                printf("A::delete %d\n", s);
        };


        A()  {printf("A constructing\n"); throw 2;};

  };

  int
  main() {
    try {
        A* ap = new A;
        delete ap;
    }
    catch(int) {printf("caught\n"); return 1;}
  }  
</PRE>

<P>The fundamental issue here is whether the deletion-on-throw
is driven by the syntax of the new (placement or non-placement)
or by signature matching.  If the former, the operator delete
would be called with the second argument equal to the size of
the class.  If the latter, it would be called with the second
argument 0.</P>

<P><A HREF="
     cwg_defects.html#127">Core issue 127</A> (in TC1) dealt with
this topic.  It removed some wording
in 15.2 [except.ctor] paragraph 2 that implied a
syntax-based interpretation, leaving wording
in 5.3.4 [expr.new] paragraph 19 that is
signature-based.  But there is no accompanying
rationale to confirm an explicit choice of the signature-based
approach.</P>

<P>EDG and g++ get 0 for the second argument, matching the presumed
core issue 127 resolution.  But maybe this should be revisited.</P>

<P><B>Notes from October 2003 meeting:</B></P>

<P>There was widespread agreement that the compiler shouldn't
just silently call the delete with either of the possible values.
In the end, we decided it's smarter to issue an error on this
case and force the programmer to say what he means.</P>

<P>Mike Miller's analysis of the status quo:
3.7.4.2 [basic.stc.dynamic.deallocation] paragraph 2
says that "<TT>operator delete(void*, std::size_t)</TT>" is a
"usual (non-placement) deallocation function" if the class does
not declare "<TT>operator delete(void*)</TT>."
3.7.4.1 [basic.stc.dynamic.allocation] does not use the
same terminology for allocation functions, but the most
reasonable way to understand the uses of the term "placement
allocation function" in the Standard is as an allocation function
that has more than one parameter and thus can (but need not) be
called using the "new-placement" syntax described in
5.3.4 [expr.new].  (In
considering <A HREF="
     cwg_defects.html#127">issue 127</A>,
the core group discussed and endorsed the
position that, "If a placement allocation function has default
arguments for all its parameters except the first, it can be
called using non-placement syntax.")</P>

<P>5.3.4 [expr.new] paragraph 19
says that any non-placement deallocation function
matches a non-placement allocation function, and that a placement
deallocation function matches a placement allocation function
with the same parameter types after the first -- i.e., a
non-placement deallocation function cannot match a placement
allocation function.  This makes sense, because non-placement
("usual") deallocation functions expect to free memory obtained
from the system heap, which might not be the case for storage
resulting from calling a placement allocation function.</P>

<P>According to this analysis, the example shows a placement
allocation function and a non-placement deallocation function, so
the deallocation function should not be invoked at all, and the
memory will just leak.</P>

<P><B>Proposed Resolution (October 2003):</B></P>

<P>Add the following text at the end of 5.3.4 [expr.new]
paragraph 19: </P>
<BLOCKQUOTE>
If the lookup finds the two-parameter form of a usual deallocation function 
(3.7.4.2 [basic.stc.dynamic.deallocation]), and that function, considered as
a placement deallocation function, would have been selected as a match
for the allocation function, the program is ill-formed.
[<I>Example:</I>
<BLOCKQUOTE>
<PRE>
struct S { 
  // <I>Placement allocation function:</I>
  static void* operator new(std::size_t, std::size_t); 

  // <I>Usual (non-placement) deallocation function:</I>
  static void operator delete(void*, std::size_t); 
}; 

S* p = new (0) S; // <I>ill-formed: non-placement deallocation function matches </I>
                  // <I>placement allocation function </I>
</PRE>
</BLOCKQUOTE>
<I>--- end example]</I>
</BLOCKQUOTE>

<BR><BR><HR><A NAME="624"></A><H4>624.
  
Overflow in calculating size of allocation
</H4><B>Section: </B>5.3.4&#160; [expr.new]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jens Maurer
 &#160;&#160;&#160;

 <B>Date: </B>8 March 2007<BR>


<P>[Voted into the WP at the September, 2008 meeting (resolution
in paper N2757).]</P>



<P><A HREF="
     cwg_defects.html#256">Issue 256</A> was closed without action,
principally on the the grounds that an implementation could provide a
means (command-line option, <TT>#pragma</TT>, etc.) for requesting
that the allocation size be checked for validity, but that &#8220;it
would not be appropriate to require this overhead for every array
allocation in every program.&#8221;</P>

<P>This rationale may be giving too much weight to the overhead such a
check would add, especially when compared to the likely cost of
actually doing the storage allocation.  In particular, the test
essentially amounts to something like</P>

<PRE>
    if (max_allocation_size / sizeof(T) &lt; num_elements)
        throw std::bad_alloc();
</PRE>

<P>(noting that <TT>max_allocation_size/sizeof(T)</TT> is a
compile-time constant).  It might make more sense to turn the
rationale around and require the check, assuming that implementations
could provide a mechanism for suppressing it if needed.</P>

<P><U>Suggested resolution</U>:</P>

<P>In 5.3.4 [expr.new] paragraph 7, add the following
words before the example:</P>

<BLOCKQUOTE>

If the value of the expression is such that the size of the allocated
object would exceed the implementation-defined limit, an exception of
type <TT>std::bad_alloc</TT> is thrown and no storage is obtained.

</BLOCKQUOTE>

<P><B>Note (March, 2008):</B></P>

<P>The Evolution Working Group has accepted the intent of
<A HREF="
     cwg_defects.html#256">issue 256</A> and referred it to CWG for
action for C++0x (see paper J16/07-0033 = WG21 N2173).</P>

<P><B>Proposed resolution (March, 2008):</B></P>

<P>As suggested.</P>

<P><B>Notes from the June, 2008 meeting:</B></P>

<P>The CWG felt that this situation should not be treated like an
out-of-memory situation and thus an exception of type
<TT>std::bad_alloc</TT> (or, alternatively, returning a null pointer
for a <TT>throw()</TT> allocator) would not be appropriate.</P>

<P><B>Proposed resolution (June, 2008):</B></P>

<P>Change 5.3.4 [expr.new] paragraph 8 as follows:</P>

<BLOCKQUOTE>

<SPAN style="font-weight:bold;background-color:#A0FFA0">If the value of the <I>expression</I> in a
<I>direct-new-declarator</I> is such that the size of the
allocated object would exceed the implementation-defined limit, no
storage is obtained and the <I>new-expression</I> terminates by
throwing an exception of a type that would match a handler
(15.3 [except.handle]) of type <TT>std::length_error</TT>
(19.2.4 [length.error]).  Otherwise, if</SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">When</SPAN> the value of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">that</SPAN> <I>expression</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">in a
<I>direct-new-declarator</I></SPAN> is zero, the allocation function is
called to allocate an array with no elements.

</BLOCKQUOTE>

<P><I>[Drafting note: <TT>std::length_error</TT> is thrown by
<TT>std::string</TT> and <TT>std::vector</TT> and thus appears to
be the right choice for the exception to be thrown here.]</I></P>

<BR><BR><HR><A NAME="288"></A><H4>288.
  
Misuse of "static type" in describing pointers
</H4><B>Section: </B>5.3.5&#160; [expr.delete]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>James Kuyper
 &#160;&#160;&#160;

 <B>Date: </B>19 May 2001<BR>


<P>[Voted into the WP at the June, 2008 meeting.]</P>

<P>For delete expressions, 5.3.5 [expr.delete] paragraph 1
says</P>

<BLOCKQUOTE>
The operand shall have a pointer type, or a class type having
a single conversion function to a pointer type.
</BLOCKQUOTE>

<P>However,
paragraph 3 of that same section says:</P>

<BLOCKQUOTE>
if the static type of the
operand is different from its dynamic type, the static type shall be a
base class of the operand's dynamic type and the static type shall
have a virtual destructor or the behavior is undefined.
</BLOCKQUOTE>

<P>Since the operand must be of pointer type, its static type is
necessarily the same as its dynamic type. That clause is clearly
referring to the object being pointed at, and not to the pointer operand
itself.</P>

<P>Correcting the wording gets a little complicated, because dynamic
and static types are attributes of expressions, not objects, and
there's no sub-expression of a <I>delete-expression</I> which has the
relevant types.</P>

<P><B>Suggested resolution:</B></P>

<BLOCKQUOTE>
then there is a static type and a dynamic type that the hypothetical
expression <TT>(*</TT> <I>const-expression</I><TT>)</TT> would
have. If that static type is different from that dynamic type, then
that static type shall be a base class of that dynamic type, and that
static type shall have a virtual destructor, or the behavior is
undefined.
</BLOCKQUOTE>

<P>There's precedent for such use of hypothetical constructs: see
5.10 [expr.eq] paragraph 2, and 8.1 [dcl.name]
paragraph 1.</P>

<P>10.3 [class.virtual] paragraph 3 has a similar problem. It
refers to</P>

<BLOCKQUOTE>
 the type of the pointer or reference denoting the object
(the static type).
</BLOCKQUOTE>

<P>The type of the pointer is different from the type of the
reference, both of which are different from the static type of
'*pointer', which is what I think was actually intended. Paragraph 6
contains the exact same wording, in need of the same correction. In
this case, perhaps replacing "pointer or reference" with "expression"
would be the best fix. In order for this fix to be sufficient,
<TT>pointer-&gt;member</TT> must be considered equivalent to
<TT>(*pointer).member</TT>, in which case the "expression" referred to
would be <TT>(*pointer)</TT>.</P>

12.5 [class.free] paragraph 4 says that

<BLOCKQUOTE>
if a <I>delete-expression</I> is used to deallocate a class object
whose static type has...
</BLOCKQUOTE>

<P>This should be changed to</P>

<BLOCKQUOTE>
if a <I>delete-expression</I> is used to deallocate a class object
through a pointer expression whose dereferenced static type would
have...
</BLOCKQUOTE>

<P>The same problem occurs later,
when it says that the</P>

<BLOCKQUOTE>
static and dynamic types of the object shall be
identical
</BLOCKQUOTE>

<P>In this case you could replace "object" with "dereferenced
pointer expression".</P>

<P>Footnote 104 says that</P>

<BLOCKQUOTE>
5.3.5 [expr.delete] requires that ... the static type of the
<I>delete-expression</I>'s operand be the same as its dynamic type.
</BLOCKQUOTE>

<P>This
would need to be changed to</P>

<BLOCKQUOTE>
the <I>delete-expression</I>'s dereferenced
operand
</BLOCKQUOTE>

<P><B>Proposed resolution (December, 2006):</B></P>

<OL>

<LI><P>Change 5.3.5 [expr.delete] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

In the first alternative (<I>delete object</I>), if the static type of
the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">operand</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">object to be deleted</SPAN> is different from its
dynamic type, the static type shall be a base class of
the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">operand's</SPAN> dynamic type <SPAN style="font-weight:bold;background-color:#A0FFA0">of the object to be deleted</SPAN>
and the static type shall have a virtual destructor or the behavior is
undefined. In the second alternative (<I>delete array</I>) if the
dynamic type of the object to be deleted differs from its static type,
the behavior is undefined.

</BLOCKQUOTE>

<LI><P>Change the footnote in 12.5 [class.free] paragraph 4 as
follows:</P></LI>

<BLOCKQUOTE>

A similar provision is not needed for the array version
of <TT>operator delete</TT> because 5.3.5 [expr.delete]
requires that in this situation, the static type of the
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>delete-expression</I>'s operand</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">object to be deleted</SPAN>
be the same as its dynamic type.

</BLOCKQUOTE>

<LI><P>Change the footnote in 12.5 [class.free] paragraph 5 as
follows:</P></LI>

<BLOCKQUOTE>

If the static type <SPAN style="text-decoration:line-through;background-color:#FFA0A0">in the <I>delete-expression</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">of the
object to be deleted</SPAN> is different from the dynamic type and the
destructor is not virtual the size might be incorrect, but that case
is already undefined; see 5.3.5 [expr.delete].

</BLOCKQUOTE>

</OL>

<P>[<I>Drafting notes:</I> No change is required for
10.3 [class.virtual] paragraph 7 because &#8220;the type of
the pointer&#8221; includes the pointed-to type.  No change is
required for 12.5 [class.free] paragraph 4 because
&#8220;...used to deallocate a class object whose static
type...&#8221; already refers to the object (and not the
operand expression).]</P>

<BR><BR><HR><A NAME="353"></A><H4>353.
  
Is deallocation routine called if destructor throws exception in delete?
</H4><B>Section: </B>5.3.5&#160; [expr.delete]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Duane Smith
 &#160;&#160;&#160;

 <B>Date: </B>30 April 2002<BR>


<P>[Voted into WP at April 2003 meeting.]</P>

<P>In a couple of comp.std.c++ threads, people have asked
whether the Standard guarantees that the deallocation function
will be called in a delete-expression if the destructor throws
an exception.  Most/all people have expressed the opinion that 
the deallocation function must be called in this case, although 
no one has been able to cite wording in the Standard supporting 
that view.</P>

<PRE>
#include &lt;new.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

static int flag = 0;

inline 
void operator delete(void* p) throw() 
{
   if (flag)
        printf("in deallocation function\n");
   free(p);
}

struct S {
    ~S() { throw 0; }
};

void f() {
    try {
        delete new S;
    }
    catch(...) { }
}

int main() {
       flag=1;
       f();
       flag=0;
       return 0;
}
</PRE>

<P><B>Proposed resolution (October 2002):</B></P>
<P>
Add to 5.3.5 [expr.delete] paragraph 7 the highlighted text:</P>
<BLOCKQUOTE>
The <I>delete-expression</I> will call a <I>deallocation function</I>
(3.7.4.2 [basic.stc.dynamic.deallocation])
<SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> The deallocation function is called regardless of
whether the destructor for the object or some element of the array
throws an exception. ]</SPAN>
</BLOCKQUOTE>

<BR><BR><HR><A NAME="442"></A><H4>442.
  
Incorrect use of null pointer constant in description of delete operator
</H4><B>Section: </B>5.3.5&#160; [expr.delete]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Matthias Hofmann
 &#160;&#160;&#160;

 <B>Date: </B>2 Dec 2003<BR>


<P>[Voted into WP at October 2005 meeting.]</P>

<P>After some discussion in comp.lang.c++.moderated we came to the conclusion
that there seems to be a defect in
5.3.5 [expr.delete]/4, which says:</P>
<BLOCKQUOTE>
The cast-expression in a delete-expression shall be evaluated exactly once.
If the delete-expression calls the implementation deallocation function
(3.7.3.2), and if the operand of the delete expression is not the null
pointer constant, the deallocation function will deallocate the storage
referenced by the pointer thus rendering the pointer invalid. [Note: the
value of a pointer that refers to deallocated storage is indeterminate. ]
</BLOCKQUOTE>
<P>In the second sentence, the term "null pointer constant" should be changed
to "null pointer". In its present form, the passage claims that the
deallocation function will deallocate the storage refered to by a null
pointer that did not come from a null pointer constant in the delete
expression. Besides, how can the null pointer constant be the operand of a
delete expression, as "delete 0" is an error because delete requires a
pointer type or a class type having a single conversion function to a
pointer type?</P>

<P>See also <A HREF="
     cwg_defects.html#348">issue 348</A>.</P>

<P><B>Proposed resolution:</B></P>
<P>
Change the indicated sentence of
5.3.5 [expr.delete] paragraph 4 as follows:</P>
<BLOCKQUOTE>
If the <I>delete-expression</I> calls the implementation deallocation
function (3.7.4.2 [basic.stc.dynamic.deallocation]), and if
<SPAN style="font-weight:bold;background-color:#A0FFA0">the value of</SPAN> the operand of
the delete expression is not <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">a</SPAN> null
pointer <SPAN style="text-decoration:line-through;background-color:#FFA0A0">constant</SPAN>, the deallocation function will deallocate the
storage referenced by the pointer thus rendering the pointer invalid.
</BLOCKQUOTE>

<P><B>Notes from October 2004 meeting:</B></P>

<P>This wording is superseded by, and this issue will be resolved
by, the resolution of <A HREF="
     cwg_defects.html#348">issue 348</A>.</P>

<P><B>Proposed resolution (April, 2005):</B></P>

<P>This issue is resolved by the resolution of <A HREF="
     cwg_defects.html#348">issue 348</A>.</P>

<BR><BR><HR><A NAME="659"></A><H4>659.
  
Alignment of function types
</H4><B>Section: </B>5.3.6&#160; [expr.alignof]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>7 November 2007<BR>


<P>[Voted into the WP at the September, 2008 meeting.]</P>



<P>The specification for the <TT>alignof</TT> operator (5.3.6 [expr.alignof]) does not forbid function types as operands, although it
probably should.</P>

<P><B>Proposed resolution (March, 2008):</B></P>

<P>The issue, as described, is incorrect.  The requirement in
5.3.6 [expr.alignof] is for &#8220;a complete object type,&#8221;
so a function type is already forbidden.  However, the existing text
does have a problem in this requirement in that it does not allow a
reference type, as anticipated by paragraph 3.  Consequently, the
proposal is to change 5.3.6 [expr.alignof] paragraph 1 as
indicated:</P>

<BLOCKQUOTE>

An <TT>alignof</TT> expression yields the alignment requirement of its operand
type. The operand shall be a <I>type-id</I> representing a complete object
type <SPAN style="font-weight:bold;background-color:#A0FFA0">or a reference to a complete object type</SPAN>.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="520"></A><H4>520.
  
Old-style casts between incomplete class types
</H4><B>Section: </B>5.4&#160; [expr.cast]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>comp.std.c++
 &#160;&#160;&#160;

 <B>Date: </B>19 May 2005<BR>


<P>[Voted into WP at April, 2007 meeting.]</P>

<P>5.4 [expr.cast] paragraph 6 says,</P>

<BLOCKQUOTE>

The operand of a cast using the cast notation can be an rvalue of type
&#8220;pointer to incomplete class type&#8221;. The destination type
of a cast using the cast notation can be &#8220;pointer to incomplete
class type&#8221;. In such cases, even if there is a inheritance
relationship between the source and destination classes, whether the
<TT>static_cast</TT> or <TT>reinterpret_cast</TT> interpretation is
used is unspecified.

</BLOCKQUOTE>

<P>The wording seems to allow the following:</P>

<OL>

<LI><P>casting from void pointer to incomplete type</P></LI>

<PRE>
    struct A;
    struct B;

    void *v;
    A *a = (A*)v; // allowed to choose reinterpret_cast
</PRE>

<LI><P>variant application of static or reinterpret casting</P></LI>

<PRE>
    B *b = (B*)a;    // compiler can choose static_cast here
    A *aa = (A*)b;   // compiler can choose reinterpret_cast here
    assert(aa == a); // might not hold
</PRE>

<LI><P>ability to somehow choose static_cast</P></LI>

<P>It's not entirely clear how a compiler can
choose <TT>static_cast</TT> as 5.4 [expr.cast] paragraph 6
seems to allow. I believe the intent of 5.4 [expr.cast]
paragraph 6 is to force the use of <TT>reinterpret_cast</TT> when
either are incomplete class types and <TT>static_cast</TT> iff the
compiler knows both types and there is a non-ambiguous
hierarchy-traversal between that cast (or maybe not, <A HREF="
     cwg_active.html#242">core issue 242</A> talks about this). I cannot see any
other interpretation because it isn't intuitive, every compiler I've
tried agrees with me, and neither standard pointer conversions
(4.10 [conv.ptr] paragraph 3) nor <TT>static_cast</TT>
(5.2.9 [expr.static.cast] paragraph 5) talk about incomplete
class types. If the committee agrees with me, I would like to see
<secton_ref ref="4.10">4.10 [conv.ptr]</secton_ref> paragraph 3 and 5.2.9 [expr.static.cast] paragraph 5 explicitly disallow incomplete class
types and the wording of 5.4 [expr.cast] paragraph 6
changed to not allow any other interpretation.</P>

</OL>

<P><B>Proposed resolution (April, 2006):</B></P>

<P>Change 5.4 [expr.cast] paragraph 6 as indicated:</P>

<BLOCKQUOTE>

The operand of a cast using the cast notation can be an rvalue of type
&#8220;pointer to incomplete class type.&#8221; The destination type
of a cast using the cast notation can be &#8220;pointer to incomplete
class type.&#8221; <SPAN style="text-decoration:line-through;background-color:#FFA0A0">In such cases, even if there is a inheritance
relationship between the source and destination classes, whether
the <TT>static_cast</TT> or <TT>reinterpret_cast</TT> interpretation
is used is unspecified.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">If both the operand and destination types
are class types and one or both are incomplete, it is unspecified
whether the <TT>static_cast</TT> or the <TT>reinterpret_cast</TT>
interpretation is used, even if there is an inheritance relationship
between the two classes. [<I>Note:</I> For example, if the classes
were defined later in the translation unit, a multi-pass compiler
would be permitted to interpret a cast between pointers to the classes
as if the class types were complete at that point.  &#8212;<I>end
note</I>]</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="497"></A><H4>497.
  
Missing required initialization in example
</H4><B>Section: </B>5.5&#160; [expr.mptr.oper]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Giovanni Bajo
 &#160;&#160;&#160;

 <B>Date: </B>03 Jan 2005<BR>


<P>[Voted into WP at October 2005 meeting.]</P>

<P>5.5 [expr.mptr.oper] paragraph 5 contains the following
example:</P>

<PRE>
    struct S {
        mutable int i;
    };
    const S cs;
    int S::* pm = &amp;S::i;   // pm<SPAN style="font-family:Times;font-style:italic"> refers to mutable member </SPAN>S::i
    cs.*pm = 88;           // <SPAN style="font-family:Times;font-style:italic">ill-formed: </SPAN>cs<SPAN style="font-family:Times;font-style:italic"> is a const object</SPAN>
</PRE>

<P>The const object <TT>cs</TT> is not explicitly initialized,
and class <TT>S</TT> does not have a user-declared default
constructor.  This makes the code ill-formed as per
8.5 [dcl.init] paragraph 9.</P>

<P><B>Proposed resolution (April, 2005):</B></P>

<P>Change the example in 5.5 [expr.mptr.oper] paragraph 5 to read
as follows:</P>

<PRE>
    struct S {
        <SPAN style="font-weight:bold;background-color:#A0FFA0">S() : i(0) { }</SPAN>
        mutable int i;
    };
    <SPAN style="font-weight:bold;background-color:#A0FFA0">void f()
    {</SPAN>
        const S cs;
        int S::* pm = &amp;S::i;   // pm<SPAN style="font-family:Times;font-style:italic"> refers to mutable member </SPAN>S::i
        cs.*pm = 88;           // <SPAN style="font-family:Times;font-style:italic">ill-formed: </SPAN>cs<SPAN style="font-family:Times;font-style:italic"> is a const object</SPAN>
    <SPAN style="font-weight:bold;background-color:#A0FFA0">}</SPAN>
</PRE>

<BR><BR><HR><A NAME="614"></A><H4>614.
  
Results of integer <TT>/</TT> and <TT>%</TT>
</H4><B>Section: </B>5.6&#160; [expr.mul]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Gabriel Dos Reis
 &#160;&#160;&#160;

 <B>Date: </B>15 January 2007<BR>


<P>[Voted into the WP at the September, 2008 meeting as part of
paper N2757.]</P>



<P>The current Standard leaves it implementation-defined whether
integer division rounds the result toward 0 or toward negative
infinity and thus whether the result of <TT>%</TT> may be negative.
C99, apparently reflecting (nearly?) unanimous hardware practice, has
adopted the rule that integer division rounds toward 0, thus requiring
that the result of <TT>-1 % 5</TT> be <TT>-1</TT>.  Should the C++
Standard follow suit?</P>

<P>On a related note, does <TT>INT_MIN % -1</TT> invoke undefined
behavior?  The <TT>%</TT> operator is defined in terms of the
<TT>/</TT> operator, and <TT>INT_MIN / -1</TT> overflows, which by
5 [expr] paragraph 5 causes undefined behavior;
however, that is not the &#8220;result&#8221; of the <TT>%</TT>
operation, so it's not clear.  The wording of 5.6 [expr.mul]
paragraph 4 appears to allow <TT>%</TT> to cause undefined behavior
only when the second operand is 0.</P>

<P><B>Proposed resolution (August, 2008):</B></P>

<P>Change 5.6 [expr.mul] paragraph 4 as follows:</P>

<BLOCKQUOTE>

The binary <TT>/</TT> operator yields the quotient, and the
binary <TT>%</TT> operator yields the remainder from the division
of the first expression by the second. If the second operand of
<TT>/</TT> or <TT>%</TT> is zero the behavior is undefined<SPAN style="text-decoration:line-through;background-color:#FFA0A0">;
otherwise <TT>(a/b)*b + a%b</TT> is equal to <TT>a</TT>. If both
operands are nonnegative then the remainder is nonnegative; if
not, the sign of the remainder is
implementation-defined. [<I>Footnote:</I> According to work
underway toward the revision of ISO C, the preferred algorithm
for integer division follows the rules defined in the ISO Fortran
standard, ISO/IEC 1539:1991, in which the quotient is always
rounded toward zero. &#8212;<I>end footnote</I>]</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">.  For
integral operands, the <TT>/</TT> operator yields the
algebraic quotient with any fractional part discarded;
[<I>Footnote:</I> This is often called &#8220;truncation towards
zero.&#8221; &#8212;<I>end footnote</I>] if the quotient
<TT>a/b</TT> is representable in the type of the result,
<TT>(a/b)*b + a%b</TT> is equal to <TT>a</TT>.</SPAN>

</BLOCKQUOTE>

<P><I>[Drafting note: see C99 6.5.5 paragraph 6.]</I></P>

<BR><BR><HR><A NAME="661"></A><H4>661.
  
Semantics of arithmetic comparisons
</H4><B>Section: </B>5.9&#160; [expr.rel]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>27 November 2007<BR>


<P>[Voted into the WP at the June, 2008 meeting.]</P>

<P>The actual semantics of arithmetic comparison &#8212; e.g.,
whether <TT>1 &lt; 2</TT> yields <TT>true</TT> or <TT>false</TT>
&#8212; appear not to be specified anywhere in the Standard.  The C
Standard has a general statement that</P>

<BLOCKQUOTE>

Each of the operators <TT>&lt;</TT> (less than), <TT>&gt;</TT>
(greater than), <TT>&lt;=</TT> (less than or equal to),
and <TT>&gt;=</TT> (greater than or equal to) shall yield 1 if the
specified relation is true and 0 if it is false.

</BLOCKQUOTE>

<P>There is no corresponding statement in the C++ Standard.</P>

<P><B>Proposed resolution (February, 2008):</B></P>

<OL><LI><P>Append the following paragraph to the end of
5.9 [expr.rel]:</P></LI>

<BLOCKQUOTE>

If both operands (after conversions) are of arithmetic type, each of
the operators shall yield <TT>true</TT> if the specified relation is
true and <TT>false</TT> if it is false.

</BLOCKQUOTE>

<LI><P>Append the following paragraph to the end of
5.10 [expr.eq]:</P></LI>

<BLOCKQUOTE>

Each of the operators shall yield <TT>true</TT> if the specified
relation is true and <TT>false</TT> if it is false.

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="446"></A><H4>446.
  
Does an lvalue-to-rvalue conversion on the "?" operator produce a temporary?
</H4><B>Section: </B>5.16&#160; [expr.cond]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Potter
 &#160;&#160;&#160;

 <B>Date: </B>31 Dec 2003<BR>


<P>[Voted into WP at October 2005 meeting.]</P>

<P>The problem occurs when the value of the operator is determined to
be an rvalue, the selected argument is an lvalue, the type is a class
type and a non-const member is invoked on the modifiable rvalue result.</P>
<PRE>
    struct B {
        int v;
        B (int v) : v(v) { }
        void inc () { ++ v; }
        };
    struct D : B {
        D (int v) : B(v) { }
        };

    B b1(42);
    (0 ? B(13) : b1).inc();
    assert(b1.v == 42);
</PRE>

<P>The types of the second and third operands are the same and
one is an rvalue.  Nothing changes until p6 where an lvalue to
rvalue conversion is performed on the third operand.
12.2 [class.temporary] states that an lvalue to rvalue
conversion produces a temporary and there is nothing to remove
it.  It seems clear that the assertion must pass, yet most
implementations fail.</P>

<P>There seems to be a defect in p3 b2 b1.  First, the conditions to get
here and pass the test.</P>
<BLOCKQUOTE>
  If E1 and E2 have class type, and the underlying class types are the
  same or one is a base class of the other: E1 can be converted to
  match E2 if the class of T2 is the same type as, or a base class of,
  the class of T1, and the cv-qualification of T2 is the same
  cv-qualification as, or a greater cv-qualification than, the
  cv-qualification of T1.
</BLOCKQUOTE>
<P>If both E1 and E2 are lvalues, passing the conditions here also passes
the conditions for p3 b1.  Thus, at least one is an rvalue.  The case of
two rvalues is not interesting and the action is covered by the case
when E1 is an rvalue.</P>
<PRE>
    (0 ? D(13) : b1).inc();
    assert(b1.v == 42);
</PRE>
<BLOCKQUOTE>
  E1 is changed to an rvalue of type T2 that still refers to the
  original source class object (or the appropriate subobject thereof).
  [Note: that is, no copy is made. ]
</BLOCKQUOTE>
<P>Having changed the rvalue to base type, we are back to the above case
where an lvalue to rvalue conversion is required on the third operand
at p6.  Again, most implementations fail.</P>

<P>The remaining case, E1 an lvalue and E2 an rvalue, is the defect.</P>
<PRE>
    D d1(42);
    (0 ? B(13) : d1).inc();
    assert(d1.v == 42);
</PRE>
<P>The above quote states that an lvalue of type T1 is changed to an rvalue
of type T2 without creating a temporary.  This is in contradiction to
everything else in the standard about lvalue to rvalue conversions.
Most implementations pass in spite of the defect.</P>

<P>The usual accessible and unambiguous is missing from the base class.</P>

<P>There seems to be two possible solutions.  Following other temporary
creations would produce a temporary rvalue of type T1 and change it
to an rvalue of type T2.  Keeping the no copy aspect of this bullet
intact would change the lvalue of type T1 to an lvalue of type T2.
In this case the lvalue to rvalue conversion would happen in p6 as
usual.</P>

<P>Suggested wording for p3 b2 b1</P>

<P>The base part:</P>
<BLOCKQUOTE>
  If E1 and E2 have class type, and the underlying class types are the
  same or one is a base class of the other: E1 can be converted to match
  E2 if the class of T2 is the same type as, or an accessible and
  unambiguous base class of, the class of T1, and the cv-qualification
  of T2 is the same cv-qualification as, or a greater cv-qualification
  than, the cv-qualification of T1.  If the conversion is applied:
</BLOCKQUOTE>
<P>The same type temporary version:</P>
<BLOCKQUOTE>
  If E1 is an lvalue, an lvalue to rvalue conversion is applied.  The
  resulting or original rvalue is changed to an rvalue of type T2 that
  refers to the same class object (or the appropriate subobject
  thereof).  [Note: that is, no copy is made in changing the type of
  the rvalue. ]
</BLOCKQUOTE>
<P>The never copy version:</P>
<BLOCKQUOTE>
  The lvalue(rvalue) E1 is changed to an lvalue(rvalue) of type T2
  that refers to the original class object (or the appropriate
  subobject thereof).  [Note: that is, no copy is made. ]
</BLOCKQUOTE>
<P>The test case was posted to clc++m and results for implementations
were reported.</P>
<PRE>
#include &lt;cassert&gt;
struct B {
    int v;
    B (int v) : v(v) { }
    void inc () { ++ v; }
    };
struct D : B {
    D (int v) : B(v) { }
    };
int main () {
    B b1(42);
    D d1(42);
    (0 ? B(13) : b1).inc();
    assert(b1.v == 42);
    (0 ? D(13) : b1).inc();
    assert(b1.v == 42);
    (0 ? B(13) : d1).inc();
    assert(d1.v == 42);
    }

// CbuilderX(EDG301) FFF  Rob Williscroft
// ICC-8.0           FFF  Alexander Stippler
// COMO-4.301        FFF  Alexander Stippler

// BCC-5.4           FFP  Rob Williscroft
// BCC32-5.5         FFP  John Potter
// BCC32-5.65        FFP  Rob Williscroft
// VC-6.0            FFP  Stephen Howe
// VC-7.0            FFP  Ben Hutchings
// VC-7.1            FFP  Stephen Howe
// OpenWatcom-1.1    FFP  Stephen Howe

// Sun C++-6.2       PFF  Ron Natalie

// GCC-3.2           PFP  John Potter
// GCC-3.3           PFP  Alexander Stippler

// GCC-2.95          PPP  Ben Hutchings
// GCC-3.4           PPP  Florian Weimer
</PRE>

<P>I see no defect with regards to lvalue to rvalue conversions; however,
there seems to be disagreement about what it means by implementers.
It may not be surprising because 5.16 and passing a POD struct to an
ellipsis are the only places where an lvalue to rvalue conversion
applies to a class type.  Most lvalue to rvalue conversions are on
basic types as operands of builtin operators.</P>

<P><B>Notes from the March 2004 meeting:</B></P>

<P>We decided all "?" operators that return a class rvalue should
copy the second or third operand to a temporary.  See
<A HREF="
     cwg_defects.html#86">issue 86</A>.</P>

<P><B>Proposed resolution (October 2004):</B></P>

<OL>

<LI><P>Change 5.16 [expr.cond] paragraph 3 bullet 2
sub-bullet 1 as follows:</P>

<BLOCKQUOTE>

if <TT>E1</TT> and <TT>E2</TT> have class type, and the
underlying class types are the same or one is a base class of the
other: <TT>E1</TT> can be converted to match <TT>E2</TT> if the
class of <TT>T2</TT> is the same type as, or a base class of, the
class of <TT>T1</TT>, and the cv-qualification of <TT>T2</TT> is
the same cv-qualification as, or a greater cv-qualification than,
the cv-qualification of <TT>T1</TT>. If the conversion is
applied, <TT>E1</TT> is changed to an rvalue of type <TT>T2</TT>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">that still refers to the original source class object (or the
appropriate subobject thereof). [<I>Note:</I> that is, no copy is
made. &#8212;<I>end note</I>]</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">by copy-initializing a
temporary of type <TT>T2</TT> from <TT>E1</TT> and using that
temporary as the converted operand.</SPAN>

</BLOCKQUOTE>

</LI>

<LI><P>Change 5.16 [expr.cond] paragraph 6 bullet 1 as
follows:</P>

<BLOCKQUOTE>

The second and third operands have the same type; the result is
of that type. <SPAN style="font-weight:bold;background-color:#A0FFA0">If the operands have class type, the result is an
rvalue temporary of the result type, which is copy-initialized
from either the second operand or the third operand depending on
the value of the first operand.</SPAN>

</BLOCKQUOTE>

</LI>

<LI><P>Change 4.1 [conv.lval] paragraph 2 as follows:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The value contained in the object indicated by the lvalue is
the rvalue result.</SPAN> When an lvalue-to-rvalue conversion occurs
within the operand of <TT>sizeof</TT> (5.3.3 [expr.sizeof]) the value contained in the referenced object is
not accessed, since that operator does not evaluate its operand.
<SPAN style="font-weight:bold;background-color:#A0FFA0">Otherwise, if the lvalue has a class type, the conversion
copy-initializes a temporary of type <TT>T</TT> from the lvalue
and the result of the conversion is an rvalue for the temporary.
Otherwise, the value contained in the object indicated by the
lvalue is the rvalue result.</SPAN>

</BLOCKQUOTE>

</LI>

</OL>

<P><I>[Note: this wording partially resolves <A HREF="
     cwg_defects.html#86">issue 86</A>.  See also <A HREF="
     cwg_defects.html#462">issue 462</A>.]</I></P>

<BR><BR><HR><A NAME="339"></A><H4>339.
  
Overload resolution in operand of <TT>sizeof</TT> in constant expression
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>11 Mar 2002<BR>


<P>[Voted into the WP at the June, 2008 meeting as paper N2634.]</P>

<P>I've seen some pieces of code recently that put complex expressions
involving overload resolution inside <TT>sizeof</TT> operations in constant
expressions in templates.</P>

<P>5.19 [expr.const] paragraph 1 implies that some kinds of
nonconstant expressions are allowed inside a <TT>sizeof</TT> in
a constant expression, but it's not clear that this was intended
to extend all the way to things like overload resolution.
Allowing such things has some hidden
costs.  For example, name mangling has to be able to represent all
operators, including calls, and not just the operators that can appear
in constant expressions.</P>

<PRE>
  template &lt;int I&gt; struct A {};

  char xxx(int);
  char xxx(float);

  template &lt;class T&gt; A&lt;sizeof(xxx((T)0))&gt; f(T){}

  int main()
  {
    f(1);
  }
</PRE>

<P>If complex expressions are
indeed allowed, it should be because of an explicit
committee decision rather than because of some looseness in this
section of the standard.</P>

<P><B>Notes from the 4/02 meeting:</B></P>

<P>Any argument for restricting such expressions must involve a
cost/benefit ratio: a restriction would be palatable only if it
causes minimum hardship for users and allows a substantial
reduction in implementation cost. If we propose a restriction,
it must be one that library writers can live with.</P>

<P>Lots of these cases fail with current compilers, so there can't
be a lot of existing code using them.  We plan to find out what
cases there are in libraries like Loki and Boost.</P>

<P>We noted that in many cases one can move the code into a class
to get the same result.  The implementation problem comes up
when the expression-in-sizeof is in a template deduction
context or part of a template signature.  The problem cases
are ones where an error causes deduction to fail, as opposed
to contexts where an error causes a diagnostic.  The latter
contexts are easier to handle; however, there are situations
where "fail deduction" may be the desired behavior.</P>

<P><B>Notes from the April 2003 meeting:</B></P>

<P>Here is a better example:</P>
<PRE>
  extern "C" int printf(const char *, ...);
  char f(int);
  int f(...);
  // Approach 1 -- overload resolution in template class
  // No problem
  template &lt;class T&gt; struct conv_int {
    static const bool value = (sizeof(f(T())) == 1);
  };
  // Approach 2 -- overload resolution in type deduction
  // Difficult
  template &lt;int I&gt; struct A {
    static const int value = I;
  };
  template &lt;class T&gt; bool conv_int2(A&lt;sizeof(f(T()))&gt; p) {
    return p.value == 1;
  }

  template&lt;typename T&gt;
  A&lt;sizeof(f(T()))&gt; make_A() {
    return A&lt;sizeof(f(T()))&gt;();
  }

  int main() {
    printf("short: %d\n", conv_int&lt;short&gt;::value);
    printf("int *: %d\n", conv_int&lt;int *&gt;::value);
    printf("short: %d\n", conv_int2&lt;short&gt;(make_A&lt;short&gt;()));
    printf("int *: %d\n", conv_int2&lt;int *&gt;(make_A&lt;int*&gt;()));
  }
</PRE>

<P>The core working group liked the idea of a restriction that
says that expressions inside sizeof in template signature contexts
must be otherwise valid as nontype template argument expressions
(i.e., integer operations only, limited casts).  This of
course is subject to whether users can live with that restriction.
This topic was brought up in full committee, but there was
limited feedback from other groups.</P>

<P>It was also noted that if typeof (whatever it is called)
is added, there may be a similar issue there.</P>

<P><B>Note (March, 2005):</B></P>



<P><U>Dave Abrahams</U> (quoting a Usenet posting by Vladimir Marko):
The decltype and auto proposal (revision 3: N1607) presents</P>

<PRE>
    template &lt;class T,class U&gt;
    decltype((*(T*)0)+(*(U*)0)) add(const T&amp; t,const U&amp; u);
</PRE>

<P>as a valid declaration (if the proposal is accepted). If [the
restrictions in the April, 2003 note] really applied to decltype, the
declaration above would be invalid. AFAICT every non-trivial use of
decltype in a template function declaration would be invalid.  And for
me this would render my favorite proposal useless.</P>

<P>I would propose to allow any kind of expression inside <TT>sizeof</TT> (and
<TT>decltype</TT>) and explicitly add <TT>sizeof</TT> (and
<TT>decltype</TT>) expressions
involving template-parameters to non-deduced contexts (add a bullet to
14.8.2.4 [temp.deduct.partial] paragraph 4).
</P>

<P><U>Jaakko Jarvi</U>: Just reinforcing that this is important and
hope for insights. The topic is discussed a bit on page 10 of the
latest revision of the proposal (N1705).  Here's a quote from the
proposal:
</P>

<BLOCKQUOTE>

However, it is crucial that no restrictions are placed on what kinds
of expressions are allowed inside <B><I>decltype</I></B>, and
therefore also inside <B><I>sizeof</I></B>. We suggest that issue 339
is resolved to require the compiler to fail deduction (apply the
SFINAE principle), and not produce an error, for as large set of
invalid expressions in operands of <B><I>sizeof</I></B> or
<B><I>decltype</I></B> as is possible to comfortably implement. We wish
that implementors aid in classifying the kinds of expressions that
should produce errors, and the kinds that should lead to failure of
deduction.


</BLOCKQUOTE>

<P><B>Notes from the April, 2007 meeting:</B></P>

<P>The CWG is pursuing a compromise proposal, to which the EWG has
tentatively agreed, which would allow arbitrary expressions in the
return types of function templates but which would restrict the
expressions that participate in the function signature (and thus in
overload resolution) to those that can be used as non-type
template arguments.  During deduction and overload resolution,
these complex return types would be ignored; that is, there would
be no substitution of the deduced template arguments into the return
type at this point.  If such a function were selected by overload
resolution, however, a substitution failure in the return type would
produce a diagnostic rather than a deduction failure.</P>

<P>This approach works when doing overload resolution in the context
of a function call, but additional tricks (still being defined) are
needed in other contexts such as friend function declaration matching
and taking the address of a function, in which the return type does
play a part.</P>

<P><B>Notes from the July, 2007 meeting:</B></P>

<P>The problem is whether arbitrary expressions (for example,
ones that include overload resolution) are allowed in template
deduction contexts, and, if so, which expression errors are
SFINAE failures and which are hard errors.</P>

<P>This issue deals with arbitrary expressions inside sizeof in
deduction contexts. That's a fringe case right now (most
compilers don't accept them). decltype makes the problem worse,
because the standard use case is one that involves overload
resolution. Generalized constant expressions make it worse yet,
because they allow overload resolution and class types to show up
in any constant expression in a deduction context.</P>

<P>Why is this an issue? Why don't we just say everything is
allowed and be done with it?</P>

<UL>

<LI>Because it's hard to implement the general case. Template
deduction/substitution has historically used a simplified model
of semantic checking, i.e., the SFINAE rules (which are mostly
about types), instead of full semantic checking. This limited
semantic checking is typically done by completely separate code
from the code for &#8220;normal&#8221; expression checking, and
it's not easy to extend it to the general
case. &#8220;Speculative compilation&#8221; sounds like an easy
way out, but in practice compilers can't do that.</LI>

<LI>Because it affects name mangling and therefore the ABI.</LI>

<LI>Because we need to figure out what to say and how to say it
in the Standard.</LI>

</UL>

<P>At the April, 2007 meeting, we were headed toward a solution
that imposed a restriction on expressions in deduction contexts,
but such a restriction seems to really hamper uses of constexpr
functions. So we're now proposing that fully general expressions
be allowed, and that most errors in such expressions be treated
as SFINAE failures rather than errors.</P>

<P>One issue with writing Standard wording for that is how to
define &#8220;most.&#8221; There's a continuum of errors, some
errors being clearly SFINAE failures, and some clearly
&#8220;real&#8221; errors, with lots of unclear cases in
between. We decided it's easier to write the definition by
listing the errors that are not treated as SFINAE failures, and
the list we came up with is as follows:</P>

<OL>

<LI>errors that occur while processing some entity external to
the expression, e.g., an instantiation of a template or the
generation of the definition of an implicitly-declared copy
constructor</LI>

<LI>errors due to implementation limits</LI>

<LI>errors due to access violations (this is a judgment call,
but the philosophy of access has always been that it doesn't
affect visibility)</LI>

</OL>

<P>Everything else produces a SFINAE failure rather than a hard
error.</P>

<P>There was broad consensus that this felt like a good solution,
but that feeling was mixed with trepidation on several
fronts:</P>

<UL>

<LI>The implementation cost is quite significant, at least for
EDG and Microsoft (under GCC, it may be easier). It involves
moving around a large amount of code. This may delay
implementation and introduce bugs in compilers.</LI>

<LI>While it seems upward compatible with C++03, it's possible it
will break existing code. Any big change in template processing
has a pretty good chance of breaking something.</LI>

<LI>Since there is no implementation, we don't really know how it
will work in the real world.</LI>

</UL>

<P>We will be producing wording for the Working Draft for the
October, 2007 meeting.</P>

<P>(See also <A HREF="
     cwg_defects.html#657">issue 657</A>.)</P>

<BR><BR><HR><A NAME="366"></A><H4>366.
  
String literal allowed in integral constant expression?
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Martin v. Loewis
 &#160;&#160;&#160;

 <B>Date: </B>29 July 2002<BR>


<P>[Voted into WP at October 2003 meeting.]</P>

<P>According to 16.1 [cpp.cond] paragraph 1, the if-group</P>
<PRE>
#if "Hello, world"
</PRE>
<P>is well-formed, since it is an integral constant expression.
Since that may not be obvious, here is why:</P>

<P>5.19 [expr.const] paragraph 1 says that an integral constant
expression may involve literals (2.14 [lex.literal]);
"Hello, world" is a literal. It restricts
operators to not use certain type conversions; this expression does
not use type conversions. It further disallows functions, class
objects, pointers, ... - this expression is none of those, since it 
is an array.</P>

<P>However, 16.1 [cpp.cond] paragraph 6 does not explain what
to do with this if-group, since
the expression evaluates neither to false(zero) nor true(non-zero).</P>

<P><B>Proposed resolution (October 2002):</B></P>

<P>Change the beginning of the second sentence of
5.19 [expr.const] paragraph 1 which currently reads
<BLOCKQUOTE>
An <I>integral constant-expression</I> can involve only literals
(2.14 [lex.literal]), ...
</BLOCKQUOTE>
to say
<BLOCKQUOTE>
An <I>integral constant-expression</I> can involve only literals of
arithmetic types (2.14 [lex.literal],
3.9.1 [basic.fundamental]), ...
</BLOCKQUOTE>
</P>

<BR><BR><HR><A NAME="367"></A><H4>367.
  
<TT>throw</TT> operator allowed in constant expression?
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Martin v. Loewis
 &#160;&#160;&#160;

 <B>Date: </B>29 July 2002<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>

<P>The following translation unit appears to be well-formed.</P>
<PRE>
int x[true?throw 4:5];
</PRE>
<P>According to 5.19 [expr.const], this appears to be an
integral constant expression:
it is a conditional expression, involves only literals, and no
assignment, increment, decrement, function-call, or comma operators.
However, if this is well-formed, the standard gives no meaning to 
this declaration, since the array bound (8.3.4 [dcl.array]
paragraph 1) cannot be computed.</P>

<P>I believe the defect is that throw expressions should also be banned
from constant expressions.</P>

<P><B>Notes from October 2002 meeting:</B></P>

<P>We should also check on <TT>new</TT> and <TT>delete</TT>.</P>

<P><B>Notes from the April, 2005 meeting:</B></P>

<P>Although it could be argued that all three of these operators
potentially involve function calls &#8212; <TT>throw</TT>
to <TT>std::terminate</TT>, <TT>new</TT> and <TT>delete</TT> to the
corresponding allocation and deallocation functions &#8212; and thus
would already be excluded from constant expressions, this reasoning
was considered to be too subtle to allow closing the issue with no
change.  A modification that explicitly clarifies the status of these
operators will be drafted.</P>

<P><B>Proposed resolution (October, 2005):</B></P>

<P>Change the last sentence of 5.19 [expr.const] as indicated:</P>

<BLOCKQUOTE>

In particular, except in <TT>sizeof</TT> expressions, functions, class
objects, pointers, or references shall not be used, and assignment,
increment, decrement, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">function-call</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">function call (including
<I>new-expression</I>s and <I>delete-expression</I>s)</SPAN>, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN> comma
operators<SPAN style="font-weight:bold;background-color:#A0FFA0">, or <I>throw-expression</I>s</SPAN> shall not be used.

</BLOCKQUOTE>

<P><I>Note: this sentence is also changed by the resolution of
<A HREF="
     cwg_defects.html#530">issue 530</A>.</I></P>

<BR><BR><HR><A NAME="457"></A><H4>457.
  
Wording nit on use of const variables in constant expressions
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mark Mitchell
 &#160;&#160;&#160;

 <B>Date: </B>03 Feb 2004<BR>


<P>[Voted into WP at April 2005 meeting.]</P>

<P>I'm looking at 5.19 [expr.const].  I see:</P>
<BLOCKQUOTE> 
    An <I>integral constant-expression</I> can involve only ... const 
variables or static data
   members of integral or enumeration types initialized with constant 
expressions ...
</BLOCKQUOTE>
<P>Shouldn't that be "const non-volatile"? </P>

<P>It seems weird to say that:
<PRE>
  const volatile int i = 3;
  int j[i];
</PRE>
is valid.</P>

<P><U>Steve Adamczyk:</U> See <A HREF="
     cwg_defects.html#76">issue 76</A>,
which made the similar change to 7.1.6.1 [dcl.type.cv]
paragraph 2, and probably should have changed this one as
well.</P>

<P><B>Proposed resolution (October, 2004):</B></P>

<P>Change the first sentence in the second part of 5.19 [expr.const] paragraph 1 as follows:</P>

<BLOCKQUOTE>

An <I>integral constant-expression</I> can involve only literals
of arithmetic types (2.14 [lex.literal], 3.9.1 [basic.fundamental]), enumerators, <SPAN style="font-weight:bold;background-color:#A0FFA0">non-volatile</SPAN>
<TT>const</TT> variables or static data members of integral or
enumeration types initialized with constant expressions
(8.5 [dcl.init]),
non-type template parameters of integral or enumeration types,
and <TT>sizeof</TT> expressions.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="530"></A><H4>530.
  
Nontype template arguments in constant expressions
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mark Mitchell
 &#160;&#160;&#160;

 <B>Date: </B>21 August 2005<BR>


<P>[Voted into the WP at the April, 2007 meeting as part of paper
J16/07-0095 = WG21 N2235.]</P>

<P>Consider:</P>

<PRE>
    template &lt;int* p&gt; struct S {
        static const int I = 3;
    };
    int i;
    int a[S&lt;&amp;i&gt;::I];
</PRE>

<P>Clearly this should be valid, but a pedantic reading of
5.19 [expr.const] would suggest that this is invalid because
&#8220;<TT>&amp;i</TT>&#8221; is not permitted in integral constant
expressions.</P>

<P><B>Proposed resolution (October, 2005):</B></P>

<P>Change the last sentence of 5.19 [expr.const] paragraph 1
as indicated:</P>

<BLOCKQUOTE>

In particular, except in <SPAN style="font-weight:bold;background-color:#A0FFA0">non-type <I>template-argument</I>s
or</SPAN> <TT>sizeof</TT> expressions, functions, class objects,
pointers, or references shall not be used, and assignment, increment,
decrement, function-call, or comma operators shall not be used.

</BLOCKQUOTE>

<P><I>(Note: the same text is changed by the resolution of
<A HREF="
     cwg_defects.html#367">issue 367</A>.)</I></P>

<P><B>Notes from April, 2006 meeting:</B></P>

<P>The proposed resolution could potentially be read as saying that
the prohibited operations and operators would be permitted in integral
constant expressions that are non-type <I>template-argument</I>s.  John
Spicer is investigating an alternate approach, to say that expressions
in non-type template arguments are not part of the expression in which
the <I>template-id</I> appears (in contrast to the operand of
<TT>sizeof</TT>, which is part of the containing expression).</P>

<P><B>Additional note (May, 2008):</B></P>

<P>This issue is resolved by the rewrite of <setion_ref ref="5.19">5.19 [expr.const]</setion_ref>
that was done in conjunction with the constexpr proposal, paper
N2235.</P>

<BR><BR><HR><A NAME="684"></A><H4>684.
  
Constant expressions involving the address of an automatic variable
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jens Maurer
 &#160;&#160;&#160;

 <B>Date: </B>13 March, 2008<BR>


<P>[Voted into the WP at the September, 2008 meeting (resolution
in paper N2757).]</P>



<P>The expressions that are excluded from being constant expressions
in 5.19 [expr.const] paragraph 2 does not address an example
like the following:</P>

<PRE>
    void f() {
       int a;
       constexpr int* p = &amp;a;    //<SPAN style="font-family:Times;font-style:italic"> should be ill-formed, currently isn't</SPAN>
    }
</PRE>

<P><U>Suggested resolution:</U></P>

<P>Add the following bullet to the list in 5.19 [expr.const]
paragraph 2:</P>

<UL><LI><P>an <I>id-expression</I> that refers to a variable with
automatic storage duration unless a permitted lvalue-to-rvalue
conversion is applied (see above)</P></LI></UL>

<P><B>Proposed resolution (June, 2008):</B></P>

<OL><LI><P>Change 3.6.2 [basic.start.init] paragraph 1 as
follows:</P></LI>

<BLOCKQUOTE>

Objects with static storage duration (3.7.1 [basic.stc.static]) or
thread storage duration (3.7.2) shall be zero-initialized
(8.5 [dcl.init]) before any other initialization takes
place. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">A reference with static or thread storage duration and an
object of trivial or literal type with static or thread storage
duration can be initialized with a constant expression (5.19 [expr.const]); this is called <I>constant initialization</I>.</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>Constant initialization</I> is performed:

<UL><LI><P>if an object of trivial or literal type with static or
thread storage duration is initialized with a constant expression
(5.19 [expr.const]), or</P></LI>

<LI><P>if a reference with static or thread storage duration is
initialized with a constant expression that is not an lvalue
designating an object with thread or automatic storage
duration.</P></LI>

</UL>
</SPAN>
Together, zero-initialization and constant
initialization...

</BLOCKQUOTE>

<LI><P>Add the following in 5.19 [expr.const] paragraph
2:</P></LI>

<BLOCKQUOTE>

<UL><LI><P>an lvalue-to-rvalue conversion (4.1) unless it is applied
to...</P></LI>

<SPAN style="font-weight:bold;background-color:#A0FFA0">

<LI><P>an array-to-pointer conversion (4.2 [conv.array]) that
is applied to an lvalue that designates an object with thread or
automatic storage duration</P></LI>

<LI><P>a unary operator <TT>&amp;</TT> (5.3.1 [expr.unary.op])
that is applied to an lvalue that designates an object with thread or
automatic storage duration</P></LI>

</SPAN>

<LI><P>an <I>id-expression</I> that refers to a variable or data
member of reference type;</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

</OL>

<P>(Note: the change to 3.6.2 [basic.start.init] paragraph 1
needs to be reconciled with the conflicting change in
<A HREF="
     cwg_defects.html#688">issue 688</A>.)</P>

<BR><BR><HR><A NAME="276"></A><H4>276.
  
Order of destruction of parameters and temporaries
</H4><B>Section: </B>6.6&#160; [stmt.jump]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>James Kanze
 &#160;&#160;&#160;

 <B>Date: </B>28 Mar 2001<BR>


<P>[Voted into the WP at the June, 2008 meeting.]</P>

<P>According to 6.6 [stmt.jump] paragraph 2,</P>

<BLOCKQUOTE>

On exit from a scope (however accomplished), destructors (12.4 [class.dtor]) are called for all constructed objects with automatic
storage duration (3.7.3 [basic.stc.auto]) (named objects or
temporaries) that are declared in that scope, in the reverse order of
their declaration.

</BLOCKQUOTE>

<P>This wording is problematic for temporaries and for parameters.
First, temporaries are not "declared," so this requirement does not
apply to them, in spite of the assertion in the quoted text that it
does.</P>

<P>Second, although the parameters of a function are <I>declared</I>
in the called function, they are constructed and destroyed in the
calling context, and the order of evaluation of the arguments is
unspecified (cf 5.2.2 [expr.call] paragraphs 4 and 8).
The order of destruction of the parameters might, therefore, be
different from the reverse order of their declaration.</P>

<P><B>Notes from 04/01 meeting:</B></P>

<P>Any resolution of this issue should be careful not to introduce
requirements that are redundant or in conflict with those of other
parts of the IS.  This is especially true in light of the pending
issues with respect to the destruction of temporaries (see issues
<A HREF="
     cwg_defects.html#86">86</A>, <A HREF="
     cwg_defects.html#124">124</A>,
<A HREF="
     cwg_defects.html#199">199</A>, and <A HREF="
     cwg_defects.html#201">201</A>).
If possible, the wording of a resolution should simply reference
the relevant sections.</P>

<P>It was also noted that the temporary for a return value is
also destroyed "out of order."  </P>

<P>Note that <A HREF="
     cwg_defects.html#378">issue 378</A> picks a nit
with the wording of this same paragraph.</P>

<P><B>Proposed Resolution (November, 2006):</B></P>

<P>Change 6.6 [stmt.jump] paragraph 2 as follows:</P>

<BLOCKQUOTE>

On exit from a scope (however accomplished), <SPAN style="text-decoration:line-through;background-color:#FFA0A0">destructors
(12.4 [class.dtor]) are called for all constructed objects
with automatic storage duration (3.7.3 [basic.stc.auto]) (named
objects or temporaries) that are declared in that scope, in the
reverse order of their declaration.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">variables with automatic
storage duration (3.7.3 [basic.stc.auto]) that have been
constructed in that scope are destroyed in the reverse order of their
construction. [<I>Note:</I> For temporaries, see 12.2 [class.temporary].
&#8212;<I>end note</I>]</SPAN> Transfer out of a loop...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="378"></A><H4>378.
  
Wording that says temporaries are declared
</H4><B>Section: </B>6.6&#160; [stmt.jump]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Gennaro Prota
 &#160;&#160;&#160;

 <B>Date: </B>07 September 2002<BR>


<P>Paragraph 6.6 [stmt.jump] paragraph 2 of the standard says:</P>
<BLOCKQUOTE>
On exit from a scope (however accomplished), destructors
(12.4 [class.dtor])
are called for all constructed objects with automatic storage
duration (3.7.3 [basic.stc.auto])
(named objects or temporaries) that are declared
in that scope.
</BLOCKQUOTE>

<P>It refers to objects "that are declared" but the text in parenthesis
also mentions temporaries, which cannot be declared. I think that text
should be removed.</P>

<P>This is related to <A HREF="
     cwg_defects.html#276">issue 276</A>.</P>

<P><B>Proposed Resolution (November, 2006):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#276">issue 276</A>.</P>

<BR><BR><HR><A NAME="281"></A><H4>281.
  
<TT>inline</TT> specifier in <TT>friend</TT> declarations
</H4><B>Section: </B>7.1.2&#160; [dcl.fct.spec]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>24 Apr 2001<BR>


<P>[Moved to DR at October 2002 meeting.]</P>



<P>There is currently no restriction on the use of the
<TT>inline</TT> specifier in <TT>friend</TT> declarations.  That
would mean that the following usage is permitted:</P>

<PRE>
    struct A {
        void f();
    };

    struct B {
        friend inline void A::f();
    };

    void A::f(){}
</PRE>

<P>I believe this should be disallowed because a <TT>friend</TT>
declaration in one class should not be able to change attributes of a
member function of another class.</P>

<P>More generally, I think that the <TT>inline</TT> attribute should
only be permitted in <TT>friend</TT> declarations that are definitions.</P>

<P><B>Notes from the 04/01 meeting:</B></P>

<P>The consensus agreed with the suggested resolution.  This
outcome would be similar to the resolution of
<A HREF="
     cwg_defects.html#136">issue 136</A>.</P>

<P><B>Proposed resolution (10/01):</B></P>

<P> Add to the end of 7.1.2 [dcl.fct.spec] paragraph 3:</P>

<BLOCKQUOTE>
If the <TT>inline</TT> specifier is used in a friend declaration, that
declaration shall be a definition or the function shall have
previously been declared inline.
</BLOCKQUOTE>

<BR><BR><HR><A NAME="317"></A><H4>317.
  
Can a function be declared inline after it has been called?
</H4><B>Section: </B>7.1.2&#160; [dcl.fct.spec]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Clamage
 &#160;&#160;&#160;

 <B>Date: </B>14 Oct 2001<BR>


<P>[Voted into WP at October 2005 meeting.]</P>



<P><U>Steve Clamage</U>:
Consider this sequence of declarations:
<PRE>
  void foo() { ... }
  inline void foo();
</PRE>
The non-inline definition of foo precedes the inline declaration.
It seems to me this code should be ill-formed, but I could not find
anything in the standard to cover the situation.</P>

<P><U>Bjarne Stroustrup</U>:
Neither could I, so I looked in the ARM, which addressed this case (apparently 
for member function only) in some detail in 7.1.2 (pp103-104).</P>

<P>The ARM allows declaring a function inline after its initial declaration,
as long as it has not been called.</P>

<P><U>Steve Clamage</U>:
If the above code is valid, how about this:</P>
<PRE>
  void foo() { ... }    // define foo
  void bar() { foo(); } // use foo
  inline void foo();    // declare foo inline
</PRE>

<P><U>Bjarne Stroustrup</U>:
... and [the ARM] disallows declaring a function inline after it
has been called.</P>

<P>This may still be a good resolution.</P>

<P><U>Steve Clamage</U>:
But the situation in the ARM is the reverse:  Declare a function
inline, and define it later (with no intervening call).  That's
a long-standing rule in C++, and allows you to write member
function definitions outside the class.</P>

<P>In my example, the compiler could reasonably process the entire
function as out-of-line, and not discover the inline declaration
until it was too late to save the information necessary for inline
generation.  The equivalent of another compiler pass would be needed
to handle this situation.</P>

<P><U>Bjarne Stroustrup</U>:
I see, and I think your argument it conclusive.</P>

<P><U>Steve Clamage</U>:
I'd like to open a core issue on this point, and I recommend wording
along the lines of:  "A function defined without an inline specifier
shall not be followed by a declaration having an inline specifier."</P>

<P>I'd still like to allow the common idiom</P>
<PRE>
  class T {
    int f();
  };
  inline int T::f() { ... }
</PRE>

<P><U>Martin Sebor</U>:
Since the inline keyword is just a hint to the compiler, I don't see
any harm in allowing the construct. Your hypothetical compiler can
simply ignore the inline on the second declaration. On the other hand,
I feel that adding another special rule will unnecessarily complicate
the language.</P>

<P><U>Steve Clamage</U>:
The inline specifier is more than a hint.  You can have multiple
definitions of inline functions, but only one definition of a
function not declared inline.  In particular, suppose the above
example were in a header file, and included multiple times in
a program.</P>

<P><B>Proposed resolution (October, 2004):</B></P>

<P>Add the indicated words to 7.1.2 [dcl.fct.spec]
paragraph 4:</P>

<BLOCKQUOTE>

An inline function shall be defined in every translation unit in
which it is used and shall have exactly the same definition in
every case (3.2 [basic.def.odr]). [<I>Note:</I> a call to
the inline function may be encountered before its definition
appears in the translation unit. &#8212;<I>end note</I>] <SPAN style="font-weight:bold;background-color:#A0FFA0">If the
definition of a function appears in a translation unit before its
first declaration as inline, the program is ill-formed.</SPAN> If a
function with external linkage is declared inline in one
translation unit...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="396"></A><H4>396.
  
Misleading note regarding use of <TT>auto</TT> for disambiguation
</H4><B>Section: </B>7.1.2&#160; [dcl.fct.spec]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Herb Sutter
 &#160;&#160;&#160;

 <B>Date: </B>3 Jan 2003<BR>


<P>[Voted into WP at March 2004 meeting.]</P>



<P>BTW, I noticed that the following note in 7.1.1 [dcl.stc]
paragraph 2 doesn't seem to have
made it onto the issues list or into the TR:</P>
<BLOCKQUOTE>
  [Note: hence, the auto specifier is almost always redundant and not
  often used; one use of auto is to distinguish a declaration-statement
  from an expression-statement (stmt.ambig) explicitly. --- end note]
</BLOCKQUOTE>
<P>I thought that this was well known to be incorrect, because using auto
does not disambiguate this. Writing:
<PRE>
  auto int f();
</PRE>
is still a declaration of a function f, just now with an error since the
function's return type may not use an auto storage class specifier. I
suppose an error is an improvement over a silent ambiguity going the
wrong way, but it's still not a solution for the user who wants to
express the other in a compilable way.</P>

<P>Proposed resolution: Replace that note with the following note:</P>
<BLOCKQUOTE>
  [Note: hence, the auto specifier is always redundant and not often
  used. --- end note]
</BLOCKQUOTE>

<P><U>John Spicer</U>:
I support the proposed change, but I think the disambiguation case is not the 
one that you describe.  An example of the supposed disambiguation is:</P>
<PRE>
  int i;
  int j;
  int main()
  {
    int(i);  // declares i, not reference to ::i
    auto int(j);  // declares j, not reference to ::j
  }
</PRE>
<P>
cfront would take "int(i)" as a cast of ::i, so the auto would force what it 
would otherwise treat as a statement to be considered a declaration
(cfront 3.0 warned that this would change in the future).</P>

<P>In a conforming compiler the auto is always redundant (as you say) because 
anything that could be considered a valid declaration should be treated as
one.</P>

<P><B>Proposed resolution (April 2003):</B></P>

<P>Replace 7.1.1 [dcl.stc] paragraph 2
<BLOCKQUOTE>
[Note: hence, the <TT>auto</TT> specifier
is almost always redundant and not often used;
one use of <TT>auto</TT> is to distinguish
a <I>declaration-statement</I> from
an <I>expression-statement</I> (6.8 [stmt.ambig])
explicitly. --- end note]
</BLOCKQUOTE>
with
<BLOCKQUOTE>
[Note: hence, the <TT>auto</TT> specifier
is always redundant and not often used.
One use of <TT>auto</TT> is to distinguish
a <I>declaration-statement</I> from an <I>expression-statement</I>
explicitly
rather than relying on the disambiguation rules
(6.8 [stmt.ambig]),
which may aid readers.
--- end note]
</BLOCKQUOTE>
</P>

<BR><BR><HR><A NAME="397"></A><H4>397.
  
Same address for string literals from default arguments in inline functions?
</H4><B>Section: </B>7.1.2&#160; [dcl.fct.spec]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mark Mitchell
 &#160;&#160;&#160;

 <B>Date: </B>13 Jan 2003<BR>


<P>[Voted into WP at April, 2007 meeting.]</P>

<P>Are string literals from default arguments
used in extern inlines supposed to have the same addresses across
all translation units?</P>
<PRE>
  void f(const char* = "s")
  inline g() {
    f();
  }
</PRE>
<P>Must the "s" strings be the same in all copies of the
inline function?</P>

<P><U>Steve Adamczyk</U>:
The totality of the standard's wisdom on this topic is
(7.1.2 [dcl.fct.spec] paragraph 4):</P>
<BLOCKQUOTE>
A string literal in an extern inline function is the same object 
in different translation units.
</BLOCKQUOTE>
 
<P>I'd hazard a guess that a literal in a default argument expression 
is not "in" the extern inline function (it doesn't appear in the
tokens of the function), and therefore it need not be
the same in different translation units.</P>

<P>I don't know that users would expect such strings to have
the same address, and an equally valid (and incompatible) expectation
would be that the same string literal would be used for every expansion of
a given default argument in a single translation unit.</P>

<P><B>Notes from April 2003 meeting:</B></P>

<P>The core working group feels that the address of a string literal
should be guaranteed to be the same only if it actually appears
textually within the body of the inline function.  So a string in
a default argument expression
in a block extern declaration inside the body of a function would
be the same in all instances of the function.  On the other
hand, a string in a default argument expression in the header of
the function (i.e., outside of the body) would not be the same.</P>

<P><B>Proposed resolution (April 2003):</B></P>

<P>Change the last sentence and add the note to the end of 
7.1.2 [dcl.fct.spec] paragraph 4:</P>
<BLOCKQUOTE>
A string literal in <SPAN style="font-weight:bold;background-color:#A0FFA0">the body of</SPAN> an <TT>extern inline</TT>
function is the same
object in different translation units.
<SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> A string literal that is encountered only in the context of a
function call (in the default argument expression of the called function),
is not &#8220;in&#8221; the <TT>extern inline</TT> function.]</SPAN>
</BLOCKQUOTE>

<P><B>Notes from October 2003 meeting:</B></P>

<P>We discussed ctor-initializer lists and decided that they are
also part of the body.  We've asked Clark Nelson to work on
syntax changes to give us a syntax term for the body of a
function so we can refer to it here.  See also
<A HREF="
     cwg_defects.html#452">issue 452</A>, which could use this term.</P>

<P><I>(October, 2005: moved to &#8220;review&#8221; status in concert with
<A HREF="
     cwg_defects.html#452">issue 452</A>.  With that resolution, the wording
above needs no further changes.)</I></P>

<P><B>Proposed resolution (April, 2006):</B></P>

<P>Change the last sentence and add the note to the end of 
7.1.2 [dcl.fct.spec] paragraph 4:</P>

<BLOCKQUOTE>
A string literal in <SPAN style="font-weight:bold;background-color:#A0FFA0">the body of</SPAN> an <TT>extern inline</TT>
function is the same object in different translation units.
<SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> A string literal appearing in a default argument
expression is not considered to be &#8220;in the body&#8221;
of an inline function merely by virtue of the expression&#8217;s use in a
function call from that inline function. &#8212;<I>end note</I>]</SPAN>
</BLOCKQUOTE>

<BR><BR><HR><A NAME="477"></A><H4>477.
  
Can <TT>virtual</TT> appear in a <TT>friend</TT> declaration?
</H4><B>Section: </B>7.1.2&#160; [dcl.fct.spec]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>23 Sep 2004<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>

<P>I couldn't find wording that makes it invalid to say
<TT>friend&#160;virtual...</TT>  The closest seems to be
7.1.2 [dcl.fct.spec] paragraph 5, which says:</P>

<BLOCKQUOTE>

The <TT>virtual</TT> specifier shall only be used in declarations
of nonstatic class member functions that appear within a
<I>member-specification</I> of a class definition; see
10.3 [class.virtual].

</BLOCKQUOTE>

<P>I don't think that excludes a friend declaration (which is a
valid <I>member-specification</I> by 9.2 [class.mem]).</P>

<P><U>John Spicer</U>: I agree that virtual should not be allowed
on friend declarations.  I think the wording in 7.1.2 [dcl.fct.spec] is intended to be <I>the</I> declaration of a
function within its class, although I think the wording should be
improved to make it clearer.</P>

<P><B>Proposed resolution (October, 2005):</B></P>

<P>Change 7.1.2 [dcl.fct.spec] paragraphs 5-6 as indicated:</P>

<BLOCKQUOTE>

<P>The <TT>virtual</TT> specifier shall <SPAN style="text-decoration:line-through;background-color:#FFA0A0">only</SPAN> be
used <SPAN style="font-weight:bold;background-color:#A0FFA0">only</SPAN> in <SPAN style="text-decoration:line-through;background-color:#FFA0A0">declarations</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">the initial declaration</SPAN>
of <SPAN style="font-weight:bold;background-color:#A0FFA0">a</SPAN> non-static class member <SPAN style="text-decoration:line-through;background-color:#FFA0A0">functions that appear within a
<I>member-specification</I> of a class definition</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">function</SPAN>;
see <secion_ref ref="10.3">10.3 [class.virtual]</secion_ref>.</P>

<P>The <TT>explicit</TT> specifier shall be used only
in <SPAN style="text-decoration:line-through;background-color:#FFA0A0">declarations</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">the declaration</SPAN> of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">constructors</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">a constructor</SPAN> within <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">its</SPAN> class definition; see
12.3.1 [class.conv.ctor].</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="424"></A><H4>424.
  
Wording problem with issue 56 resolution on redeclaring typedefs in class scope
</H4><B>Section: </B>7.1.3&#160; [dcl.typedef]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>25 June 2003<BR>


<P>[Voted into WP at March 2004 meeting.]</P>

<P>I wonder if perhaps the <A HREF="
     cwg_defects.html#56">core issue 56</A>
change in 7.1.3 [dcl.typedef] paragraph 2
wasn't quite careful enough.  The intent was to remove
the allowance for:</P>
<PRE>
  struct S {
    typedef int I;
    typedef int I;
  };
</PRE>
<P>but I think it also disallows the following:</P>
<PRE>
  class B {
    typedef struct A {} A;
    void f(struct B::A*p);
  };
</PRE>

<P>See also <A HREF="
     cwg_defects.html#407">issue 407</A>.</P>

<P><B>Proposed resolution (October 2003):</B></P>

<P>At the end of 7.1.3 [dcl.typedef]
paragraph 2, add the following:</P>
<BLOCKQUOTE>
In a given class scope, a <TT>typedef</TT> specifier can be used to redefine 
any <I>class-name</I> declared in that scope that is not
also a <I>typedef-name</I>
to refer to the type to which it already refers. [<I>Example:</I>
<PRE>
  struct S {
    typedef struct A {} A;  // OK
    typedef struct B B;     // OK
    typedef A A;            // error
  };
</PRE>
]
</BLOCKQUOTE>

<BR><BR><HR><A NAME="647"></A><H4>647.
  
Non-constexpr instances of constexpr constructor templates
</H4><B>Section: </B>7.1.5&#160; [dcl.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>12 Aug 2007<BR>


<P>[Voted into the WP at the September, 2008 meeting.]</P>



<P>According to 7.1.5 [dcl.constexpr] paragraph 5,</P>

<BLOCKQUOTE>

If the instantiated template specialization of a constexpr function
template would fail to satisfy the requirements for a constexpr
function, the <TT>constexpr</TT> specifier is ignored and the
specialization is not a constexpr function.

</BLOCKQUOTE>

<P>One would expect to see a similar provision for an instantiated
constructor template (because the requirements for a constexpr function
[paragraph 3] are different from the requirements for a constexpr
constructor [paragraph 4]), but there is none; constexpr constructor
templates are not mentioned.</P>

<P><U>Suggested resolution:</U></P>

<P>Change the wording of 7.1.5 [dcl.constexpr] paragraph 5 as
indicated:</P>

<BLOCKQUOTE>

If the instantiated template specialization of a constexpr function
template would fail to satisfy the requirements for a constexpr
function <SPAN style="font-weight:bold;background-color:#A0FFA0">or constexpr constructor, as appropriate to the function
template</SPAN>, the <TT>constexpr</TT> specifier is ignored and the
specialization is not a constexpr function <SPAN style="font-weight:bold;background-color:#A0FFA0">or constexpr
constructor</SPAN>.

</BLOCKQUOTE>

<P><B>Proposed resolution (June, 2008):</B></P>

<P><I>[Drafting note: This resolution goes beyond the problem
described in the issue discussion, which is one aspect of the general
failure of the existing wording to deal consistently with the
distinctions between constexpr functions and constexpr
constructors. The wording below attempts to rectify that problem
systematically.]</I></P>

<OL><LI><P>Change 7.1.5 [dcl.constexpr] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

A <TT>constexpr</TT> specifier used in <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a function declaration</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">the declaration of a function that is not a constructor</SPAN>
declares that function to be a <I>constexpr function</I>. Similarly, a
<TT>constexpr</TT> specifier used in a constructor declaration
declares that constructor to be a <I>constexpr
constructor</I>. Constexpr functions and constexpr constructors are
implicitly <TT>inline</TT> (7.1.2 [dcl.fct.spec]). <SPAN style="text-decoration:line-through;background-color:#FFA0A0">A constexpr
function shall not be virtual (10.3).</SPAN>

</BLOCKQUOTE>

<LI><P>Change 7.1.5 [dcl.constexpr] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

<P>The definition of a constexpr function shall satisfy the following
constraints:</P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">it shall not be virtual (10.3 [class.virtual])</SPAN></P></LI>

<LI><P>its return type shall be a literal type</P></LI>

<LI><P>each of its parameter types shall be a literal type</P></LI>

<LI><P>its function-body  shall be a compound-statement  of the form</P>

<UL><TT>{ return</TT> <I>expression</I> <TT>; }</TT></UL>

<P>where <I>expression</I> is a potential constant expression
(5.19 [expr.const])</P>

</LI>

<LI><P>every implicit conversion used in converting <I>expression</I>
to the function return type (8.5 [dcl.init]) shall be one of
those allowed in a constant expression (5.19 [expr.const]).</P></LI>

</UL>

<P>[<I>Example:</I>...</P>

</BLOCKQUOTE>

<LI><P>Change 7.1.5 [dcl.constexpr] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

<P>The definition of a constexpr constructor shall satisfy the
following constraints:</P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">each of its parameter types shall be a literal
type</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">its <I>function-body</I> shall not be a
<I>function-try-block</I></SPAN></P></LI>

<LI><P>the <I>compound-statement</I> of its <I>function-body</I> shall
be empty</P></LI>

<LI><P>every non-static data member and base class sub-object shall be
initialized (12.6.2 [class.base.init])</P></LI>

<LI><P>every constructor involved in initializing non-static data
members and base class sub-objects <SPAN style="font-weight:bold;background-color:#A0FFA0">invoked by a
<I>mem-initializer</I></SPAN> shall be a constexpr constructor <SPAN style="text-decoration:line-through;background-color:#FFA0A0">invoked
with potential constant expression arguments, if any.</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">every constructor argument and full-expression in a
<I>mem-initializer</I> shall be a potential constant
expression</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">every implicit conversion used in converting a constructor
argument to the corresponding parameter type and converting a
full-expression to the corresponding member type shall be one of those
allowed in a constant expression.</SPAN></P></LI>

</UL>

<P>A trivial copy constructor is also a constexpr
constructor. [<I>Example:</I> ...</P>

</BLOCKQUOTE>

<LI><P>Change 7.1.5 [dcl.constexpr] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

If the instantiated template specialization of a constexpr function
template would fail to satisfy the requirements for a constexpr
function <SPAN style="font-weight:bold;background-color:#A0FFA0">or constexpr constructor</SPAN>, the <TT>constexpr</TT>
specifier is ignored <SPAN style="text-decoration:line-through;background-color:#FFA0A0">and the specialization is not a constexpr
function</SPAN>.

</BLOCKQUOTE>

<LI><P>Change 7.1.5 [dcl.constexpr] paragraph 6 as follows:</P></LI>

<BLOCKQUOTE>

A <TT>constexpr</TT> specifier <SPAN style="text-decoration:line-through;background-color:#FFA0A0">used in</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">for</SPAN> a non-static
member function <SPAN style="text-decoration:line-through;background-color:#FFA0A0">definition</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">that is not a constructor</SPAN>
declares that member function to be <TT>const</TT> (9.3.1 [class.mfct.non-static]). [<I>Note:</I> ...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="648"></A><H4>648.
  
Constant expressions in constexpr initializers
</H4><B>Section: </B>7.1.5&#160; [dcl.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>12 Aug 2007<BR>


<P>[Voted into the WP at the September, 2008 meeting.]</P>



<P>The current wording of 7.1.5 [dcl.constexpr] paragraph 7
seems not quite correct.  It reads,</P>

<BLOCKQUOTE>

A <TT>constexpr</TT> specifier used in an object declaration declares
the object as <TT>const</TT>. Such an object shall be initialized, and
every expression that appears in its initializer (8.5 [dcl.init]) shall be a constant expression.

</BLOCKQUOTE>

<P>The phrase &#8220;every expression&#8221; is intended to cover
multiple arguments to a constexpr constructor and multiple expressions
in an aggregate initializer.  However, it could be read (incorrectly)
as saying that non-constant expressions cannot appear as subexpressions
in such initializers, even in places where they do not render the
full-expression non-constant (i.e., as unevaluated operands and in the
unselected branches of <TT>&amp;&amp;</TT>, <TT>||</TT>, and
<TT>?:</TT>).  Perhaps this problem could be remedied by replacing
&#8220;every expression&#8221; with &#8220;every
full-expression?&#8221;</P>

<P><B>Proposed resolution (June, 2008):</B></P>

<P>Change 7.1.5 [dcl.constexpr] paragraph 7 as follows:</P>

<BLOCKQUOTE>

A <TT>constexpr</TT> specifier used in an object declaration declares
the object as <TT>const</TT>. Such an object shall be <SPAN style="text-decoration:line-through;background-color:#FFA0A0">initialized,
and every expression that appears in its initializer (8.5)</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">initialized. If it is initialized by a constructor call, the
constructor shall be a constexpr constructor and every argument to the
constructor shall be a constant expression. Otherwise, every
full-expression that appears in its initializer</SPAN> shall be a
constant expression.  Every implicit conversion used...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="283"></A><H4>283.
  
Template <I>type-parameter</I>s are not syntactically <I>type-name</I>s
</H4><B>Section: </B>7.1.6.2&#160; [dcl.type.simple]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Clark Nelson
 &#160;&#160;&#160;

 <B>Date: </B>01 May 2001<BR>


<P>[Voted into WP at April 2003 meeting.]</P>

<P>Although 14.1 [temp.param] paragraph 3 contains an
assertion that</P>

<BLOCKQUOTE>

A <I>type-parameter</I> defines its identifier to be a
<I>type-name</I> (if declared with <TT>class</TT> or
<TT>typename</TT>)

</BLOCKQUOTE>

<P>the grammar in 7.1.6.2 [dcl.type.simple] paragraph 1
says that a <I>type-name</I> is either a <I>class-name</I>, an
<I>enum-name</I>, or a <I>typedef-name</I>.  The <I>identifier</I>
in a template <I>type-parameter</I> is none of those.  One
possibility might be to equate the <I>identifier</I> with a
<I>typedef-name</I> instead of directly with a <I>type-name</I>,
which would have the advantage of not requiring parallel treatment
of the two in situations where they are treated the same (e.g.,
in <I>elaborated-type-specifier</I>s, see
<A HREF="
     cwg_defects.html#245">issue 245</A>).  See also
<A HREF="
     cwg_defects.html#215">issue 215</A>.</P>

<P><B>Proposed resolution (Clark Nelson, March 2002):</B></P>

<P>In 14.1 [temp.param] paragraph 3,
change "A <I>type-parameter</I> defines its identifier to be a
<I>type-name</I>"
to "A <I>type-parameter</I> defines its identifier
to be a <I>typedef-name</I>"</P>

<P>In 7.1.6.3 [dcl.type.elab] paragraph 2,
change "If the identifier resolves to a <I>typedef-name</I> or a template
<I>type-parameter</I>"
to "If the identifier resolves to a <I>typedef-name</I>".</P>

<P>This has been consolidated with the edits for some other
issues.  See N1376=02-0034.</P>

<BR><BR><HR><A NAME="516"></A><H4>516.
  
Use of <TT>signed</TT> in bit-field declarations
</H4><B>Section: </B>7.1.6.2&#160; [dcl.type.simple]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>comp.std.c++
 &#160;&#160;&#160;

 <B>Date: </B>25 Apr 2005<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>

<P>7.1.6.2 [dcl.type.simple] paragraph 3 reads,</P>

<BLOCKQUOTE>

It is implementation-defined whether bit-fields and objects
of <TT>char</TT> type are represented as signed or unsigned
quantities.  The <TT>signed</TT> specifier forces <TT>char</TT>
objects and bit-fields to be signed; it is redundant with other
integral types.

</BLOCKQUOTE>

<P>The last sentence in that quote is misleading w.r.t. bit-fields. The
first sentence in that quote is correct but incomplete.</P>

<P>Proposed fix: change the two sentences to read:</P>

<BLOCKQUOTE>

It is implementation-defined whether objects of <TT>char</TT> type are
represented as signed or unsigned quantities. The <TT>signed</TT>
specifier forces <TT>char</TT> objects signed; it is redundant with
other integral types except when declaring bit-fields (9.6 [class.bit]).

</BLOCKQUOTE>

<P><B>Proposed resolution (October, 2005):</B></P>

<P>Change 7.1.6.2 [dcl.type.simple] paragraph 3 as indicated:</P>

<BLOCKQUOTE>

When multiple <I>simple-type-specifier</I>s are allowed, they can be
freely intermixed with other <I>decl-specifier</I>s in any
order. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I></SPAN> It is implementation-defined whether
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">bit-fields and</SPAN> objects of <TT>char</TT> type <SPAN style="font-weight:bold;background-color:#A0FFA0">and certain
bit-fields (9.6 [class.bit])</SPAN> are represented as signed
or unsigned quantities.  The <TT>signed</TT> specifier
forces <SPAN style="font-weight:bold;background-color:#A0FFA0">bit-fields and</SPAN> <TT>char</TT> objects <SPAN style="text-decoration:line-through;background-color:#FFA0A0">and
bit-fields</SPAN> to be signed; it is redundant <SPAN style="text-decoration:line-through;background-color:#FFA0A0">with other integral
types</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">in other contexts</SPAN>. <SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end note</I>]</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="651"></A><H4>651.
  
Problems in <TT>decltype</TT> specification and examples
</H4><B>Section: </B>7.1.6.2&#160; [dcl.type.simple]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>16 Aug 2007<BR>


<P>[Voted into the WP at the September, 2008 meeting.]</P>

<P>The second bullet of 7.1.6.2 [dcl.type.simple] paragraph 4
reads,</P>

<BLOCKQUOTE>

<UL>
<LI>otherwise, if <TT>e</TT> is a function call (5.2.2 [expr.call]) or an invocation of an overloaded operator
(parentheses around <TT>e</TT> are ignored), <TT>decltype(e)</TT> is
the return type of that function;</LI>
</UL>

</BLOCKQUOTE>

<P>The reference to &#8220;that function&#8221; is imprecise; it is
not the actual function called at runtime but the statically chosen
function (ignoring covariant return types in virtual functions).</P>

<P>Also, the examples in this paragraph have errors:</P>

<OL>

<LI><P>The declaration of <TT>struct A</TT> should end with a
semicolon.</P></LI>

<LI><P>The lines of the form <TT>decltype(...);</TT> are ill-formed;
they need a declarator.</P></LI>

</OL>

<P><B>Proposed Resolution (October, 2007):</B></P>

<P>Change 7.1.6.2 [dcl.type.simple] paragraph 4 as follows:</P>

<BLOCKQUOTE>

<P>The type denoted by <TT>decltype(e)</TT> is defined as follows:</P>

<UL>

<LI><P>if <TT>e</TT> is an <I>id-expression</I> or a class member
access (5.2.5 [expr.ref]), <TT>decltype(e)</TT> is the type
of the entity named by <TT>e</TT>. If there is no such entity, or
if <TT>e</TT> names a set of overloaded functions, the program is
ill-formed;</P></LI>

<LI><P>otherwise, if <TT>e</TT> is a function call (5.2.2 [expr.call]) or an invocation of an overloaded operator (parentheses
around <TT>e</TT> are ignored), <TT>decltype(e)</TT> is the return
type of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">that</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">the statically chosen</SPAN> function;</P></LI>

<LI><P>otherwise, if <TT>e</TT> is an lvalue, <TT>decltype(e)</TT>
is <TT>T&amp;</TT>, where <TT>T</TT> is the type of <TT>e</TT>;</P></LI>

<LI><P>otherwise, <TT>decltype(e)</TT> is the type
of <TT>e</TT>.</P></LI>
</UL>

<P>The operand of the <TT>decltype</TT> specifier is an unevaluated
operand (clause 5 [expr]).</P>

<P>[<I>Example:</I></P>
<PRE>
    const int&amp;&amp; foo();
    int i;
    struct A { double x; }<SPAN style="font-weight:bold;background-color:#A0FFA0">;</SPAN>
    const A* a = new A();
    decltype(foo())<SPAN style="font-weight:bold;background-color:#A0FFA0"> x1</SPAN>;      //<SPAN style="font-family:Times;font-style:italic"> type is </SPAN>const int&amp;&amp;
    decltype(i)<SPAN style="font-weight:bold;background-color:#A0FFA0"> x2</SPAN>;          //<SPAN style="font-family:Times;font-style:italic"> type is </SPAN>int
    decltype(a-&gt;x)<SPAN style="font-weight:bold;background-color:#A0FFA0"> x3</SPAN>;       //<SPAN style="font-family:Times;font-style:italic"> type is </SPAN>double
    decltype((a-&gt;x))<SPAN style="font-weight:bold;background-color:#A0FFA0"> x4</SPAN>;     //<SPAN style="font-family:Times;font-style:italic"> type is </SPAN>const double&amp;
</PRE>
<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="629"></A><H4>629.
  
<TT>auto</TT> parsing ambiguity
</H4><B>Section: </B>7.1.6.4&#160; [dcl.spec.auto]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>14 March 2007<BR>


<P>[Voted into the WP at the February, 2008 meeting as paper
J16/08-0056 = WG21 N2546.]</P>



<P>We've found an interesting parsing ambiguity with the new meaning of  
<TT>auto</TT>.  Consider:</P>

<PRE>
    typedef int T;
    void f() {
        auto T = 42;  // Valid or not?
    }
</PRE>

<P>The question here is whether T should be a type specifier or a  
storage class?  7.1.6.4 [dcl.spec.auto] paragraph 1 says,</P>

<BLOCKQUOTE>

The <TT>auto</TT> <I>type-specifier</I> has two meanings depending on
the context of its use. In a <I>decl-specifier-seq</I> that contains
at least one <I>type-specifier</I> (in addition to <TT>auto</TT>) that
is not a <I>cv-qualifier</I>, the <TT>auto</TT> <I>type-specifier</I>
specifies that the object named in the declaration has automatic
storage duration.

</BLOCKQUOTE>

<P>In this case, <TT>T</TT> is a <I>type-specifier</I>, so the
declaration is ill-formed: there is no <I>declarator-id</I>.  Many,
however, would like to see <TT>auto</TT> work &#8220;just like
<TT>int</TT>,&#8221; i.e., forcing <TT>T</TT> to be redeclared in
the inner scope.  Concerns cited included hijacking of the name in
templates and inline function bodies over the course of time if a
program revision introduces a type with that name in the surrounding
context.  Although it was pointed out that enclosing the name in
parentheses in the inner declaration would prevent any such
problems, this was viewed as unacceptably ugly.</P>

<P><B>Notes from the April, 2007 meeting:</B></P>

<P>The CWG wanted to avoid a rule like, &#8220;if <TT>auto</TT> can
be a <I>type-specifier</I>, it is&#8221; (similar to the existing
&#8220;if it can be a declaration, it is&#8221; rule) because of the
lookahead and backtracking difficulties such an approach would pose
for certain kinds of parsing techniques.  It was noted that the
difficult lookahead cases all involve parentheses, which would not
be a problem if only the &#8220;=&#8221; form of initializer were
permitted in <TT>auto</TT> declarations; only very limited lookahead
is required in that case.  It was also pointed out that the &#8220;if
it can be a <I>type-specifier</I>, it is&#8221; approach results in a
quiet change of meaning for cases like
</P>

<PRE>
    typedef int T;
    int n = 3;
    void f() {
        auto T(n);
    }
</PRE>

<P>This currently declares <TT>n</TT> to be an <TT>int</TT> variable
in the inner scope but would, under the full lookahead approach,
declare <TT>T</TT> to be a variable, quitely changing uses
of <TT>n</TT> inside <TT>f()</TT> to refer to the outer variable.</P>

<P>The consensus of the CWG was to pursue the change to require the
&#8220;=&#8221; form of initializer for <TT>auto</TT>.</P>

<P><B>Notes from the July, 2007 meeting:</B></P>

<P>See paper J16/07-0197 = WG21 N2337.  There was no consensus
among the CWG for either of the approaches recommended in the
paper; additional input and direction is required.</P>

<BR><BR><HR><A NAME="172"></A><H4>172.
  
Unsigned int as underlying type of enum
</H4><B>Section: </B>7.2&#160; [dcl.enum]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Bjarne Stroustrup
 &#160;&#160;&#160;

 <B>Date: </B>26 Sep 1999<BR>



<P>[Moved to DR at October 2002 meeting.]</P>



<P>According to 7.2 [dcl.enum]
 paragraph 5,
the underlying type of an enum is an unspecified integral type,
which could potentially be <TT>unsigned int</TT>.  The promotion
rules in 4.5 [conv.prom]
 paragraph 2 say
that such an enumeration value used in an expression will be promoted
to <TT>unsigned int</TT>.  This means that a conforming
implementation could give the value <TT>false</TT> for the
following code:</P>

<PRE>
    enum { zero };
    -1 &lt; zero;       // might be false
</PRE>

This is counterintuitive.  Perhaps the description of the underlying
type of an enumeration should say that an unsigned underlying type
can be used only if the values of the enumerators cannot be
represented in the corresponding signed type.  This approach would
be consistent with the treatment of integral promotion of
bitfields (4.5 [conv.prom]
 paragraph 3).

<P>On a related note,
7.2 [dcl.enum]
 paragraph 5 says,</P>

<BLOCKQUOTE>
the underlying type shall not be larger than <TT>int</TT> unless
the value of an enumerator cannot fit in an <TT>int</TT> or
<TT>unsigned int</TT>.
</BLOCKQUOTE>

<P>This specification does not allow for an enumeration like</P>

<PRE>
    enum { a = -1, b = UINT_MAX };
</PRE>

<P>Since each enumerator can fit in an <TT>int</TT>
or <TT>unsigned int</TT>, the underlying type is required to be
no larger than <TT>int</TT>, even though there is no such type that
can represent all the enumerators.</P>

<P><B>Proposed resolution (04/01; obsolete, see below):</B></P>

<P>Change 7.2 [dcl.enum] paragraph 5 as follows:</P>

<BLOCKQUOTE>

It is implementation-defined which integral type is used as
the underlying type for an enumeration except that the
underlying type shall not be larger than <TT>int</TT> unless
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">the value of an enumerator cannot fit in an <TT>int</TT>
or <TT>unsigned int</TT></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">neither <TT>int</TT> nor
<TT>unsigned int</TT> can represent all the enumerator values.
Furthermore, the underlying type shall not be an unsigned
type if the corresponding signed type can represent all the
enumerator values.</SPAN>

</BLOCKQUOTE>

<P>See also <A HREF="
     cwg_defects.html#58">issue 58</A>.</P>

<P><B>Notes from 04/01 meeting:</B></P>

<P>It was noted that 4.5 [conv.prom] promotes unsigned
types smaller than <TT>int</TT> to (signed) <TT>int</TT>.  The
signedness chosen by an implementation for small underlying types
is therefore unobservable, so the last sentence of the proposed
resolution above should apply only to <TT>int</TT> and larger
types.  This observation also prompted discussion of an
alternative approach to resolving the issue, in which the
<I>b<sub>min</sub></I> and <I>b<sub>max</sub></I> of the enumeration
would determine the promoted type rather than the underlying type.

</P>

<P><B>Proposed resolution (10/01):</B></P>

<P>Change 4.5 [conv.prom] paragraph 2 from
<BLOCKQUOTE>
An rvalue of type <TT>wchar_t</TT> (3.9.1 [basic.fundamental])
or an enumeration type
(7.2 [dcl.enum]) can be converted to an rvalue of
the first of the following
types  that  can represent all the values of its underlying type:
<TT>int</TT>, <TT>unsigned int</TT>, <TT>long</TT>, or <TT>unsigned long</TT>.
</BLOCKQUOTE>
to
<BLOCKQUOTE>
An rvalue of type <TT>wchar_t</TT> (3.9.1 [basic.fundamental])
can be converted to an rvalue of the first of the following
types  that  can represent all the values of its underlying type:
<TT>int</TT>, <TT>unsigned int</TT>, <TT>long</TT>, or <TT>unsigned long</TT>.
An rvalue of an enumeration type (7.2 [dcl.enum])
can be converted to an rvalue of the first of the following
types  that  can represent all the values of the enumeration (i.e., the
values in the range <I>b<SUB>min</SUB></I> to <I>b<SUB>max</SUB></I> as
described in 7.2 [dcl.enum]):
<TT>int</TT>, <TT>unsigned int</TT>, <TT>long</TT>, or <TT>unsigned long</TT>.
</BLOCKQUOTE>
</P>

<BR><BR><HR><A NAME="377"></A><H4>377.
  
Enum whose enumerators will not fit in any integral type
</H4><B>Section: </B>7.2&#160; [dcl.enum]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mark Mitchell
 &#160;&#160;&#160;

 <B>Date: </B>30 August 2002<BR>


<P>[Voted into WP at April 2003 meeting.]</P>

<P>7.2 [dcl.enum] defines the underlying type of an
enumeration as an integral type "that can represent all the enumerator
values defined in the enumeration".</P>

<P>What does the standard say about this code:</P>
<PRE>
  enum E { a = LONG_MIN, b = ULONG_MAX };
</PRE>
<P>?</P>

<P>I think this should be ill-formed.</P>

<P><B>Proposed resolution:</B></P>

<P>In 7.2 [dcl.enum] paragraph 5 after
<BLOCKQUOTE>
The <I>underlying</I> <I>type</I> of an enumeration is an integral type
that can represent all the enumerator values defined in the enumeration.
</BLOCKQUOTE>
insert
<BLOCKQUOTE>
If no integral type can represent all the enumerator values,
the enumeration is ill-formed.
</BLOCKQUOTE>
</P>

<BR><BR><HR><A NAME="518"></A><H4>518.
  
Trailing comma following <I>enumerator-list</I>
</H4><B>Section: </B>7.2&#160; [dcl.enum]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Charles Bryant
 &#160;&#160;&#160;

 <B>Date: </B>10 May 2005<BR>


<P>[Voted into WP at April, 2006 meeting.]</P>

<P>The C language (since C99), and some C++ compilers, accept:</P>

<PRE>
    enum { FOO, };
</PRE>

<P>as syntactically valid. It would be useful</P>

<UL>

<LI><P>for machine generated code</P></LI>

<LI><P>for minimising changes when editing</P></LI>

<LI><P>to allow a distinction between the final item being intended as
an ordinary item or as a limit:</P></LI>

<PRE>
  enum { red, green, blue, num_colours };  // note no comma
  enum { fred, jim, sheila, };             // last is not special
</PRE>

</UL>

<P>This proposed change is to permit a trailing comma in enum by adding:</P>

<BLOCKQUOTE>

<TT>enum</TT> <I>identifier<SUB>opt</SUB></I> <TT>{</TT> <I>enumerator-list</I> <TT>,</TT> <TT>}</TT> 

</BLOCKQUOTE>

<P>as an alternative definition for the <I>enum-specifier</I> nonterminal
in <secton_ref ref="7.2">7.2 [dcl.enum]</secton_ref> paragraph 1.</P>

<P><B>Proposed resolution (October, 2005):</B></P>

<P>Change the grammar in 7.2 [dcl.enum] paragraph 1 as
indicated:</P>

<BLOCKQUOTE>

<I>enum-specifier:</I>
<UL><TT>enum</TT> <I>identifier<SUB>opt</SUB> </I><TT>{</TT><I> enumerator-list<SUB>opt</SUB> </I><TT>}</TT></UL>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><UL><TT>enum</TT> <I>identifier<SUB>opt</SUB> </I><TT>{</TT><I> enumerator-list </I><TT>,</TT> <TT>}</TT></UL></SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="660"></A><H4>660.
  
Unnamed scoped enumerations
</H4><B>Section: </B>7.2&#160; [dcl.enum]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>15 November 2007<BR>


<P>[Voted into the WP at the September, 2008 meeting.]</P>

<P>The current specification of scoped enumerations does not appear
to forbid an example like the following, even though the enumerator
<TT>e</TT> cannot be used:</P>

<PRE>
    enum class { e };
</PRE>

<P>This might be covered by 7 [dcl.dcl] paragraph 3,</P>

<BLOCKQUOTE>

In a <I>simple-declaration</I>, the
optional <I>init-declarator-list</I> can be omitted only when
declaring a class (clause 9 [class]) or enumeration
(7.2 [dcl.enum]), that is, when
the <I>decl-specifier-seq</I> contains either
a <I>class-specifier</I>, an <I>elaborated-type-specifier</I> with a
<I>class-key</I> (9.1 [class.name]), or
an <I>enum-specifier</I>. In these cases and whenever a
<I>class-specifier</I> or <I>enum-specifier</I> is present in the
<I>decl-specifier-seq</I>, the identifiers in these specifiers are
among the names being declared by the declaration
(as <I>class-name</I>s, <I>enum-name</I>s, or <I>enumerator</I>s,
depending on the syntax). In such cases, and except for the
declaration of an unnamed bit-field (9.6 [class.bit]), the
<I>decl-specifier-seq</I> shall introduce one or more names into the
program, or shall redeclare a name introduced by a previous
declaration.

</BLOCKQUOTE>

<P>which, when combined with paragraph 2,</P>

<BLOCKQUOTE>

A declaration occurs in a scope (3.3 [basic.scope]); the scope
rules are summarized in 3.4 [basic.lookup]. A declaration that
declares a function or defines a class, namespace, template, or
function also has one or more scopes nested within it. These nested
scopes, in turn, can have declarations nested within them. Unless
otherwise stated, utterances in clause 7 [dcl.dcl] about
components in, of, or contained by a declaration or subcomponent
thereof refer only to those components of the declaration that
are <I>not</I> nested within scopes nested within the declaration.

</BLOCKQUOTE>

<P>appears to rule out the similar class definition,</P>

<PRE>
    struct { int m; };
</PRE>

<P>However, a scoped enumeration is not listed in paragraph 2 among the
constructs containing a nested scope (although 3.3.8 [basic.scope.enum]
does describe &#8220;enumeration scope&#8221;); furthermore, an
<I>enumerator-definition</I> is not formally a &#8220;nested
declaration.&#8221;  If unusable scoped enumeration definitions are to
be banned, these shortcomings in 7 [dcl.dcl] paragraph 2
must be addressed.  (A note in 7.2 [dcl.enum] mentioning that
unnamed scoped enumerations are not allowed would also be helpful.)</P>

<P><B>Notes from the February, 2008 meeting:</B></P>

<P>The consensus was to require that the <I>identifier</I> be
present in an <I>enum-specifier</I> unless the <I>enum-key</I> is
<TT>enum</TT>.</P>

<P><B>Proposed resolution (June, 2008):</B></P>

<P>Change 7.2 [dcl.enum] paragraph 2 as follows:</P>

<BLOCKQUOTE>

...The <I>enum-key</I>s <TT>enum class</TT> and <TT>enum struct</TT>
are semantically equivalent; an enumeration type declared with one of
these is a <I>scoped enumeration</I>, and its <I>enumerator</I>s are
<I>scoped enumerators</I>. <SPAN style="font-weight:bold;background-color:#A0FFA0">The optional <I>identifier</I> shall not be
omitted in the declaration of a scoped enumeration.</SPAN> The
<I>type-specifier-seq</I> of an <I>enum-base</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="540"></A><H4>540.
  
Propagation of cv-qualifiers in reference-to-reference collapse
</H4><B>Section: </B>7.3.1&#160; [namespace.def]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Russell Yanofsky
 &#160;&#160;&#160;

 <B>Date: </B>24 September 2005<BR>


<P>[Voted into the WP at the October, 2006 meeting as part of
paper J16/06-0188 = WG21 N2118.]</P>



<P>The resolution of <A HREF="
     cwg_defects.html#106">issue 106</A> specifies
that an attempt to create a type &#8220;reference to <I>cv1</I>
<TT>T</TT>,&#8221; where <TT>T</TT> is a typedef or template parameter
of the type &#8220;reference to <I>cv2</I> <TT>S</TT>,&#8221; actually
creates the type &#8220;reference to <I>cv12</I> <TT>S</TT>,&#8221;
where <I>cv12</I> is the union of the two sets of cv-qualifiers.</P>

<P>One objection that has been raised to this resolution is that it
is inconsistent with the treatment of cv-qualification and references
specified in 8.3.2 [dcl.ref] paragraph 1, which says
that cv-qualifiers applied to a typedef or template argument that is
a reference type are ignored.  For example:</P>

<PRE>
    typedef int&amp; intref;
    const intref r1;       //<SPAN style="font-family:Times;font-style:italic"> reference to int</SPAN>
    const intref&amp; r2;      //<SPAN style="font-family:Times;font-style:italic"> reference to const int</SPAN>
</PRE>

<P>In fact, however, these two declarations are quite different. In the
declaration of <TT>r1</TT>, <TT>const</TT> applies to a
&#8220;top-level&#8221; reference, while in the declaration of <TT>t2</TT>,
it occurs under a reference.  In general, cv-qualifiers that appear under
a reference are preserved, even if the type appears in a context in which
top-level cv-qualification is removed, for example, in determining the
type of a function from parameter types (8.3.5 [dcl.fct]
paragraph 3) and in template argument deduction
(14.8.2.1 [temp.deduct.call] paragraph 2).</P>

<P>Another objection to the resolution is that type composition gives
different results in a single declaration than it does when separated
into two declarations.  For example:</P>

<PRE>
    template &lt;class T&gt;
    struct X {
       typedef T const T_const;
       typedef T_const&amp; type1;
       typedef T const&amp; type2;
    };

    X&lt;int&amp;&gt;::type1 t1;    // int&amp;
    X&lt;int&amp;&gt;::type2 t2;    // int const&amp;
</PRE>

<P>The initial motivation for the propagation of cv-qualification
during reference-to-reference collapse was to prevent inadvertent
loss of cv-qualifiers in contexts in which it could make a
difference.  For example, if the resolution were changed to discard,
rather than propagate, embedded cv-qualification, overload
resolution could surprisingly select a non-const version of a member
function:</P>

<PRE>
   struct X {
       void g();
       void g() const;
   };

   template &lt;typename T&gt; struct S {
       static void f(const T&amp; t) {
           t.g();    //<SPAN style="font-family:Times;font-style:italic"> const or non-const???</SPAN>
       }
   };

   X x;

   void q() {
       S&lt;X&gt;::f(x);    //<SPAN style="font-family:Times;font-style:italic"> calls </SPAN>X::g() const
       S&lt;X&amp;&gt;::f(x);   //<SPAN style="font-family:Times;font-style:italic"> calls </SPAN>X::g()
   }
</PRE>

<P>Another potentially-surprising outcome of dropping embedded
cv-qualifiers would be:</P>

<PRE>
   template &lt;typename T&gt; struct A {
       void f(T&amp;);          //<SPAN style="font-family:Times;font-style:italic"> mutating version</SPAN>
       void f(const T&amp;);    //<SPAN style="font-family:Times;font-style:italic"> non-mutating version</SPAN>
   };

   A&lt;int&amp;&gt; ai;    //<SPAN style="font-family:Times;font-style:italic"> Ill-formed: </SPAN>A&lt;int&amp;&gt;<SPAN style="font-family:Times;font-style:italic"> declares</SPAN> f(int&amp;)<SPAN style="font-family:Times;font-style:italic"> twice</SPAN>

</PRE>

<P>On the other hand, those who would like to see the resolution
changed to discard embedded cv-qualifiers observe that these examples
are too simple to be representative of real-world code.  In general,
it is unrealistic to expect that a template written with non-reference
type parameters in mind will automatically work correctly with
reference type parameters as a result of applying the issue 106
resolution.  Instead, template metaprogramming allows the template
author to choose explicitly whether cv-qualifiers are propagated or
dropped, according to the intended use of the template, and it is more
important to respect the reasonable intuition that a declaration
involving a template parameter will not change the type that the
parameter represents.</P>

<P>As a sample of real-world code, <TT>tr1::tuple</TT> was examined.
In both cases &#8212; the current resolution of issue 106 and one in
which embedded cv-qualifiers were dropped &#8212; some metaprogramming
was required to implement the intended interface, although the version
reflecting the revised resolution was somewhat simpler.</P>

<P><B>Notes from the October, 2005 meeting:</B></P>

<P>The consensus of the CWG was that the resolution of
<A HREF="
     cwg_defects.html#106">issue 106</A> should be revised not to
propagate embedded cv-qualification.</P>

<P><B>Note (February, 2006):</B></P>

<P>The wording included in the rvalue-reference paper,
J16/06-0022 = WG21 N1952, incorporates changes intended to implement
the October, 2005 consensus of the CWG.</P>

<BR><BR><HR><A NAME="11"></A><H4>11.
  
How do the keywords typename/template interact with using-declarations?
</H4><B>Section: </B>7.3.3&#160; [namespace.udecl]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Bill Gibbons
 &#160;&#160;&#160;

 <B>Date: </B>unknown<BR>



<P>[Voted into WP at March 2004 meeting.]</P>



<P><B><U>Issue 1:</U></B></P>

<P>The working paper is not clear about how the typename/template keywords
interact with using-declarations:</P>
<PRE>
     template&lt;class T&gt; struct A {
         typedef int X;
     };
     
     template&lt;class T&gt; void f() {
         typename A&lt;T&gt;::X a;      // OK
         using typename A&lt;T&gt;::X;  // OK
         typename X b;  // ill-formed; X must be qualified
         X c;  // is this OK?
     }
</PRE>
When the rules for <TT>typename</TT> and the similar use of <TT>template</TT>
were decided, we chose to require that they be used at every reference.
The way to avoid <TT>typename</TT> at every use is to declare a typedef;
then the typedef name itself is known to be a type. For <I>using-declaration</I>s,
we decided that they do not introduce new declarations but rather are aliases
for existing declarations, like symbolic links. This makes it unclear whether
the declaration "<TT>X c;</TT>" above should be well-formed, because there
is no new name declared so there is no declaration with a "this is a type"
attribute. (The same problem would occur with the <TT>template</TT> keyword
when a member template of a dependent class is used). I think these are
the main options:
<OL>
<LI>
Continue to allow <TT>typename</TT> in <I>using-declaration</I>s, and <TT>template</TT>
(for member templates) too. Attach the "is a type" or "is a template"
attribute to the placeholder name which the using-declaration "declares"</LI>

<LI>
Disallow <TT>typename</TT> and <TT>template</TT> in <I>using-declaration</I>s
(just as <I>class-key</I>s are disallowed now). Allow <TT>typename</TT>
and <TT>template</TT> before unqualified names which refer to dependent
qualified names through <I>using-declaration</I>s.</LI>

<LI>
Document that this is broken.</LI>
</OL>
<B>Suggested Resolution:</B>

<P>The core WG already resolved this issue according to (1), but the wording
does not seem to have been added to the standard. New wording needs to
be drafted.</P>

<P><B><U>Issue 2:</U></B></P>

<P>Either way, one more point needs clarification. If the first option
is adopted:</P>
<PRE>
     template&lt;class T&gt; struct A {
         struct X { };
     };
     
     template&lt;class T&gt; void g() {
         using typename A&lt;T&gt;::X;
         X c;    // if this is OK, then X by itself is a  type
         int X;  // is this OK?
     }
</PRE>
When "<TT>g</TT>" is instantiated, the two declarations of <TT>X</TT> are compatible
(7.3.3 [namespace.udecl]
 paragraph 10).
But there is no way to know this when the definition of "<TT>g</TT>" is
compiled. I think this case should be ill-formed under the first option.
(It cannot happen under the second option.) If the second option is adopted:
<PRE>
     template&lt;class T&gt; struct A {
         struct X { };
     };
     
     template&lt;class T&gt; void g() {
         using A&lt;T&gt;::X;
         int X;  // is this OK?
     }
</PRE>
Again, the instantiation would work but there is no way to know that in
the template definition. I think this case should be ill-formed under the
second option. (It would already be ill-formed under the first option.)

<P>From John Spicer:</P>
<BLOCKQUOTE>The "not a new declaration" decision is more of a guiding principle
than a hard and fast rule. For example, a name introduced in a 
<I>using-declaration</I>
can have different access than the original declaration.

<P>Like symbolic links, a <I>using-declaration</I> can be viewed as a declaration
that declares an alias to another name, much like a typedef.</P>

<P>In my opinion, "<TT>X c;</TT>" is already well-formed. Why would we permit
<TT>typename</TT> to be used in a <I>using-declaration</I> if not to permit this
precise usage?</P>

<P>In my opinion, all that needs to be done is to clarify that the "typeness"
or "templateness" attribute of the name referenced in the <I>using-declaration</I>
is attached to the alias created by the <I>using-declaration</I>. This is
solution #1.</P></BLOCKQUOTE>
<B>Tentative Resolution:</B>

<P>The rules for multiple declarations with the same name in the same scope
should treat a <I>using-declaration</I> which names a type as a typedef,
just as a typedef of a class name is treated as a class declaration. This
needs drafting work. Also see <A HREF="
     cwg_active.html#36">Core issue 36</A>.</P>

<P><B>Rationale (04/99):</B> Any semantics associated with the
<TT>typename</TT> keyword in <I>using-declaration</I>s should be considered an
extension.</P>

<P><B>Notes from the April 2003 meeting:</B></P>

<P>This was reopened because we are now considering extensions again.
We agreed that it is desirable for the typename to be "sticky" on
a using-declaration, i.e., references to the name introduced by
the using-declaration are known to be type names without the use
of the typename keyword (which can't be specified on an unqualified
name anyway, as of now).  The related issue with the template keyword
already has a separate issue <A HREF="
     cwg_closed.html#109">109</A>.</P>

<P>Issue 2 deals with the "struct hack."
There is an example in 7.3.3 [namespace.udecl] paragraph 10
that shows a use of using-declarations to import two names that
coexist because of the "struct hack."  After some deliberation,
we decided that the template-dependent using-declaration case is
different enough that we did not have to support the "struct hack"
in that case.
A name introduced in such a case is like a typedef, and no other
hidden type can be accessed through an elaborated type specifier.</P>

<P><B>Proposed resolution (April 2003, revised October 2003):</B></P>

<P>Add a new paragraph to the bottom of 7.3.3 [namespace.udecl]:</P>

<BLOCKQUOTE>
If a <I>using-declaration</I> uses
the keyword <TT>typename</TT> and specifies a dependent name
(14.6.2 [temp.dep]), the
name introduced by the <I>using-declaration</I> is treated as a
<I>typedef-name</I> (7.1.3 [dcl.typedef]).
</BLOCKQUOTE>

<BR><BR><HR><A NAME="258"></A><H4>258.
  
<I>using-declaration</I>s and cv-qualifiers
</H4><B>Section: </B>7.3.3&#160; [namespace.udecl]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Liam Fitzpatrick
 &#160;&#160;&#160;

 <B>Date: </B>2 Nov 2000<BR>


<P>[Voted into WP at April 2003 meeting.]</P>



<P>According to 7.3.3 [namespace.udecl] paragraph 12,</P>

<BLOCKQUOTE>

When a <I>using-declaration</I> brings names from a base class into a
derived class scope, member functions in the derived class override
and/or hide member functions with the same name and parameter types in
a base class (rather than conflicting).

</BLOCKQUOTE>

<P>Note that this description says nothing about the cv-qualification
of the hiding and hidden member functions.  This means, for instance,
that a non-const member function in the derived class hides a const
member function with the same name and parameter types instead of
overloading it in the derived class scope.  For example,</P>

<PRE>
    struct A {
      virtual int f() const;
      virtual int f();
    };
    struct B: A {
      B();
      int f();
      using A::f;
    };

    const B cb;
    int i = cb.f(); // ill-formed: A::f() const hidden in B

</PRE>

<P>The same terminology is used in 10.3 [class.virtual]
paragraph 2:</P>

<BLOCKQUOTE>

If a virtual member function <TT>vf</TT> is declared in a class
<TT>Base</TT> and in a class <TT>Derived</TT>, derived directly or
indirectly from <TT>Base</TT>, a member function <TT>vf</TT> with the
same name and same parameter list as <TT>Base::vf</TT> is declared,
then <TT>Derived::vf</TT> is also virtual (whether or not it is so
declared) and it overrides <TT>Base::vf</TT>.

</BLOCKQUOTE>

<P><B>Notes on the 04/01 meeting:</B></P>

<P> The hiding and overriding should
be on the basis of the function signature, which includes any
cv-qualification on the function.</P>

<P><B>Proposed resolution (04/02):</B></P>

<P>In 7.3.3 [namespace.udecl] paragraph 12 change:
<BLOCKQUOTE>
When a <I>using-declaration</I> brings names from a base class into a
derived class scope, member functions in the derived class override and/or
hide member functions with the same name and parameter types in a base
class (rather than conflicting).
</BLOCKQUOTE>
to read:
<BLOCKQUOTE>
When a <I>using-declaration</I> brings names from a base class into a
derived class scope, member functions and member function templates in
the derived class override and/or hide member functions and member
function templates with the same name, parameter-type-list
(8.3.5 [dcl.fct]),
and <I>cv</I>-qualification in a base class (rather than conflicting).
</BLOCKQUOTE>
</P>
<P>
In 10.3 [class.virtual] paragraph 2 change:
<BLOCKQUOTE>
If a virtual member function <TT>vf</TT> is declared in a class
<TT>Base</TT> and in a class <TT>Derived</TT>, derived directly or
indirectly from <TT>Base</TT>, a member function <TT>vf</TT> with the
same name and same parameter list as <TT>Base::vf</TT> is declared,
then <TT>Derived::vf</TT> is also virtual (whether or not it is so
declared) and it overrides <TT>Base::vf</TT>.
</BLOCKQUOTE>
to read:
<BLOCKQUOTE>
If a virtual member function <TT>vf</TT> is declared in a class
<TT>Base</TT> and in a class <TT>Derived</TT>, derived directly or
indirectly from <TT>Base</TT>, a member function <TT>vf</TT> with the
same name, parameter-type-list (8.3.5 [dcl.fct]), and
<I>cv</I>-qualification as <TT>Base::vf</TT>
is declared, then <TT>Derived::vf</TT> is also virtual (whether or not
it is so declared) and it overrides <TT>Base::vf</TT>.
</BLOCKQUOTE>
</P>

<P>See <A HREF="
     cwg_defects.html#140">issue 140</A> for the definition of
<I>parameter-type-list</I>.</P>
<BR><BR><HR><A NAME="460"></A><H4>460.
  
Can a <I>using-declaration</I> name a namespace?
</H4><B>Section: </B>7.3.3&#160; [namespace.udecl]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>12 Feb 2004<BR>


<P>[Voted into WP at April 2005 meeting.]</P>

<P>Can a using-declaration be used to import a namespace?</P>
<PRE>
namespace my_namespace{
  namespace my_namespace2 {
    int function_of_my_name_space(){ return 2;}
  }
}

int main (){
  using  ::my_namespace::my_namespace2;
  return my_namespace2::function_of_my_name_space();
}
</PRE>
<P>Several popular compilers give an error on this, but there
doesn't seem to be anything in 7.3.3 [namespace.udecl] that
prohibits it.  It should be noted that the user can get the same
effect by using a namespace alias:</P>
<PRE>
  namespace my_namespace2 = ::my_namespace::my_namespace2;
</PRE>

<P><B>Notes from the March 2004 meeting:</B></P>

<P>We agree that it should be an error.</P>

<P><B>Proposed resolution (October, 2004):</B></P>

<P>Add the following as a new paragraph after 7.3.3 [namespace.udecl] paragraph 5:</P>

<BLOCKQUOTE>

A <I>using-declaration</I> shall not name a namespace;

</BLOCKQUOTE>

<BR><BR><HR><A NAME="4"></A><H4>4.
  
Does extern "C" affect the linkage of function names with internal linkage?
</H4><B>Section: </B>7.5&#160; [dcl.link]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Anderson
 &#160;&#160;&#160;

 <B>Date: </B>unknown<BR>



<P>[Moved to DR at 4/01 meeting.]</P>



<P>7.5 [dcl.link]
 paragraph 6 says the following:</P>
<UL>At most one of a set of overloaded functions with a particular name
can have C linkage.</UL>
Does this apply to static functions as well? For example, is the following
well-formed?
<PRE>
        extern "C" {
            static void f(int) {}
            static void f(float) {}
        };
</PRE>
Can a function with internal linkage "have C linkage" at all (assuming
that phrase means "has extern "C" linkage"), for how can a function be
extern "C" if it's not extern? The function <B>type</B> can have extern
"C" linkage &#8212; but I think that's independent of the linkage of the function
<B>name</B>. It should be perfectly reasonable to say, in the example above,
that extern "C" applies only to the types of <TT>f(int)</TT> and <TT>f(float)</TT>,
not to the function names, and that the rule in 7.5 [dcl.link]
 paragraph 6 doesn't apply.
<P><B>Suggested  resolution:</B> The extern "C" linkage specification applies
only to the type of functions with internal linkage, and therefore some
of the rules that have to do with name overloading don't apply.</P>

<P><B>Proposed Resolution:</B></P>

<P>The intent is to distingush <I>implicit</I> linkage from explicit linkage
for both name linkage and language (function type) linkage. (It might
be more clear to use the terms <I>name linkage</I> and <I>type linkage</I>
to distinguish these concepts. A function can have a name with one
kind of linkage and a type with a different kind of linkage. The
function itself has no linkage: it has no name, only the declaration has
a name. This becomes more obvious when you consider function pointers.)</P>

<P>The tentatively agreed proposal is to apply implicit linkage to names
declared in brace-enclosed linkage specifications and to non-top-level
names declared in simple linkage specifications; and to apply explicit
linkage to top-level names declared in simple linkage specifications.</P>

<P>The language linkage of any function type formed through a function
declarator is that of the nearest enclosing <I>linkage-specification</I>.
For purposes of determining whether the declaration of a namespace-scope
name matches a previous declaration, the language linkage portion of the
type of a function declaration (that is, the language linkage of the function
itself, not its parameters, return type or exception specification) is
ignored.</P>

<P>For a <I>linkage-specification</I> using braces, i.e.</P>
<BLOCKQUOTE><TT>extern</TT> <I>string-literal</I> <TT>{</TT> <I>declaration-seq</I><SUB>opt</SUB>
<TT>}</TT></BLOCKQUOTE>
the linkage of any declaration of a namespace-scope name (including local
externs) which is not contained in a nested <I>linkage-specification</I>,
is not declared to have no linkage (static), and does not match a previous
declaration is given the linkage specified in the <I>string-literal.</I>
The language linkage of the type of any function declaration of a namespace-scope
name (including local externs) which is not contained in a nested <I>linkage-specification</I>
and which is declared with function declarator syntax is the same as that
of a matching previous declaration, if any, else is specified by <I>string-literal</I>.

<P>For a <I>linkage-specification</I> without braces, i.e.</P>
<BLOCKQUOTE><TT>extern</TT> <I>string-literal</I> <I>declaration</I></BLOCKQUOTE>
<P>the linkage of the names declared in the top-level declarators of <I>declaration</I>
is specified by <I>string-literal</I>; if this conflicts with the linkage
of any matching previous declarations, the program is ill-formed. The language
linkage of the type of any top-level function declarator is specified by
<I>string-literal</I>; if this conflicts with the language linkage of the
type of any matching previous function declarations, the program is ill-formed.
The effect of the <I>linkage-specification</I> on other (non top-level)
names declared in <I>declaration</I> is the same as that of the brace-enclosed
form.</P>



<P><U>Bill Gibbons</U>: In particular, these should be well-formed:</P>

<PRE>
    extern "C" void f(void (*fp)());   // parameter type is pointer to
                                       // function with C language linkage
    extern "C++" void g(void (*fp)()); // parameter type is pointer to
                                       // function with C++ language linkage

    extern "C++" {                     // well-formed: the linkage of "f"
        void f(void(*fp)());           // and the function type used in the
    }                                  // parameter still "C"

    extern "C" {                       // well-formed: the linkage of "g"
        void g(void(*fp)());           // and the function type used in the
    }                                  // parameter still "C++"
</PRE>

<P>but these should not:</P>

<PRE>
    extern "C++" void f(void(*fp)());  // error - linkage of "f" does not
                                       // match previous declaration
                                       // (linkage of function type used in
                                       // parameter is still "C" and is not
                                       // by itself ill-formed)
    extern "C" void g(void(*fp)());    // error - linkage of "g" does not
                                       // match previous declaration
                                       // (linkage of function type used in
                                       // parameter is still "C++" and is not
                                       // by itself ill-formed)
</PRE>

<P>That is, non-top-level declarators get their linkage from matching
declarations, if any, else from the nearest enclosing linkage
specification.  (As already described, top-level declarators in a
brace-enclosed linkage specification get the linkage from matching
declarations, if any, else from the linkage specifcation; while
top-level declarators in direct linkage specifications get their
linkage from that specification.)</P>

<P><U>Mike Miller</U>: This is a pretty significant change from the
current specification, which treats the two forms of language linkage
similarly for most purposes.  I don't understand why it's desirable to
expand the differences.</P>

<P>It seems very unintuitive to me that you could have a top-level
declaration in an <TT>extern "C"</TT>  block that would <I>not</I>
receive "C" linkage.</P>

<P>In the current standard, the statement in
7.5 [dcl.link] paragraph 4 that</P>

<BLOCKQUOTE>

the specified language linkage applies to the function types of all
function declarators, function names, and variable names introduced by
the declaration(s)

</BLOCKQUOTE>

<P>applies to both forms.  I would thus expect that in</P>

<PRE>
    extern "C" void f(void(*)());
    extern "C++" {
        void f(void(*)());
    }
    extern "C++" f(void(*)());
</PRE>

<P>both "C++" declarations would be well-formed, declaring an
overloaded version of <TT>f</TT> that takes a pointer to a "C++"
function as a parameter.  I wouldn't expect that either declaration
would be a redeclaration (valid or invalid) of the "C" version of
<TT>f</TT>.</P>

<P><U>Bill Gibbons</U>: The potential difficulty is the matching
process and the handling of deliberate overloading based on language
linkage.  In the above examples, how are these two declarations
matched:</P>

<PRE>
    extern "C" void f(void (*fp1)());

    extern "C++" {
        void f(void(*fp2)());
    }
</PRE>

<P>given that the linkage that is part of fp1 is "C" while the linkage (prior
to the matching process) that is part of fp2 is "C++"?</P>

<P>The proposal is that the linkage which is part of the parameter type is not
determined until after the match is attempted.  This almost always correct
because you can't overload "C" and "C++" functions; so if the function names
match, it is likely that the declarations are supposed to be the
same.</P>

<P><U>Mike Miller</U>: This seems like more trouble than it's worth.
This comparison of function types ignoring linkage specifications is,
as far as I know, not found anywhere in the current standard.  Why do
we need to invent it?</P>

<P><U>Bill Gibbons</U>: It is possible to construct pathological cases where this fails, e.g.</P>

<PRE>
    extern "C" typedef void (*PFC)();  // pointer to "C" linkage function
    void f(PFC);         // parameter is pointer to "C" function
    void f(void (*)());  // matching declaration or overload based on
                         // difference in linkage type?
</PRE>

<P>It is reasonable to require explicit typedefs in this case so that
in the above example the second function declaration gets its parameter type
function linkage from the first function declaration.</P>

<P>(In fact, I think you can't get into this situation without having already
used typedefs to declare different language linkage for the top-level and
parameter linkages.)</P>

<P>For example, if the intent is to overload based on linkage a
typedef is needed:</P>

<PRE>
    extern "C" typedef void (*PFC)();  // pointer to "C" linkage function
    void f(PFC);              // parameter is pointer to "C" function
    typedef void (*PFCPP)();  // pointer to "C++" linkage function
    void f(PFCPP);            // parameter is pointer to "C++" function
</PRE>

<P>In this case the two function declarations refer to different
functions.</P>

<P><U>Mike Miller</U>: This seems pretty strange to me.  I think it
would be simpler to determine the type of the parameter based on the
containing linkage specification (implicitly "C++") and require a
typedef if the user wants to override the default behavior.  For
example:</P>

<PRE>
    extern "C" {
        typedef void (*PFC)();    // pointer to "C" function
        void f(void(*)());        // takes pointer to "C" function
    }

    void f(void(*)());            // new overload of "f", taking
                                  // pointer to "C++" function

    void f(PFC);                  // redeclare extern "C" version
</PRE>

<P><B>Notes from 04/00 meeting:</B></P>

<P>The following changes were tentatively approved, but because they
do not completely implement the proposal above the issue is being kept
for the moment in "drafting" status.</P>

<P><B>Notes from 10/00 meeting:</B></P>

<P>After further discussion, the core language working group
determined that the more extensive proposal described above is
not needed and that the following changes are sufficient.</P>

<P><B>Proposed resolution (04/01):</B></P>

<OL>
<LI><P>Change the first sentence of 7.5 [dcl.link]
paragraph 1 from</P>

<BLOCKQUOTE>
All function types, function names, and variable names
have a language linkage.
</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>
All function types, function names with external
linkage, and variable names with external linkage have
a language linkage.
</BLOCKQUOTE>
</LI>

<LI>Change the following sentence of 7.5 [dcl.link]
paragraph 4:

<BLOCKQUOTE>
In a <I>linkage-specification</I>, the specified language
linkage applies to the function types of all function
declarators, function names, and variable names
introduced by the declaration(s).
</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>
In a <I>linkage-specification</I>, the specified language
linkage applies to the function types of all function
declarators, function names with external linkage, and
variable names with external linkage declared within
the <I>linkage-specification</I>.
</BLOCKQUOTE>
</LI>

<LI><P>Add at the end of the final example on 7.5 [dcl.link] paragraph 4:</P>

<PRE>
    extern "C" {
      static void f4();    // <I>the name of the function</I> f4 <I>has</I>
                           // <I>internal linkage (not C language</I>
                           // <I>linkage) and the function's type</I>
                           // <I>has C language linkage</I>
    }
    extern "C" void f5() {
      extern void f4();    // <I>Okay -- name linkage (internal)</I>
                           // <I>and function type linkage (C</I>
                           // <I>language linkage) gotten from</I>
                           // <I>previous declaration.</I>
    }
    extern void f4();      // <I>Okay -- name linkage (internal)</I>
                           // <I>and function type linkage (C</I>
                           // <I>language linkage) gotten from</I>
                           // <I>previous declaration.</I>
    void f6() {
      extern void f4();    // <I>Okay -- name linkage (internal)</I>
                           // <I>and function type linkage (C</I>
                           // <I>language linkage) gotten from</I>
                           // <I>previous declaration.</I>
    }
</PRE>
</LI>

<LI><P>Change 7.5 [dcl.link] paragraph 7 from</P>

<BLOCKQUOTE>
<P>Except for functions with internal linkage, a function
first declared in a <I>linkage-specification</I> behaves as a
function with external linkage.  [<I>Example:</I></P>

<PRE>
    extern "C" double f();
    static double f();     // <I>error</I>
</PRE>

<P>is ill-formed (7.1.1 [dcl.stc]). ] The form of
<I>linkage-specification</I> that contains a braced-enclosed
<I>declaration-seq</I> does not affect whether the contained
declarations are definitions or not (3.1 [basic.def]); the
form of <I>linkage-specification</I> directly containing a
single declaration is treated as an <TT>extern</TT> specifier
(7.1.1 [dcl.stc]) for the purpose of determining whether
the contained declaration is a definition.  [<I>Example:</I></P>

<PRE>
    extern "C" int i;      // <I>declaration</I>
    extern "C" {
	  int i;           // <I>definition</I>
    }
</PRE>

<P>&#8212;<I>end example</I>] A <I>linkage-specification</I> directly
containing a single declaration shall not specify a
storage class.  [<I>Example:</I></P>

<PRE>
    extern "C" static void f(); // <I>error</I>
</PRE>

<P>&#8212;<I>end example</I>]</P>
</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>
A declaration directly contained in a
<I>linkage-specification</I> is treated as if it contains the
<TT>extern</TT> specifier (7.1.1 [dcl.stc]) for the purpose of
determining the linkage of the declared name and
whether it is a definition.  Such a declaration shall
not specify a storage class.  [<I>Example:</I>

<PRE>
    extern "C" double f();
    static double f();     // <I>error</I>
    extern "C" int i;      // <I>declaration</I>
    extern "C" {
	    int i;         // <I>definition</I>
    }
    extern "C" static void g(); // <I>error</I>
</PRE>

<P>&#8212;<I>end example</I>]</P>
</BLOCKQUOTE>
</LI>
</OL>
<BR><BR><HR><A NAME="29"></A><H4>29.
  
Linkage of locally declared functions
</H4><B>Section: </B>7.5&#160; [dcl.link]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Ball
 &#160;&#160;&#160;

 <B>Date: </B>19 Mar 1998<BR>



<P>[Moved to DR at October 2002 meeting.  This was incorrectly
marked as having DR status between 4/01 and 4/02.  It was overlooked
when <A HREF="
     cwg_defects.html#4">issue 4</A> was moved to DR at the 4/01
meeting; this one should have been moved as well, because it's resolved
by the changes there.]</P>



<P>Consider the following:</P>
<PRE>
    extern "C" void foo()
    {
        extern void bar();
        bar();
    }
</PRE>
Does "bar()" have "C" language linkage?

<P>The ARM is explicit and says</P>
<BLOCKQUOTE>A linkage-specification for a function also applies to functions
and objects declared within it.</BLOCKQUOTE>
The DIS says
<BLOCKQUOTE>In a <I>linkage-specification</I>, the specified language linkage
applies to the function types of all function declarators, function names,
and variable names introduced by the declaration(s).</BLOCKQUOTE>
Is the body of a function definition part of the declaration?

<P><U>From Mike Miller:</U></P>

<P>Yes: from 7 [dcl.dcl]
 paragraph 1,</P>
<UL><I>declaration:</I>
<UL><I>function-definition</I></UL>
</UL>
and 8.4 [dcl.fct.def]
 paragraph 1:
<UL><I>function-definition:</I>
<UL><I>decl-specifier-seq<SUB>opt</SUB> declarator ctor-initializer<SUB>opt</SUB>&#160;function-body</I></UL>
</UL>
At least that's how I'd read it.

<P><U>From Dag Br&#252;ck:</U></P>

<P>Consider the
following where extern "C" has been moved to a separate declaration:</P>
<PRE>
    extern "C" void foo();
    
    void foo() { extern void bar(); bar(); }
</PRE>
I think the ARM wording could possibly be interpreted such that bar() has
"C" linkage in my example, but not the DIS wording.

<P>As a side note, I have always wanted to think that placing extern "C"
on a function definition or a separate declaration would produce identical
programs.</P>

<P><B>Proposed Resolution (04/01):</B></P>

<P>See the proposed resolution for
<A HREF="
     cwg_defects.html#4">Core issue 4</A>, which covers this case.</P>

<P>The ODR should also be checked to see whether it addresses name and
type linkage.</P>
<BR><BR><HR><A NAME="686"></A><H4>686.
  
Type declarations/definitions in <I>type-specifier-seq</I>s and <I>type-id</I>s
</H4><B>Section: </B>8.1&#160; [dcl.name]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jens Maurer
 &#160;&#160;&#160;

 <B>Date: </B>21 March, 2008<BR>


<P>[Voted into the WP at the September, 2008 meeting.]</P>



<P>The restrictions on declaring and/or defining classes inside
<I>type-specifier-seq</I>s and <I>type-id</I>s are inconsistent
throughout the Standard.  This is probably due to the fact that
nearly all of the sections that deal with them attempt to state
the restriction afresh.  There are three cases:</P>

<OL>
<LI><P>5.3.4 [expr.new], 6.4 [stmt.select],
and 12.3.2 [class.conv.fct] prohibit &#8220;declarations&#8221;
of classes and enumerations.  That means that</P>

<PRE>
    while (struct C* p = 0) ;
</PRE>

<P>is ill-formed unless a prior declaration of <TT>C</TT> has been
seen.  These appear to be cases that should have been fixed by
<A HREF="
     cwg_defects.html#379">issue 379</A>, changing &#8220;class
declaration&#8221; to &#8220;class definition,&#8221; but were
overlooked.</P>
</LI>

<LI><P>5.1.2 [expr.prim.lambda], 7 [dcl.dcl], and
8.3.5 [dcl.fct] (late-specified return types) do not
contain any restriction at all. </P></LI>

<LI><P>All the remaining cases prohibit &#8220;type
definitions,&#8221; apparently referring to classes and
enumerations.</P></LI>

</OL>

<P><U>Suggested resolution</U>:</P>

<P>Add something like, &#8220;A class or enumeration shall
not be defined in a <I>type-specifier-seq</I> or in a
<I>type-id</I>,&#8221; to a single place in the Standard and
remove all other mentions of that restriction (allowing
declarations via <I>elaborated-type-specifier</I>).</P>

<P><U>Mike Miller</U>:</P>

<P>An <I>alias-declaration</I> is just a different syntax for
a typedef declaration, which allows definitions of a class in
the type; I would expect the same to be true of an
<I>alias-declaration</I>.  I don't have any particularly
strong attachment to allowing a class definition in an
<I>alias-declaration</I>.  My only concern is introducing
an irregularity into what are currently exact-match
semantics with typedefs.</P>

<P>There's a parallel restriction in many (but not all?) of
these places on typedef declarations.</P>

<P><U>Jens Maurer</U>:</P>

<P>Those are redundant, as <TT>typedef</TT> is not a
<I>type-specifier</I>, and should be removed as well.</P>

<P><B>Proposed resolution (March, 2008):</B></P>

<OL>
<LI><P>Delete the indicated words from 5.2.7 [expr.dynamic.cast]
paragraph 1:</P></LI>

<BLOCKQUOTE>

...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Types shall not be defined in a <TT>dynamic_cast</TT>.</SPAN>...

</BLOCKQUOTE>

<LI><P>Delete the indicated words from 5.2.8 [expr.typeid]
paragraph 4:</P></LI>

<BLOCKQUOTE>

...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Types shall not be defined in the <I>type-id</I>.</SPAN>...

</BLOCKQUOTE>

<LI><P>Delete the indicated words from 5.2.9 [expr.static.cast]
paragraph 1:</P></LI>

<BLOCKQUOTE>

...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Types shall not be defined in a <TT>static_cast</TT>.</SPAN>...

</BLOCKQUOTE>

<LI><P>Delete the indicated words from 5.2.10 [expr.reinterpret.cast]
paragraph 1:</P></LI>

<BLOCKQUOTE>

...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Types shall not be defined in a <TT>reinterpret_cast</TT>.</SPAN>...

</BLOCKQUOTE>

<LI><P>Delete the indicated words from 5.2.11 [expr.const.cast]
paragraph 1:</P></LI>

<BLOCKQUOTE>

...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Types shall not be defined in a <TT>const_cast</TT>.</SPAN>...

</BLOCKQUOTE>

<LI><P>Delete paragraph 5 of 5.3.3 [expr.sizeof]:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Types shall not be defined in a <TT>sizeof</TT> expression.</SPAN>

</BLOCKQUOTE>

<LI><P>Delete paragraph 5 of 5.3.4 [expr.new]:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The <I>type-specifier-seq</I> shall not contain class declarations, or
enumeration declarations.</SPAN>

</BLOCKQUOTE>

<LI><P>Delete paragraph 4 of 5.3.6 [expr.alignof]:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A type shall not be defined in an <TT>alignof</TT> expression.</SPAN>

</BLOCKQUOTE>

<LI><P>Delete paragraph 3 of 5.4 [expr.cast]:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Types shall not be defined in casts.</SPAN>

</BLOCKQUOTE>

<LI><P>Delete the indicated words from 6.4 [stmt.select]
paragraph 2:</P></LI>

<BLOCKQUOTE>

...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The <I>type-specifier-seq</I> shall not contain
<TT>typedef</TT> and shall not declare a new class or
enumeration.</SPAN>...

</BLOCKQUOTE>

<LI><P>Add the indicated words to 7.1.6 [dcl.type]
paragraph 3:</P></LI>

<BLOCKQUOTE>

At least one <I>type-specifier</I> that is not a
<I>cv-qualifier</I> is required in a declaration unless it
declares a constructor, destructor or conversion function.
[<I>Footnote:</I> ... ] <SPAN style="font-weight:bold;background-color:#A0FFA0">A <I>type-specifier-seq</I> shall not
define a class or enumeration unless it appears in the
<I>type-id</I> of an <I>alias-declaration</I>
(7.1.3 [dcl.typedef]).</SPAN>

</BLOCKQUOTE>

<LI><P>Delete the indicated words from 12.3.2 [class.conv.fct]
paragraph 1:</P></LI>

<BLOCKQUOTE>

...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Classes, enumerations, and <I>typedef-name</I>s shall not be
declared in the <I>type-specifier-seq</I>.</SPAN>...

</BLOCKQUOTE>

<LI><P>Delete the indicated words from 15.3 [except.handle]
paragraph 1:</P></LI>

<BLOCKQUOTE>

...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Types shall not be defined in an <I>exception-declaration</I>.</SPAN>

</BLOCKQUOTE>

<LI><P>Delete paragraph 6 of 15.4 [except.spec]:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Types shall not be defined in <I>exception-specification</I>s.</SPAN>

</BLOCKQUOTE>

</OL>

<P><I>[Drafting note: no changes are required to
5.1.2 [expr.prim.lambda], 7.1.3 [dcl.typedef],
7.6.2 [dcl.align], 7.2 [dcl.enum],
8.3.5 [dcl.fct], 14.1 [temp.param],
or 14.2 [temp.names].]</I></P>

<BR><BR><HR><A NAME="160"></A><H4>160.
  
Missing <TT>std::</TT> qualification
</H4><B>Section: </B>8.2&#160; [dcl.ambig.res]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Al Stevens
 &#160;&#160;&#160;

 <B>Date: </B>23 Aug 1999<BR>



<P>[Moved to DR at 10/01 meeting.]</P>

<P>8.2 [dcl.ambig.res]
 paragraph 3
shows an example that includes <TT>&lt;cstddef&gt;</TT> with no using
declarations or directives and refers to <TT>size_t</TT>
without the <TT>std::</TT>
qualification.</P>

<P>Many references to <TT>size_t</TT> throughout the document omit the
<TT>std::</TT>
namespace
qualification.</P>

<P>This is a typical case. The use of <TT>std::</TT>
is inconsistent throughout
the
document.</P>

<P>In addition, the use of exception specifications should be
examined for consistency.</P>

<P>(See also <A HREF="
     cwg_active.html#282">issue 282</A>.)</P>

<P><B>Proposed resolution:</B></P>

<P>In
1.9 [intro.execution]
paragraph 9, replace all two instances of "<TT>sig_atomic_t</TT>"
by "<TT>std::sig_atomic_t</TT>".</P>


<P>In
3.1 [basic.def]
paragraph 4, replace all three instances of "<TT>string</TT>" by
"<TT>std::string</TT>" in the example and insert "<TT>#include
&lt;string&gt;</TT>" at the beginning of the example code.</P>


<P>In
3.6.1 [basic.start.main]
paragraph 4, replace</P>
<BLOCKQUOTE>
Calling the function
<BLOCKQUOTE>
<TT>void exit(int);</TT>
</BLOCKQUOTE>
declared in <TT>&lt;cstdlib&gt;</TT>...
</BLOCKQUOTE>
<P>by</P>
<BLOCKQUOTE>
Calling the function <TT>std::exit(int)</TT> declared in
<TT>&lt;cstdlib&gt;</TT>...
</BLOCKQUOTE>
<P>and also replace "<TT>exit</TT>" by "<TT>std::exit</TT>" in
the last sentence of that paragraph.</P>


<P>In
3.6.1 [basic.start.main]
first sentence of paragraph 5, replace "<TT>exit</TT>" by
"<TT>std::exit</TT>".</P>


<P>In
3.6.2 [basic.start.init]
paragraph 4, replace "<TT>terminate</TT>" by
"<TT>std::terminate</TT>".</P>


<P>In
3.6.3 [basic.start.term]
paragraph 1, replace "<TT>exit</TT>" by "<TT>std::exit</TT>"
(see also <A HREF="
     cwg_defects.html#28">issue 28</A>).</P>


<P>In
3.6.3 [basic.start.term]
paragraph 3, replace all three instances of "<TT>atexit</TT>" by
"<TT>std::atexit</TT>" and both instances of "<TT>exit</TT>"
by "<TT>std::exit</TT>" (see also <A HREF="
     cwg_defects.html#28">issue 28</A>).</P>


<P>In
3.6.3 [basic.start.term]
paragraph 4, replace</P>
<BLOCKQUOTE>
Calling the function
<BLOCKQUOTE>
<TT>void abort();</TT>
</BLOCKQUOTE>
declared in <TT>&lt;cstdlib&gt;</TT>...
</BLOCKQUOTE>
<P>by</P>
<BLOCKQUOTE>
Calling the function <TT>std::abort()</TT> declared in
<TT>&lt;cstdlib&gt;</TT>...</BLOCKQUOTE>
and "<TT>atexit</TT>" by "<TT>std::atexit</TT>" (see also
<A HREF="
     cwg_defects.html#28">issue 28</A>).


<P>In
3.7.4.1 [basic.stc.dynamic.allocation]
paragraph 1 third sentence, replace "<TT>size_t</TT>" by
"<TT>std::size_t</TT>".</P>


<P>In
3.7.4.1 [basic.stc.dynamic.allocation]
paragraph 3, replace "<TT>new_handler</TT>" by
"<TT>std::new_handler</TT>". Furthermore, replace
"<TT>set_new_handler</TT>" by "<TT>std::set_new_handler</TT>"
in the note.</P>


<P>In
3.7.4.1 [basic.stc.dynamic.allocation]
paragraph 4, replace "<TT>type_info</TT>" by
"<TT>std::type_info</TT>" in the note.</P>


<P>In
3.7.4.2 [basic.stc.dynamic.deallocation]
paragraph 3, replace all four instances of "<TT>size_t</TT>" by
"<TT>std::size_t</TT>".</P>


<P>In
3.8 [basic.life]
paragraph 5, replace "<TT>malloc</TT>" by
"<TT>std::malloc</TT>" in the example code and insert
"<TT>#include &lt;cstdlib&gt;</TT>" at the beginning of the example
code.</P>


<P>In
3.9 [basic.types]
paragraph 2, replace "<TT>memcpy</TT>" by
"<TT>std::memcpy</TT>" (the only instance in the footnote and both
instances in the example) and replace "<TT>memmove</TT>" by
"<TT>std::memmove</TT>" in the footnote (see also
<A HREF="
     cwg_defects.html#43">issue 43</A>).</P>


<P>In
3.9 [basic.types]
paragraph 3, replace "<TT>memcpy</TT>" by
"<TT>std::memcpy</TT>", once in the normative text and once in the
example (see also <A HREF="
     cwg_defects.html#43">issue 43</A>).</P>


<P>In
3.9.1 [basic.fundamental]
paragraph 8 last sentence, replace "<TT>numeric_limits</TT>" by
"<TT>std::numeric_limits</TT>".</P>


<P>In
5.2.7 [expr.dynamic.cast]
paragraph 9 second sentence, replace "<TT>bad_cast</TT>" by
"<TT>std::bad_cast</TT>".</P>


<P>In
5.2.8 [expr.typeid]
paragraph 2, replace "<TT>type_info</TT>" by
"<TT>std::type_info</TT>" and "<TT>bad_typeid</TT>" by
"<TT>std::bad_typeid</TT>".</P>


<P>In
5.2.8 [expr.typeid]
paragraph 3, replace "<TT>type_info</TT>" by
"<TT>std::type_info</TT>".</P>


<P>In
5.2.8 [expr.typeid]
paragraph 4, replace both instances of "<TT>type_info</TT>" by
"<TT>std::type_info</TT>".</P>


<P>In
5.3.3 [expr.sizeof]
paragraph 6, replace both instances of "<TT>size_t</TT>" by
"<TT>std::size_t</TT>".</P>


<P>In
5.3.4 [expr.new]
paragraph 11 last sentence, replace "<TT>size_t</TT>" by
"<TT>std::size_t</TT>".</P>


<P>In
5.7 [expr.add]
paragraph 6, replace both instances of "<TT>ptrdiff_t</TT>" by
"<TT>std::ptrdiff_t</TT>".</P>


<P>In
5.7 [expr.add]
paragraph 8, replace "<TT>ptrdiff_t</TT>" by
"<TT>std::ptrdiff_t</TT>".</P>


<P>In
6.6 [stmt.jump]
paragraph 2, replace "<TT>exit</TT>" by "<TT>std::exit</TT>"
and "<TT>abort</TT>" by "<TT>std::abort</TT>" in the note.</P>


<P>In
8.2 [dcl.ambig.res]
paragraph 3, replace "<TT>size_t</TT>" by
"<TT>std::size_t</TT>" in the example.</P>


<P>In
8.4 [dcl.fct.def]
paragraph 5, replace "<TT>printf</TT>" by
"<TT>std::printf</TT>" in the note.</P>


<P>In
12.4 [class.dtor]
paragraph 13, replace "<TT>size_t</TT>" by
"<TT>std::size_t</TT>" in the example.</P>


<P>In
12.5 [class.free]
paragraph 2, replace all four instances of "<TT>size_t</TT>" by
"<TT>std::size_t</TT>" in the example.</P>


<P>In
12.5 [class.free]
paragraph 6, replace both instances of "<TT>size_t</TT>" by
"<TT>std::size_t</TT>" in the example.</P>


<P>In
12.5 [class.free]
paragraph 7, replace all four instances of "<TT>size_t</TT>" by
"<TT>std::size_t</TT>" in the two examples.</P>


<P>In
12.7 [class.cdtor]
paragraph 4, replace "<TT>type_info</TT>" by
"<TT>std::type_info</TT>".</P>


<P>In
13.6 [over.built]
paragraph 13, replace all five instances of "<TT>ptrdiff_t</TT>"
by "<TT>std::ptrdiff_t</TT>".</P>


<P>In
13.6 [over.built]
paragraph 14, replace "<TT>ptrdiff_t</TT>" by
"<TT>std::ptrdiff_t</TT>".</P>


<P>In
13.6 [over.built]
paragraph 21, replace both instances of "<TT>ptrdiff_t</TT>" by
"<TT>std::ptrdiff_t</TT>".</P>


<P>In
14.2 [temp.names]
paragraph 4, replace both instances of "<TT>size_t</TT>" by
"<TT>std::size_t</TT>" in the example.  (The example is quoted in
<A HREF="
     cwg_defects.html#96">issue 96</A>.)</P>


<P>In
14.3 [temp.arg]
paragraph 1, replace "<TT>complex</TT>" by
"<TT>std::complex</TT>", once in the example code and once in the
comment.</P>


<P>In
14.7.3 [temp.expl.spec]
paragraph 8, <A HREF="
     cwg_defects.html#24">issue 24</A>
has already corrected the example.</P>


<P>In
15.1 [except.throw]
paragraph 6, replace "<TT>uncaught_exception</TT>" by
"<TT>std::uncaught_exception</TT>".</P>


<P>In
15.1 [except.throw]
paragraph 7, replace "<TT>terminate</TT>" by
"<TT>std::terminate</TT>" and both instances of
"<TT>unexpected</TT>" by "<TT>std::unexpected</TT>".</P>


<P>In
15.1 [except.throw]
paragraph 8, replace "<TT>terminate</TT>" by
"<TT>std::terminate</TT>".</P>


<P>In
15.2 [except.ctor]
paragraph 3, replace "<TT>terminate</TT>" by
"<TT>std::terminate</TT>".</P>


<P>In
15.3 [except.handle]
paragraph 9, replace "<TT>terminate</TT>" by
"<TT>std::terminate</TT>".</P>


<P>In
15.4 [except.spec]
paragraph 8, replace "<TT>unexpected</TT>" by
"<TT>std::unexpected</TT>".</P>


<P>In
15.4 [except.spec]
paragraph 9, replace "<TT>unexpected</TT>" by
"<TT>std::unexpected</TT>" and "<TT>terminate</TT>" by
"<TT>std::terminate</TT>".</P>


<P>In
15.5 [except.special]
paragraph 1, replace "<TT>terminate</TT>" by
"<TT>std::terminate</TT>" and "<TT>unexpected</TT>" by
"<TT>std::unexpected</TT>".</P>


<P>In the heading of
15.5.1 [except.terminate],
replace "<TT>terminate</TT>" by "<TT>std::terminate</TT>".</P>


<P>In
15.5.1 [except.terminate]
paragraph 1, footnote in the first bullet, replace
"<TT>terminate</TT>" by "<TT>std::terminate</TT>".  In the
same paragraph, fifth bullet, replace "<TT>atexit</TT>" by
"<TT>std::atexit</TT>".  In the same paragraph, last bullet,
replace "<TT>unexpected_handler</TT>" by
"<TT>std::unexpected_handler</TT>".</P>


<P>In
15.5.1 [except.terminate]
paragraph 2, replace</P>
<BLOCKQUOTE>
In such cases,
<BLOCKQUOTE>
<TT>void terminate();</TT>
</BLOCKQUOTE>
is called...
</BLOCKQUOTE>
<P>by</P>
<BLOCKQUOTE>
In such cases, <TT>std::terminate()</TT> is called...
</BLOCKQUOTE>
<P>and replace all three instances of "<TT>terminate</TT>" by
"<TT>std::terminate</TT>".</P>


<P>In the heading of
15.5.2 [except.unexpected],
replace "<TT>unexpected</TT>" by "<TT>std::unexpected</TT>".</P>


<P>In
15.5.2 [except.unexpected]
paragraph 1, replace </P>
<BLOCKQUOTE>
...the function
<BLOCKQUOTE>
<TT>void unexpected();</TT>
</BLOCKQUOTE>
is called...
</BLOCKQUOTE>
<P>by</P>
<BLOCKQUOTE>
...the function <TT>std::unexpected()</TT> is called...
</BLOCKQUOTE>.


<P>In
15.5.2 [except.unexpected]
paragraph 2, replace "<TT>unexpected</TT>" by
"<TT>std::unexpected</TT>" and "<TT>terminate</TT>" by
"<TT>std::terminate</TT>".</P>


<P>In
15.5.2 [except.unexpected]
paragraph 3, replace "<TT>unexpected</TT>" by
"<TT>std::unexpected</TT>".</P>


<P>In the heading of
15.5.3 [except.uncaught],
replace "<TT>uncaught_exception</TT>" by
"<TT>std::uncaught_exception</TT>".</P>


<P>In 
15.5.3 [except.uncaught]
paragraph 1, replace</P>
<BLOCKQUOTE>
The function
<BLOCKQUOTE>
<TT>bool uncaught_exception()</TT>
</BLOCKQUOTE>
returns <TT>true</TT>...
</BLOCKQUOTE>
<P>by</P>
<BLOCKQUOTE>
The function <TT>std::uncaught_exception()</TT> returns <TT>true</TT>...
</BLOCKQUOTE>.
<P>In the last sentence of the same paragraph, replace
"<TT>uncaught_exception</TT>" by
"<TT>std::uncaught_exception</TT>".</P>

<BR><BR><HR><A NAME="112"></A><H4>112.
  
Array types and cv-qualifiers
</H4><B>Section: </B>8.3.4&#160; [dcl.array]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Clamage
 &#160;&#160;&#160;

 <B>Date: </B>4 May 1999<BR>



<P>[Moved to DR at 10/01 meeting.]</P>



<P><U>Steve Clamage:</U>
Section 8.3.4 [dcl.array]
 paragraph 1
reads in part as follows:</P>

<BLOCKQUOTE>
Any type of the form "<I>cv-qualifier-seq</I> array of <TT>N T</TT>"
is adjusted to
"array of <TT>N</TT> <I>cv-qualifier-seq</I> <TT>T</TT>,"
and similarly for "array of unknown
bound of <TT>T</TT>." [<I>Example:</I>
<PRE>
    typedef int A[5], AA[2][3];
    typedef const A CA;     // <I>type is "array of 5 const int"</I>
    typedef const AA CAA;   // <I>type is "array of 2 array of 3 const int"</I>
</PRE>
&#8212;<I>end example</I>]
[<I>Note:</I> an "array of <TT>N</TT> <I>cv-qualifier-seq</I> <TT>T</TT>"
has cv-qualified type; such
an array has internal linkage unless explicitly declared <TT>extern</TT>
(7.1.6.1 [dcl.type.cv]
)
and must be initialized as specified in
8.5 [dcl.init]
. ]
</BLOCKQUOTE>

The Note appears to contradict the sentence that precedes it. 

<P><U>Mike Miller:</U>
I disagree; all it says is that whether the qualification on
the element type is direct ("<TT>const int x[5]</TT>") or indirect
("<TT>const A CA</TT>"), the array itself is qualified in the same way
the elements are.</P>

<P><U>Steve Clamage:</U> In addition, section
3.9.3 [basic.type.qualifier]
 paragraph 2 says:</P>

<BLOCKQUOTE>
A compound type (3.9.2 [basic.compound]
)
is not cv-qualified by the cv-qualifiers (if
any) of the types from which it is compounded.  Any cv-qualifiers
applied to an array type affect the array element type, not the
array type (8.3.4 [dcl.array]
)."
</BLOCKQUOTE>

The Note appears to contradict that section as well.

<P><U>Mike Miller:</U>
Yes, but consider the last two sentences of
3.9.3 [basic.type.qualifier]
 paragraph 5:</P>
<BLOCKQUOTE>
Cv-qualifiers applied to an array type attach to the
underlying element type, so the notation "<I>cv</I> <TT>T</TT>,"
where <TT>T</TT> is
an array type, refers to an array whose elements are
so-qualified.  Such array types can be said to be more (or
less) cv-qualified than other types based on the cv-qualification
of the underlying element types.
</BLOCKQUOTE>

I think this says essentially the same thing as
8.3.4 [dcl.array]
 paragraph 1 and
its note: the qualification of an array is (bidirectionally)
equivalent to the qualification of its members.

<P><U>Mike Ball:</U>
I find this a very far reach.  The text in
8.3.4 [dcl.array]
 is essentially that which
is in the C standard (and is a change from early versions of C++).
I don't see any justification at all for the bidirectional equivalence.
It seems to me that
the note is left over from the earlier version of the language.</P>

<P><U>Steve Clamage:</U> Finally, the Note seems to say that the declaration</P>
<PRE>
    volatile char greet[6] = "Hello";
</PRE>
gives "greet" internal linkage, which makes no sense.

<P>Have I missed something, or should that Note be entirely removed?</P>

<P><U>Mike Miller:</U>
At least the wording in the note
should be repaired not to indicate that volatile-qualification
gives an array internal linkage.  Also, depending on how the
discussion goes, either the wording in
3.9.3 [basic.type.qualifier]
 paragraph 2
or in paragraph 5 needs
to be amended to be consistent regarding whether an array type
is considered qualified by the qualification of its element
type.</P>

<P><U>Steve Adamczyk</U> pointed out that
the current state of affairs resulted from the need to handle
reference binding consistently.  The wording is intended to define
the question, "Is an array type cv-qualified?" as being equivalent
to the question, "Is the element type of the array cv-qualified?"</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>Replace the portion of the note in 8.3.4 [dcl.array]
paragraph 1 reading</P>

<BLOCKQUOTE>

such an array has internal linkage unless explicitly declared
<TT>extern</TT> (7.1.6.1 [dcl.type.cv]) and must be
initialized as specified in 8.5 [dcl.init].

</BLOCKQUOTE>

<P>with</P>

<BLOCKQUOTE>

see 3.9.3 [basic.type.qualifier].

</BLOCKQUOTE>

<BR><BR><HR><A NAME="140"></A><H4>140.
  
Agreement of parameter declarations
</H4><B>Section: </B>8.3.5&#160; [dcl.fct]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Clamage
 &#160;&#160;&#160;

 <B>Date: </B>15 Jul 1999<BR>



<P>[Moved to DR at 10/01 meeting.]</P>



<P>8.3.5 [dcl.fct]
 paragraph 3 says,</P>

<BLOCKQUOTE>
All declarations for a function with a given parameter list shall
agree exactly both in the type of the value returned and in the
number and type of parameters.
</BLOCKQUOTE>

It is not clear what this requirement means with respect to a pair
of declarations like the following:

<PRE>
    int f(const int);
    int f(int x) { ... }
</PRE>

Do they violate this requirement?  Is <TT>x const</TT> in the body of
the function declaration?

<P><U>Tom Plum</U>:
I think the FDIS quotation means that the pair of decls are valid.
But it doesn't clearly answer whether
<TT>x</TT> is <TT>const</TT> inside the function definition.
As to intent, I <I>know</I> the intent was that if the function
definition wants to specify that <TT>x</TT> is <TT>const</TT>,
the <TT>const</TT> must appear specifically in the defining
decl, not just on some decl elsewhere.
But I can't prove that intent from the drafted words.</P>

<P><U>Mike Miller</U>:
I think the intent was something along the
following lines:</P>

<BLOCKQUOTE>
Two function declarations denote the same entity if
the names are the same and the function signatures
are the same.  (Two function declarations with C
language linkage denote the same entity if the names
are the same.)  All declarations of a given function
shall agree exactly both in the type of the value
returned and in the number and type of parameters;
the presence or absence of the ellipsis is considered
part of the signature.
</BLOCKQUOTE>

(See 3.5 [basic.link]
 paragraph 9.
That paragraph talks about names in different
scopes and says that function references are the same if the
"types are identical for purposes of overloading," i.e., the
signatures are the same.  See also
7.5 [dcl.link]
 paragraph 6
regarding C language
linkage, where only the name is required to be the same for
declarations in different namespaces to denote the same
function.)

<P>According to this paragraph, the type of a parameter is
determined by considering its <I>decl-specifier-seq</I> and
<I>declarator</I>
and then applying the array-to-pointer and function-to-pointer
adjustments.  The <I>cv-qualifier</I> and storage class adjustments
are performed for the function type but not for the parameter
types.</P>

<P>If my interpretation of the intent of the second sentence of
the paragraph is correct, the two declarations in the example
violate that restriction &#8212; the parameter types are not the
same, even though the function types are.  Since there's no
dispensation mentioned for "no diagnostic required," an
implementation presumably must issue a diagnostic in this
case.  (I think "no diagnostic required" should be stated if
the declarations occur in different translation units &#8212;
unless there's a blanket statement to that effect that I have
forgotten?)</P>

<P>(I'd also note in passing that, if my interpretation is
correct,</P>

<PRE>
    void f(int);
    void f(register int) { }
</PRE>

is also an invalid pair of declarations.)



<P><B>Proposed resolution (10/00):</B></P>

<OL>
<LI><P>In 1.3 [intro.defs] &#8220;<B>signature</B>,&#8221; change
"the types of its parameters"
to
"its parameter-type-list (8.3.5 [dcl.fct])".
</P></LI>

<LI><P>In the third bullet of 3.5 [basic.link] paragraph 9
change
"the function types are identical for the purposes of overloading"
to
"the parameter-type-lists of the functions (8.3.5 [dcl.fct]) are identical."
</P></LI>

<LI><P>In the sub-bullets of the third bullet of
5.2.5 [expr.ref] paragraph 4, change all four occurrences
of
"function of (parameter type list)"
to
"function of parameter-type-list."
</P></LI>

<LI><P>In 8.3.5 [dcl.fct] paragraph 3, change

<BLOCKQUOTE>
All declarations for a function with a given parameter list shall agree
exactly both in the type of the value returned and in the number and
type of parameters; the presence or absence of the ellipsis is
considered part of the function type.
</BLOCKQUOTE>

to

<BLOCKQUOTE>
All declarations for a function shall
agree exactly in both the return type and the
parameter-type-list.
</BLOCKQUOTE>
</P></LI>

<LI><P>In 8.3.5 [dcl.fct] paragraph 3, change

<BLOCKQUOTE>
The resulting list of transformed parameter types is the function's
<I>parameter type list</I>.
</BLOCKQUOTE>

to

<BLOCKQUOTE>
The resulting list of transformed parameter types and the presence or
absence of the ellipsis is the function's <I>parameter-type-list</I>.
</BLOCKQUOTE>
</P></LI>

<LI><P>In 8.3.5 [dcl.fct] paragraph 4, change
"the parameter type list"
to
"the parameter-type-list."
</P></LI>

<LI><P>In the second bullet of 13.1 [over.load] paragraph 2,
change all occurrences of "parameter types" to
"parameter-type-list."
</P></LI>

<LI><P>In 13.3 [over.match] paragraph 1, change "the types of
the parameters" to "the parameter-type-list."
</P></LI>

<LI><P>In the last sub-bullet of the third bullet of
13.3.1.2 [over.match.oper] paragraph 3, change "parameter type
list" to "parameter-type-list."
</P></LI>

</OL>
<P><B>Note, 7 Sep 2001:</B></P>
<P>Editorial changes while putting in <A HREF="
     cwg_defects.html#147">issue 147</A>
brought up the fact that injected-class-name is not a syntax term and
therefore perhaps shouldn't be written with hyphens. The same can be said of
parameter-type-list.

</P>
<BR><BR><HR><A NAME="262"></A><H4>262.
  
Default arguments and ellipsis
</H4><B>Section: </B>8.3.5&#160; [dcl.fct]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jamie Schmeiser
 &#160;&#160;&#160;

 <B>Date: </B>13 Nov 2000<BR>


<P>[Voted into WP at April 2003 meeting.]</P>



<P>The interaction of default arguments and ellipsis is not clearly
spelled out in the current wording of the Standard.
8.3.6 [dcl.fct.default] paragraph 4 says,</P>

<BLOCKQUOTE>

In a given function declaration, all parameters subsequent to a
parameter with a default argument shall have default arguments
supplied in this or previous declarations.

</BLOCKQUOTE>

<P>Strictly speaking, ellipsis isn't a parameter, but this could
be clearer.  Also, in 8.3.5 [dcl.fct] paragraph 2,</P>

<BLOCKQUOTE>

If the <I>parameter-declaration-clause</I> terminates with an
ellipsis, the number of arguments shall be equal to or greater than
the number of parameters specified.

</BLOCKQUOTE>

<P>This could be interpreted to refer to the number of arguments
after the addition of default arguments to the argument list given
in the call expression, but again it could be clearer.</P>

<P><B>Notes from 04/01 meeting:</B></P>

<P>The consensus opinion was that an ellipsis is not a parameter
and that default arguments should be permitted preceding an
ellipsis.</P>

<P><B>Proposed Resolution (4/02):</B></P>

<P>Change the following sentence in 8.3.5 [dcl.fct] paragraph 2
from</P>
<BLOCKQUOTE>
If the <I>parameter-declaration-clause</I> terminates with an ellipsis, the
number of arguments shall be equal to or greater than the number of
parameters specified.
</BLOCKQUOTE>
<P>to</P>
<BLOCKQUOTE>
If the <I>parameter-declaration-clause</I> terminates with an ellipsis, the
number of arguments shall be equal to or greater than the number of
parameters that do not have a default argument.
</BLOCKQUOTE>

<P>As noted in the defect, section 8.3.6 [dcl.fct.default]
is correct but could be clearer.</P>

<P>In 8.3.6 [dcl.fct.default], add the following as the first line
of the example in paragraph 4.</P>
<PRE>
  void g(int = 0, ...);  // okay, ellipsis is not a parameter so it can follow 
                         // a parameter with a default argument
</PRE>

<BR><BR><HR><A NAME="295"></A><H4>295.
  
cv-qualifiers on function types
</H4><B>Section: </B>8.3.5&#160; [dcl.fct]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Nathan Sidwell
 &#160;&#160;&#160;

 <B>Date: </B>29 Jun 2001<BR>


<P>[Moved to DR at October 2002 meeting.]</P>

<P>This concerns the inconsistent treatment of cv qualifiers on
reference types and function types. The problem originated with
GCC bug report c++/2810. The bug report is available at
<A HREF="http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&amp;pr=2810&amp;database=gcc">
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&amp;pr=2810&amp;database=gcc
</A></P>

<P>8.3.2 [dcl.ref] describes references. Of interest is
the statement (my emphasis)</P>
<BLOCKQUOTE>
Cv-qualified references are ill-formed <B>except</B> when
the cv-qualifiers are introduced through the use of a typedef
or of a template type argument, in which case the cv-qualifiers
are ignored.
</BLOCKQUOTE>
<P>Though it is strange to ignore 'volatile' here, that is not the point
of this defect report. 8.3.5 [dcl.fct] describes function types.
Paragraph 4 states,</P>
<BLOCKQUOTE>
In fact, if at any time in the determination of a type a
cv-qualified function type is formed, the program is ill-formed.
</BLOCKQUOTE>
<P>No allowance for typedefs or template type parameters is
made here, which is inconsistent with the equivalent reference case.</P>

<P>The GCC bug report was template code which attempted to do,</P>
<PRE>
    template &lt;typename T&gt; void foo (T const &amp;);
    void baz ();
    ...
    foo (baz);
</PRE>

<P>in the instantiation of foo, <TT>T</TT> is `<TT>void ()</TT>' and an attempt
is made to const qualify that, which is ill-formed. This is a surprise.</P>

<P><B>Suggested resolution:</B></P>

<P>Replace the quoted sentence from paragraph 4 in
8.3.5 [dcl.fct] with</P>
<BLOCKQUOTE>
cv-qualified functions are ill-formed, except when the
cv-qualifiers are introduced through the use of a typedef or of
a template type argument, in which case the cv-qualifiers are
ignored.
</BLOCKQUOTE>
<P>Adjust the example following to reflect this.</P>

<P><B>Proposed resolution (10/01):</B></P>

<P>In 8.3.5 [dcl.fct] paragraph 4, replace
<BLOCKQUOTE>
The effect of a <I>cv-qualifier-seq</I> in a function declarator is
not the same as adding cv-qualification on top of the function type,
i.e., it does not create a cv-qualified function type.  In fact, if at
any time in the determination of a type a cv-qualified function type
is formed, the program is ill-formed. [<I>Example:
</I>
<PRE>
  typedef void F();
  struct S {
    const F f;          // ill-formed
  };
</PRE>
<I>-- end example</I>]
</BLOCKQUOTE>
by
<BLOCKQUOTE>
The effect of a <I>cv-qualifier-seq</I> in a function declarator is
not the same as adding cv-qualification on top of the function type.
In the latter case, the cv-qualifiers are ignored.  [<I>Example:
</I>
<PRE>
  typedef void F();
  struct S {
    const F f;          // ok; equivalent to void f();
  };
</PRE>
<I>-- end example</I>]
</BLOCKQUOTE>
</P>

<P>Strike the last bulleted item in 14.8.2 [temp.deduct]
paragraph 2, which reads
<BLOCKQUOTE>
Attempting to create a cv-qualified function type.
</BLOCKQUOTE>
</P>

<P><U>Nathan Sidwell</U> comments (18 Dec 2001
):
The proposed resolution simply states attempts to add cv qualification
on top of a function type are ignored.  There is no mention of whether
the function type was introduced via a typedef or template type parameter.
This would appear to allow
<PRE>
  void (const *fptr) ();
</PRE>
but, that is not permitted by the grammar.  This is inconsistent
with the wording of adding cv qualifiers to a reference type, which does
mention typedefs and template parameters, even though
<PRE>
  int &amp;const ref;
</PRE>
is also not allowed by the grammar.</P>

<P>Is this difference intentional? It seems needlessly confusing.</P>

<P><B>Notes from 4/02 meeting:</B></P>

<P>Yes, the difference is intentional.  There is no way to add cv-qualifiers
other than those cases.</P>

<P><B>Notes from April 2003 meeting:</B></P>

<P>Nathan Sidwell pointed out that some libraries use the inability to
add const to a type T as a way of testing that T is a function
type.  He will get back to us if he has a proposal for a change.</P>

<BR><BR><HR><A NAME="681"></A><H4>681.
  
Restrictions on declarators with late-specified return types
</H4><B>Section: </B>8.3.5&#160; [dcl.fct]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>10 March, 2008<BR>


<P>[Voted into the WP at the September, 2008 meeting as part of
paper N2757.]</P>

<P>The wording added to 8.3.5 [dcl.fct] for declarators with
late-specified return types says,</P>

<BLOCKQUOTE>

<P>In a declaration <TT>T D</TT> where <TT>D</TT> has the form</P>

<UL><TT>D1 (</TT> <I>parameter-declaration-clause</I> <TT>)</TT> <I>cv-qualifier-seq<SUB>opt</SUB> ref-qualifier<SUB>opt</SUB> exception-specification<SUB>opt</SUB></I> <TT>-&gt;</TT> <I>type-id</I></UL>

<P>and the type of the contained <I>declarator-id</I> in the
declaration <TT>T D1</TT> is
&#8220;<I>derived-declarator-type-list</I> <TT>T</TT>,&#8221; <TT>T</TT>
shall be the single <I>type-specifier</I> <TT>auto</TT> and the
<I>derived-declarator-type-list</I> shall be empty.</P>

</BLOCKQUOTE>

<P>These restrictions were intended to ensure that the return type of
the function is exactly the specified <I>type-id</I> following the
<TT>-&gt;</TT>, not modified by declarator operators and
cv-qualification.</P>

<P>Unfortunately, the requirement for an empty
<I>derived-declarator-type-list</I> does not achieve this goal but
instead forbids declarations like</P>

<PRE>
    auto (*fp)() -&gt; int;    //<SPAN style="font-family:Times;font-style:italic"> pointer to function returning </SPAN>int
</PRE>

<P>while allowing declarations like</P>

<PRE>
    auto *f() -&gt; int;       //<SPAN style="font-family:Times;font-style:italic"> function returning pointer to </SPAN>int
</PRE>

<P>The reason for this is that, according to the grammar in
8 [dcl.decl] paragraph 4, the declarator <TT>*f() -&gt; int</TT>
is parsed as a <I>ptr-operator</I> applied to the <I>direct-declarator</I>
<TT>f() -&gt; int</TT>; that is, the declarator <TT>D1</TT> seen in
8.3.5 [dcl.fct] is just <TT>f</TT>, and the
<I>derived-declarator-type-list</I> is thus empty.</P>

<P>By contrast, the declarator <TT>(*fp)() -&gt; int</TT> is parsed
as the <I>direct-declarator</I> <TT>(*fp)</TT> followed by the
<I>parameter-declaration-clause</I>, etc.  In this case, <TT>D1</TT> in
8.3.5 [dcl.fct] is <TT>(*fp)</TT> and the
<I>derived-declarator-type-list</I> is &#8220;pointer to,&#8221; i.e.,
not empty.</P>

<P>My personal view is that there is no reason to forbid the
<TT>(*fp)() -&gt; int</TT> form, and that doing so is problematic.
For example, this restriction would require users desiring the
late-specified return type syntax to write function parameters as
function types and rely on parameter type transformations rather
than writing them as pointer-to-function types, as they will actually
turn out to be:</P>

<PRE>
    void f(auto (*fp)() -&gt; int);  //<SPAN style="font-family:Times;font-style:italic"> ill-formed</SPAN>
    void f(auto fp() -&gt; int);     //<SPAN style="font-family:Times;font-style:italic"> OK (but icky)</SPAN>
</PRE>

<P>It may be helpful in deciding whether to allow this form to
consider the example of a function returning a pointer to a function.
With the current restriction, only one of the three plausible forms is
allowed:</P>

<PRE>
    auto (*f())() -&gt; int;           //<SPAN style="font-family:Times;font-style:italic"> Disallowed</SPAN>
    auto f() -&gt; int (*)();          //<SPAN style="font-family:Times;font-style:italic"> Allowed</SPAN>
    auto f() -&gt; auto (*)() -&gt; int;  //<SPAN style="font-family:Times;font-style:italic"> Disallowed</SPAN>
</PRE>

<U>Suggested resolution:</U>

<OL>
<LI><P>Delete the words &#8220;and
the <I>derived-declarator-type-list</I> shall be empty&#8221; from
8.3.5 [dcl.fct] paragraph 2.</P></LI>

<LI><P>Add a new paragraph following 8 [dcl.decl] paragraph
4:</P></LI>

<BLOCKQUOTE>

A <I>ptr-operator</I> shall not be applied, directly or indirectly,
to a function declarator with a late-specified return type
(8.3.5 [dcl.fct]).

</BLOCKQUOTE>
</OL>

<P><B>Proposed resolution (June, 2008):</B></P>

<OL><LI><P>Change the grammar in 8 [dcl.decl] paragraph 4
as follows:</P></LI>

<UL><I>declarator:</I><BR>
<UL><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>direct-declarator</I><BR>
<I>ptr-operator declarator</I></SPAN><BR>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>ptr-declarator</I><BR>
<I>noptr-declarator parameters-and-qualifiers</I> <TT>-&gt;</TT> <I>type-id</I></SPAN>
</UL><BR>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>ptr-declarator:</I><BR>
<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><I>noptr-declarator</I><BR>
<I>ptr-operator ptr-declarator</I><BR>
</SPAN></UL>
</SPAN><BR>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>direct-declarator:</I></SPAN><BR>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>noptr-declarator:</I></SPAN><BR>
<UL><I>declarator-id</I><BR>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>direct-declarator</I> <TT>(</TT> <I>parameter-declaration-clause</I> <TT>)</TT><BR>
<UL><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>cv-qualifier-seq<SUB>opt</SUB> ref-qualifier<SUB>opt</SUB> exception-specification<SUB>opt</SUB></I><BR></SPAN></UL>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>direct-declarator</I><TT>(</TT> <I>parameter-declaration-clause</I> <TT>)</TT><BR></SPAN>
<UL><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>cv-qualifier-seq<SUB>opt</SUB> ref-qualifier<SUB>opt</SUB> exception-specification<SUB>opt</SUB></I> <TT>-&gt;</TT> <I>type-id</I><BR></SPAN></UL>
<I>direct-declarator</I> <TT>[</TT> <I>constant-expression<SUB>opt</SUB></I> <TT>]</TT><BR></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>noptr-declarator parameters-and-qualifiers</I><BR>
<I>noptr-declarator</I> <TT>[</TT> <I>constant-expression<SUB>opt</SUB></I> <TT>]</TT></SPAN><BR>
<TT>(</TT> <I><SPAN style="font-weight:bold;background-color:#A0FFA0">ptr-</SPAN>declarator</I> <TT>)</TT><BR>
</UL><BR>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>parameters-and-qualifiers:</I><BR>
<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>(</TT> <I>parameter-declaration-clause</I> <TT>)</TT> <I>cv-qualifier-seq<SUB>opt</SUB> ref-qualifier<SUB>opt</SUB> exception-specification<SUB>opt</SUB></I><BR></SPAN></UL>
</SPAN>
...
</UL>

<LI><P>Change the grammar in 8.1 [dcl.name] paragraph 1
as follows:</P></LI>

<UL>...<BR>
<I>abstract-declarator:</I><BR>
<UL><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>ptr-operator abstract-declarator<SUB>opt</SUB></I><BR>
<I>direct-abstract-declarator</I></SPAN><BR>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>ptr-abstract-declarator</I><BR>
<I>noptr-abstract-declarator<SUB>opt</SUB> parameters-and-qualifiers</I> <TT>-&gt;</TT> <I>type-id</I></SPAN><BR>
<TT>...</TT><BR>
</UL><BR>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>ptr-abstract-declarator:</I><BR>
<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><I>noptr-abstract-declarator</I><BR>
<I>ptr-operator ptr-abstract-declarator<SUB>opt</SUB></I><BR>
</SPAN></UL>
</SPAN><BR>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>direct-abstract-declarator:</I><BR></SPAN>
<UL><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>direct-abstract-declarator<SUB>opt</SUB></I> <TT>(</TT> <I>parameter-declaration-clause</I> <TT>)</TT><BR>
<UL><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>cv-qualifier-seq<SUB>opt</SUB> ref-qualifier<SUB>opt</SUB> exception-specification<SUB>opt</SUB></I><BR>
</SPAN></UL>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>direct-abstract-declarator<SUB>opt</SUB></I> <TT>(</TT> <I>parameter-declaration-clause</I> <TT>)</TT><BR></SPAN>
<UL><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>cv-qualifier-seq<SUB>opt</SUB> ref-qualifier<SUB>opt</SUB> exception-specification<SUB>opt</SUB></I> <TT>-&gt;</TT> <I>type-id</I><BR></SPAN></UL>
<I>direct-abstract-declarator<SUB>opt</SUB></I> <TT>[</TT> <I>constant-expression<SUB>opt</SUB></I> <TT>]</TT></SPAN><BR></UL>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>noptr-abstract-declarator:</I></SPAN><BR>
<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><I>noptr-abstract-declarator<SUB>opt</SUB> parameters-and-qualifiers</I><BR>
<I>noptr-abstract-declarator<SUB>opt</SUB></I> <TT>[</TT> <I>constant-expression<SUB>opt</SUB></I> <TT>]</TT></SPAN><BR>
<TT>(</TT> <I><SPAN style="font-weight:bold;background-color:#A0FFA0">ptr-</SPAN>abstract-declarator</I> <TT>)</TT><BR>
</UL>
</UL>

<LI><P>Change 8.3.5 [dcl.fct] paragraph 2 as
follows:</P></LI>

<BLOCKQUOTE>

... <TT>T</TT> shall be the single <I>type-specifier</I> <TT>auto</TT>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">and the <I>derived-declarator-type-list</I> shall be
empty</SPAN>. Then the type...

</BLOCKQUOTE>

<LI><P>Change all occurrences of <I>direct-new-declarator</I> in
5.3.4 [expr.new] to <I>noptr-new-declarator</I>. These
changes appear in the grammar in paragraph 1 and in the text of
paragraphs 6-8, as follows:</P></LI>

<BLOCKQUOTE>

<P><UL>...<BR>
<I>new-declarator:</I><BR>
<UL><I>ptr-operator new-declarator<SUB>opt</SUB></I><BR>
<I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">direct-</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">noptr-</SPAN>new-declarator</I><BR>
</UL><BR>

<I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">direct-</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">noptr-</SPAN>new-declarator:</I><BR>
<UL><TT>[</TT> <I>expression</I> <TT>]</TT><BR>
<I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">direct-</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">noptr-</SPAN>new-declarator</I> <TT>[</TT> <I>constant-expression</I> <TT>]</TT><BR>
</UL>
...
</UL></P>

<P>When the allocated object is an array (that is, the
<I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">direct-</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">noptr-</SPAN>new-declarator</I> syntax is used or the
<I>new-type-id</I> or <I>type-id</I> denotes an array type), the
<I>new-expression</I> yields a pointer to the initial element (if any)
of the array. [<I>Note:</I> both <TT>new int</TT> and <TT>new
int[10]</TT> have type <TT>int*</TT> and the type of <TT>new
int[i][10]</TT> is <TT>int (*)[10]</TT> &#8212;<I>end note</I>]</P>

<P>Every <I>constant-expression</I> in a
<I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">direct-</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">noptr-</SPAN>new-declarator</I> shall be an integral
constant expression (5.19 [expr.const]) and evaluate to a
strictly positive value. The <I>expression</I> in a
<I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">direct-</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">noptr-</SPAN>new-declarator</I> shall be of integral
type, enumeration type, or a class type for which a single
non-explicit conversion function to integral or enumeration type
exists (12.3 [class.conv]). If the expression is of class
type, the expression is converted by calling that conversion function,
and the result of the conversion is used in place of the original
expression.  If the value of the expression is negative, the behavior
is undefined.  [<I>Example:</I> given the definition <TT>int n =
42</TT>, <TT>new float[n][5]</TT> is well-formed (because <TT>n</TT>
is the <I>expression</I> of a
<I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">direct-</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">noptr-</SPAN>new-declarator</I>), but <TT>new
float[5][n]</TT> is ill-formed (because <TT>n</TT> is not a constant
expression). If <TT>n</TT> is negative, the effect of <TT>new float[n][5]</TT>
is undefined. &#8212;<I>end example</I>]</P>

<P>When the value of the <I>expression</I> in a
<I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">direct-</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">noptr-</SPAN>new-declarator</I> is zero, the
allocation function is called to allocate an array with no
elements.</P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="136"></A><H4>136.
  
Default arguments and friend declarations
</H4><B>Section: </B>8.3.6&#160; [dcl.fct.default]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>9 July 1999<BR>



<P>[Moved to DR at 10/01 meeting.]</P>



<P>8.3.6 [dcl.fct.default]
 paragraph 4 says,</P>

<BLOCKQUOTE>
For non-template functions, default arguments can be added in later
declarations of a function in the same scope.  Declarations in
different scopes have completely distinct sets of default arguments.
That is, declarations in inner scopes do not acquire default arguments
from declarations in outer scopes, and vice versa.
</BLOCKQUOTE>

It is unclear how this wording applies to friend function declarations.
For example,

<PRE>
    void f(int, int, int=0);             // #1
    class C {
        friend void f(int, int=0, int);  // #2
    };
    void f(int=0, int, int);             // #3
</PRE>

Does the declaration at #2 acquire the default argument from #1, and
does the one at #3 acquire the default arguments from #2?

<P>There are several related questions involved with this issue:</P>

<OL>
<LI>Is the friend
declaration in the scope of class C or in the surrounding namespace
scope?

<P><U>Mike Miller</U>:
8.3.6 [dcl.fct.default]
 paragraph 4
is speaking about the lexical location of the
declaration...
The friend declaration occurs in a different declarative region
from the declaration at #1, so I would read [this paragraph] as saying that it
starts out with a clean slate of default arguments.</P>

<P><U>Bill Gibbons</U>:
Yes.  It occurs in a different region, although it declares a name
in the same region (i.e. a redeclaration).  This is the same as with
local externs and is intended to work the same way.  We decided that
local extern declarations cannot add (beyond the enclosing block) new
default arguments, and the same should apply to friend declarations.</P>

<P><U>John Spicer</U>:
The question is whether [this paragraph]
does (or should) mean declarations that appear in the same lexical
scope or declarations that declare names in the same scope.  In my opinion,
it really needs to be the latter.  It seems somewhat paradoxical to say
that a friend declaration declares a function in namespace scope yet the
declaration in the class still has its own attributes.  To make that work
I think you'd have to make friends more like block externs that really do
introduce a name into the scope in which the declaration is contained.</P></LI>

<LI>Should default arguments be permitted in friend function
declarations, and what effect should they have?

<P><U>Bill Gibbons</U>:
In the absence of a declaration visible in class scope to which
they could be attached, default arguments on friend declarations
do not make sense.
[They should be] ill-formed, to prevent surprises.</P>

<P><U>John Spicer</U>:
It is important that
the following case work correctly:</P>

<PRE>
        class X {
                friend void f(X x, int i = 1){}
        };

        int main()
        {
                X x;
                f(x);
        }
</PRE>

<P>In other words, a function first declared in a friend declaration must be
permitted to have default arguments and those default arguments must be
usable when the function is found by argument dependent lookup.  The reason
that this is important is that it is common practice to <I>define</I> functions
in friend declarations in templates, and that definition is the only place
where the default arguments can be specified.</P></LI>

<LI>What restrictions should be placed on default argument usage with
friend declarations?

<P><U>John Spicer</U>:
We want to avoid instantiation side effects.  IMO, the way to do this
would be to prohibit a friend declaration from providing default arguments
if a declaration of that function is already visible.
Once a function has had a default specified in a friend
declaration it should not be possible to add defaults in another declaration
be it a friend or normal declaration.</P>

<P><U>Mike Miller</U>:
The position that seems most reasonable to me is to
allow default arguments in friend declarations to be used in
Koenig lookup, but to say that they are
completely unrelated to default arguments in declarations in
the surrounding scope; and to forbid use of a default argument
in a call if more than one declaration in the overload set has
such a default, as in the proposed resolution for
<A HREF="
     cwg_defects.html#1">issue 1</A>.</P></LI>

</OL>

(See also issues
<A HREF="
     cwg_defects.html#21">21</A>,
<A HREF="
     cwg_closed.html#95">95</A>,
<A HREF="
     cwg_active.html#138">138</A>,
<A HREF="
     cwg_defects.html#139">139</A>,
<A HREF="
     cwg_defects.html#143">143</A>,
<A HREF="
     cwg_closed.html#165">165</A>, and
<A HREF="
     cwg_defects.html#166">166</A>.)

<P><B>Notes from 10/99 meeting:</B></P>

<P>Four possible outcomes were identified:</P>

<OL>

<LI>If a friend declaration declares a default parameter, allow no
other declarations of that function in the translation unit.</LI>

<LI>Same as preceding, but only allow the friend declaration if it is
also a definition.</LI>

<LI>Disallow default arguments in friend declarations.</LI>

<LI>Treat the default arguments in each friend declaration as a
distinct set, causing an error if the call would be ambiguous.</LI>

</OL>

<P>The core group eliminated the first and fourth options from
consideration, but split fairly evenly between the remaining two.</P>

<P>A straw poll of the full committee yielded the following results
(given as number favoring/could live with/"over my dead body"):</P>

<OL>

<LI>0/14/5</LI>

<LI>8/13/5</LI>

<LI>11/7/14</LI>

<LI>7/10/9</LI>

</OL>

<P>Additional discussion is recorded in the "Record of Discussion" for
the meeting, J16/99-0036 = WG21 N1212.  See also paper
J16/00-0040 = WG21 N1263.</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>In 8.3.6 [dcl.fct.default], add following paragraph 4:</P>

<BLOCKQUOTE>

If a friend declaration specifies a default argument expression,
that declaration must be a definition and shall be the only declaration
of the function or function template in the translation unit.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="5"></A><H4>5.
  
CV-qualifiers and type conversions
</H4><B>Section: </B>8.5&#160; [dcl.init]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Josee Lajoie
 &#160;&#160;&#160;

 <B>Date: </B>unknown<BR>



<P>[Moved to DR at 4/01 meeting.]</P>



<P>The description of copy-initialization in 8.5 [dcl.init]
 paragraph 14 says:</P>
<UL>
<LI>
If the destination type is a (possibly cv-qualified) class type:

<BR>&#160;...</LI>
<LI>
Otherwise (i.e. for the remaining copy-initialization cases), user-defined
conversion sequences that can convert from the source type to the destination
type or (when a conversion function is used) to a derived class thereof
are enumerated ... if the function is a constructor, the call initializes
a temporary of the destination type. ...
</LI></UL>
Should "destination type" in this last bullet refer to "cv-unqualified
destination type" to make it clear that the destination type excludes any
cv-qualifiers? This would make it clearer that the following example is
well-formed:
<PRE>
     struct A {
       A(A&amp;);
     };
     struct B : A { };
     
     struct C {
       operator B&amp;();
     };
     
     C c;
     const A a = c; // allowed?
</PRE>
<P>The temporary created with the conversion function is an lvalue of type
<TT>B</TT>. If the temporary must have the cv-qualifiers of the destination
type (i.e. const) then the copy-constructor for <TT>A</TT> cannot be called
to create the object of type <TT>A</TT> from the lvalue of type <TT>const
B</TT>. If the temporary has the cv-qualifiers of the result type of the
conversion function, then the copy-constructor for <TT>A</TT> can be called
to create the object of type <TT>A</TT> from the lvalue of type <TT>const
B</TT>. This last outcome seems more appropriate.</P>

<P><U>Steve Adamczyk</U>: </P>
<P>Because of late changes to this area, the
relevant text is now the third sub-bullet of the fourth bullet of
8.5 [dcl.init] paragraph 14:</P>

<BLOCKQUOTE>

Otherwise (i.e., for the remaining copy-initialization cases),
user-defined conversion sequences that can convert from the source
type to the destination type or (when a conversion function is used)
to a derived class thereof are enumerated...
The function selected is called with the initializer expression as its
argument; if the function is a constructor, the call initializes a
temporary of the destination type.  The result of the call (which is
the temporary for the constructor case) is then used to
direct-initialize, according to the rules above, the object that is
the destination of the copy-initialization.

</BLOCKQUOTE>

<P>The issue still remains whether the wording should refer to "the
cv-unqualified version of the destination type."  I think it
should.
</P>

<P><B>Notes from 10/00 meeting:</B></P>

<P>The original example does not illustrate the remaining
problem.  The following example does:</P>

<PRE>
    struct C { };
    C c;
    struct A {
        A(const A&amp;);
        A(const C&amp;);
    };
    const volatile A a = c;    // Okay
</PRE>

<P><B>Proposed Resolution (04/01):</B></P>

<P>In 8.5 [dcl.init], paragraph 14, bullet 4,
sub-bullet 3, change</P>

<BLOCKQUOTE>

if the function is a constructor, the call initializes a temporary
of the destination type.

</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>

if the function is a constructor, the call initializes a temporary
of the cv-unqualified version of the destination type.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="78"></A><H4>78.
  
Section 8.5 paragraph 9 should state it only applies to non-static objects
</H4><B>Section: </B>8.5&#160; [dcl.init]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Judy Ward
 &#160;&#160;&#160;

 <B>Date: </B>15 Dec 1998<BR>



<P>Paragraph 9 of
8.5 [dcl.init]

 says:</P>
<BLOCKQUOTE>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 an object, the object and
its subobjects, if any, have an indeterminate initial value; if the object
or any of its subobjects are of const-qualified type, the program is ill-formed.</BLOCKQUOTE>
It should be made clear that this paragraph does not apply to static objects.

<P><B>Proposed resolution (10/00):</B> In
8.5 [dcl.init]
 paragraph 9, replace</P>
<BLOCKQUOTE>
Otherwise, if no initializer is specified for an object..."
</BLOCKQUOTE>
with
<BLOCKQUOTE>
Otherwise, if no initializer is specified for a <SPAN style="font-weight:bold;background-color:#A0FFA0">non-static</SPAN>
object...
</BLOCKQUOTE>

<BR><BR><HR><A NAME="177"></A><H4>177.
  
Lvalues vs rvalues in copy-initialization
</H4><B>Section: </B>8.5&#160; [dcl.init]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>25 October 1999<BR>



<P>[Moved to DR at 4/02 meeting.]</P>

<P>Is the temporary created during copy-initialization of a class object
treated as an lvalue or an rvalue?  That is, is the following example
well-formed or not?</P>

<PRE>
    struct B { };
    struct A {
        A(A&amp;);    // not const
        A(const B&amp;);
    };
    B b;
    A a = b;
</PRE>

<P>According to 8.5 [dcl.init]
 paragraph
14, the initialization of <TT>a</TT> is performed in two steps.
First, a temporary of type <TT>A</TT> is created using <TT>A::A(const
B&amp;)</TT>.  Second, the resulting temporary is used to
direct-initialize <TT>a</TT> using <TT>A::A(A&amp;)</TT>.</P>

<P>The second step requires binding a reference to non-const to the
temporary resulting from the first step.  However,
8.5.3 [dcl.init.ref]
 paragraph 5 requires
that such a reference be bound only to lvalues.</P>

<P>It is not clear from 3.10 [basic.lval]

whether the temporary created in the process of copy-initialization
should be treated as an lvalue or an rvalue.  If it is an lvalue, the
example is well-formed, otherwise it is ill-formed.</P>

<P><B>Proposed resolution (04/01):</B></P>

<OL>
<LI><P>In 8.5 [dcl.init] paragraph 14, insert
the following after "the call initializes a temporary of
the destination type":</P>

<BLOCKQUOTE>

The temporary is an rvalue.

</BLOCKQUOTE>
</LI>

<LI><P>In 15.1 [except.throw] paragraph 3, replace</P>

<BLOCKQUOTE>

The temporary is used to initialize the variable...

</BLOCKQUOTE>

<P>with</P>

<BLOCKQUOTE>

The temporary is an lvalue and is used to initialize
the variable...

</BLOCKQUOTE>

</LI>

</OL>

<P>(See also <A HREF="
     cwg_defects.html#84">issue 84</A>.)</P>
<BR><BR><HR><A NAME="277"></A><H4>277.
  
Zero-initialization of pointers
</H4><B>Section: </B>8.5&#160; [dcl.init]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Andrew Sawyer
 &#160;&#160;&#160;

 <B>Date: </B>5 Apr 2001<BR>


<P>[Moved to DR at 10/01 meeting.]</P>



<P>The intent of 8.5 [dcl.init] paragraph 5 is that
pointers that are zero-initialized will contain a null pointer
value.  Unfortunately, the wording used,</P>

<BLOCKQUOTE>

...set to the value of 0 (zero) converted to <TT>T</TT>

</BLOCKQUOTE>

<P>does not match the requirements for creating a null pointer
value given in 4.10 [conv.ptr] paragraph 1:</P>

<BLOCKQUOTE>

A <I>null pointer constant</I> is an integral constant expression
(5.19 [expr.const]) rvalue of integer type that evaluates to
zero. A null pointer constant can be converted to a pointer type; the
result is the <I>null pointer value</I> of that type...

</BLOCKQUOTE>

<P>The problem is that the "value of 0" in the description of
zero-initialization is not specified to be an integral constant
expression.  Nonconstant expressions can also have the value 0,
and converting a nonconst 0 to pointer type need not result in
a null pointer value.</P>

<P><B>Proposed resolution (04/01):</B></P>

<P>In 8.5 [dcl.init] paragraph 5, change</P>

<BLOCKQUOTE>

...set to the value 0 (zero) converted to <TT>T</TT>;

</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>

...set to the value 0 (zero), taken as an integral constant
expression, converted to <TT>T</TT>; [<I>footnote:</I> as
specified in 4.10 [conv.ptr], converting an integral
constant expression whose value is 0 to a pointer type results
in a null pointer value.]

</BLOCKQUOTE>

<BR><BR><HR><A NAME="302"></A><H4>302.
  
Value-initialization and generation of default constructor
</H4><B>Section: </B>8.5&#160; [dcl.init]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>23 Jul 2001<BR>


<P>[Moved to DR at October 2002 meeting.]</P>



<P>We've been looking at implementing value-initialization.  At one point,
some years back, I remember Bjarne saying that something like X() in
an expression should produce an X object with the same value one would
get if one created a static X object, i.e., the uninitialized members
would be zero-initialized because the whole object is initialized
at program startup, before the constructor is called.</P>

<P>The formulation for default-initialization that made it into TC1 (in
8.5 [dcl.init])
is written a little differently (see <A HREF="
     cwg_defects.html#178">issue 178</A>),
but I had always 
assumed that it would still be a valid implementation to zero the whole 
object and then call the default constructor for the troublesome
"non-POD but no user-written constructor" cases.</P>

<P>That almost works correctly, but I found a problem case:</P>
<PRE>
    struct A {
      A();
      ~A();
    };
    struct B {
      // B is a non-POD with no user-written constructor.
      // It has a nontrivial generated constructor.
      const int i;
      A a;
    };
    int main () {
      // Value-initializing a "B" doesn't call the default constructor for
      // "B"; it value-initializes the members of B.  Therefore it shouldn't
      // cause an error on generation of the default constructor for the
      // following:
      new B();
    }
</PRE>

<P>If the definition of the <TT>B::B()</TT> constructor is generated, an error
is issued because the const member "<TT>i</TT>" is not initialized.  But the
definition of value-initialization doesn't require calling the
constructor, and therefore it doesn't require generating it, and
therefore the error shouldn't be detected.</P>

<P>So this is a case where zero-initializing and then calling the constructor
is not equivalent to value-initializing, because one case generates
an error and the other doesn't.</P>

<P>This is sort of unfortunate, because one doesn't want to generate all
the required initializations at the point where the "<TT>()</TT>"
initialization
occurs.  One would like those initializations to be packaged in a
function, and the default constructor is pretty much the function
one wants.</P>

<P>I see several implementation choices:</P>
<OL>
<LI>
Zero the object, then call the default generated constructor.  This
is not valid unless the standard is changed to say that the default 
constructor might be generated for value-initialization cases like the
above (that is, it's implementation-dependent whether the constructor
definition is generated).  The zeroing operation can of course be
optimized, if necessary, to hit only the pieces of the object that
would otherwise be left uninitialized.  An alternative would be
to <I>require</I> generation of the constructor for value-initialization
cases, even if the implementation technique doesn't call the
constructor at that point.  It's pretty likely that the constructor
is going to have to be generated at some point in the program anyway.
</LI>
<LI>
Make a new value-initialization "constructor," whose body looks a
lot like the usual generated constructor, but which also zeroes other members.
No errors would be generated while generating this modified constructor,
because it generates code that does full initialization.  (Actually,
it wouldn't guarantee initialization of reference members, and that
might be an argument for generating the constructor, in order to get that
error.)  This is standard-conforming, but it destroys object-code 
compatibility.
</LI>
<LI>
Variation on (1):  Zero first, and generate the object code for the 
default constructor when it's needed for value-initialization cases, but 
don't issue any errors at that time.  Issue the errors only if it turns 
out the constructor is "really" referenced.  Aside from the essential
shadiness of this approach, I fear that something in the generation
of the constructor will cause a template instantiation which will be
an abservable side effect.
</LI>
</OL>

<P>Personally, I find option 1 the least objectionable.</P>

<P><B>Proposed resolution (10/01):</B></P>

<P>Add the indicated wording to the third-to-last sentence of
3.2 [basic.def.odr] pararaph 2:</P>
<BLOCKQUOTE>
A default constructor for a class is used by default initialization
<SPAN style="font-weight:bold;background-color:#A0FFA0">or value initialization</SPAN> as specified in 8.5 [dcl.init].
</BLOCKQUOTE>
<P>Add a footnote to the indicated bullet in 8.5 [dcl.init]
paragraph 5:</P>
<UL>
<LI>
if <TT>T</TT> is a non-union class type without a user-declared constructor,
then every non-static data member and base-class component of <TT>T</TT> is
value-initialized.
<SPAN style="font-weight:bold;background-color:#A0FFA0">[Footnote: Value-initialization for such a class object may be
implemented by zero-initializing the object and then calling the default
constructor.]</SPAN>
</LI>
</UL>
<P>Add the indicated wording to the first sentence of
12.1 [class.ctor] paragraph 7:</P>
<BLOCKQUOTE>
An implicitly-declared default constructor for a class is <I>implicitly
defined</I> when it is used <SPAN style="font-weight:bold;background-color:#A0FFA0">(3.2 [basic.def.odr])</SPAN> to
create an object of its class type
(1.8 [intro.object]).
</BLOCKQUOTE>

<BR><BR><HR><A NAME="509"></A><H4>509.
  
Dead code in the specification of default initialization
</H4><B>Section: </B>8.5&#160; [dcl.init]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>18 Mar 2005<BR>


<P>[Voted into the WP at the September, 2008 meeting (resolution
in paper N2762).]</P>

<P>The definition of default initialization (8.5 [dcl.init]
paragraph 5) is:</P>

<BLOCKQUOTE>

<UL>

<LI><P>if <TT>T</TT> is a non-POD class type (clause 9 [class]), the default constructor for <TT>T</TT> is called (and the
initialization is ill-formed if <TT>T</TT> has no accessible default
constructor);</P></LI>

<LI><P>if <TT>T</TT> is an array type, each element is
default-initialized;</P></LI>

<LI><P>otherwise, the object is zero-initialized.</P></LI>

</UL>

</BLOCKQUOTE>

<P>However, default initialization is invoked only for non-POD class
types and arrays thereof (5.3.4 [expr.new] paragraph 15
for <I>new-expression</I>s, 8.5 [dcl.init] paragraph 10
for top-level objects, and 12.6.2 [class.base.init] paragraph 4
for member and base class subobjects&#160;&#8212; but see
<A HREF="
     cwg_defects.html#510">issue 510</A>).  Consequently, all cases that
invoke default initialization are handled by the first two bullets;
the third bullet can never be reached.  Its presence is misleading, so
it should be removed.</P>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>The approach adopted in the resolution in paper N2762 was
different from the suggestion above: it changes the definition of
default initialization to include POD types and changes the third
bullet to specify that &#8220;no initialization is
performed.&#8221;</P>

<BR><BR><HR><A NAME="543"></A><H4>543.
  
Value initialization and default constructors
</H4><B>Section: </B>8.5&#160; [dcl.init]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>27 October 2005<BR>


<P>[Voted into the WP at the September, 2008 meeting (resolution
in paper N2762).]</P>

<P>The wording resulting from the resolution of
<A HREF="
     cwg_defects.html#302">issue 302</A> does not quite implement the intent
of the issue.  The revised wording of 3.2 [basic.def.odr]
paragraph 2 is:</P>

<BLOCKQUOTE>

A default constructor for a class is used by default initialization or
value initialization as specified in 8.5 [dcl.init].

</BLOCKQUOTE>

<P>This sounds as if 8.5 [dcl.init] specifies how and
under what circumstances value initialization uses a default
constructor (which was, in fact, the case for default initialization
in the original wording).  However, the normative text there makes it
plain that value initialization does <I>not</I> call the default
constructor (the permission granted to implementations to call the
default constructor for value initialization is in a non-normative
footnote).</P>

<P>The example that occasioned this observation raises an
additional question.  Consider:</P>

<PRE>
    struct POD {
      const int x;
    };

    POD data = POD();
</PRE>

<P>According to the (revised) resolution of issue 302, this code is
ill-formed because the implicitly-declared default constructor will
be implicitly defined as a result of being used by value initialization
(12.1 [class.ctor] paragraph 7), and the implicitly-defined
constructor fails to initialize a const-qualified member
(12.6.2 [class.base.init] paragraph 4).  This seems unfortunate,
because the (trivial) default constructor of a POD class is otherwise
not used &#8212; default initialization applies only to non-PODs
&#8212; and it is not actually needed in value initialization.
Perhaps value initialization should be defined to &#8220;use&#8221;
the default constructor only for non-POD classes?  If so, both of
these problems would be resolved by rewording the above-referenced
sentence of 3.2 [basic.def.odr] paragraph 2 as:</P>

<BLOCKQUOTE>

A default constructor for a <SPAN style="font-weight:bold;background-color:#A0FFA0">non-POD</SPAN> class is used by
default initialization or value initialization <SPAN style="text-decoration:line-through;background-color:#FFA0A0">as specified in</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">(</SPAN>8.5 [dcl.init]<SPAN style="font-weight:bold;background-color:#A0FFA0">)</SPAN>.

</BLOCKQUOTE>

<P><B>Notes from the April, 2006 meeting:</B></P>

<P>The approach favored by the CWG was to leave 3.2 [basic.def.odr]
unchanged and to add normative wording to 8.5 [dcl.init]
indicating that it is unspecified whether the default constructor is
called.</P>

<P><B>Notes from the October, 2006 meeting:</B></P>

<P>The CWG now prefers that it should not be left unspecified whether
programs of this sort are well- or ill-formed; instead, the Standard
should require that the default constructor be defined in such cases.
Three possibilities of implementing this decision were discussed:</P>

<OL>
<LI><P>Change 3.2 [basic.def.odr] to state flatly that the
default constructor is used by value initialization (removing the
implication that 8.5 [dcl.init] determines the conditions
under which it is used).</P></LI>

<LI><P>Change 8.5 [dcl.init] to specify that non-union
class objects with no user-declared constructor are value-initialized
by first zero-initializing the object and then calling the
(implicitly-defined) default constructor, replacing the current
specification of value-initializing each of its sub-objects.</P></LI>

<LI><P>Add a normative statement to 8.5 [dcl.init] that
value-initialization causes the implicitly-declared default constructor
to be implicitly defined, even if it is not called.</P></LI>

</OL>

<P><B>Proposed resolution (June, 2008):</B></P>

<P>Change the second bullet of the value-initialization definition
in 8.5 [dcl.init] paragraph 5 as follows:</P>

<UL><LI><P>if <TT>T</TT> is a non-union class type without a
user-provided constructor, then <SPAN style="text-decoration:line-through;background-color:#FFA0A0">every non-static data member and
base-class component of <TT>T</TT> is value-initialized;
[<I>Footnote:</I> Value-initialization for such a class object may be
implemented by zero-initializing the object and then calling the
default constructor. &#8212;<I>end footnote</I>]</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">the object is
zero-initialized and the implicitly-defined default constructor is
called;</SPAN></P></LI></UL>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>The resolution supplied in paper N2762 differs from the June,
2008 proposed resolution in that the implicitly-declared default
constructor is only called (and thus defined) if it is
non-trivial, making the <TT>struct POD</TT> example above
well-formed.</P>

<BR><BR><HR><A NAME="430"></A><H4>430.
  
Ordering of expression evaluation in initializer list
</H4><B>Section: </B>8.5.1&#160; [dcl.init.aggr]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Nathan Sidwell
 &#160;&#160;&#160;

 <B>Date: </B>23 July 2003<BR>


<P>[Voted into the WP at the April, 2007 meeting as part of paper
J16/07-0099 = WG21 N2239.]</P>



<P>A recent GCC bug report
(<A HREF="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11633">
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11633</A>)
asks about the validity of
<PRE>
  int count = 23;
  int foo[] = { count++, count++, count++ };
</PRE>
is this undefined or unspecified or something else? I can find nothing in
8.5.1 [dcl.init.aggr] that indicates whether the components of
an initializer-list are evaluated in order or not, or whether they
have sequence points between them.</P>

<P>6.7.8/23 of the C99 std has this to say
<BLOCKQUOTE>
The order in which any side effects occur among the initialization list
expressions is unspecified.
</BLOCKQUOTE>
I think similar wording is needed in 8.5.1 [dcl.init.aggr]</P>

<P><U>Steve Adamczyk:</U>
I believe the standard is clear that each initializer
expression in the above is a full-expression
(1.9 [intro.execution]/12-13; see also
<A HREF="
     cwg_defects.html#392">issue 392</A>) and therefore there is a sequence point
after each expression (1.9 [intro.execution]/16).  I agree that the
standard does not seem to dictate the order in which the expressions
are evaluated, and perhaps it should.  Does anyone know of a compiler
that would not evaluate the expressions left to right?</P>

<P><U>Mike Simons:</U> Actually there is one, that does not do
left to right: gcc/C++.  None of the post increment operations
take effect until after the statement finishes.  So in the sample
code gcc stores 23 into all positions in the array.  The
commercial vendor C++ compilers for AIX, Solaris, Tru64, HPUX
(parisc and ia64), and Windows, all do sequence points at each
',' in the initializer list.</P>

<BR><BR><HR><A NAME="491"></A><H4>491.
  
Initializers for empty-class aggregrate members
</H4><B>Section: </B>8.5.1&#160; [dcl.init.aggr]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Nathan Sidwell
 &#160;&#160;&#160;

 <B>Date: </B>15 Dec 2004<BR>


<P>[Voted into WP at April, 2007 meeting.]</P>

<P>The current wording of 8.5.1 [dcl.init.aggr] paragraph
8 requires that</P>

<BLOCKQUOTE>

An <I>initializer</I> for an aggregate member that is an empty class
shall have the form of an empty initializer-list <TT>{}</TT>.

</BLOCKQUOTE>

<P>This is overly constraining.  There is no reason that the
following should be ill-formed:</P>

<PRE>
    struct S { };
    S s;
    S arr[1] = { s };
</PRE>

<P><U>Mike Miller</U>: The wording of 8.5.1 [dcl.init.aggr] paragraph 8 is unclear.  &#8220;An aggregate
member&#8221; would most naturally mean &#8220;a member of an
aggregate.&#8221; In context, however, I think it must mean
&#8220;a member [of an aggregate] that is an aggregate&#8221;,
that is, a subaggregate.  Members of aggregates need not
themselves be aggregates (cf paragraph 13 and 12.6.1 [class.expl.init]); it cannot be the case that an object of an
empty class with a user-declared constructor must be initialized
with <TT>{}</TT> when it is a member of an aggregate.  This
wording should be clarified, regardless of the decision on
Nathan's point.</P>

<P><B>Proposed resolution (October, 2005):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#413">issue 413</A>.</P>

<BR><BR><HR><A NAME="632"></A><H4>632.
  
Brace-enclosed initializer for scalar member of aggregate
</H4><B>Section: </B>8.5.1&#160; [dcl.init.aggr]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Greg Comeau
 &#160;&#160;&#160;

 <B>Date: </B>3 May 2007<BR>


<P>[Voted into the WP at the June, 2008 meeting as part of paper N2672.]</P>

<P>C (both C90 and C99) appear to allow a declaration of the form</P>

<PRE>
    struct S { int i; } s = { { 5 } };
</PRE>

<P>in which the initializer of a scalar member of an aggregate can
itself be brace-enclosed.  The relevant wording from the C99
Standard is found in 6.7.8 paragraph 11:</P>

<BLOCKQUOTE>

The initializer for a scalar shall be a single expression,
optionally enclosed in braces.

</BLOCKQUOTE>

<P>and paragraph 16:</P>

<BLOCKQUOTE>

Otherwise, the initializer for an object that has aggregate or
union type shall be a brace-enclosed list of initializers for the
elements or named members.

</BLOCKQUOTE>

<P>The &#8220;list of initializers&#8221; in paragraph 16 must be
a recursive reference to paragraph 11 (that's the only place that
describes how an initialized item gets its value from the
initializer expression), which would thus make the
&#8220;brace-enclosed&#8221; part of paragraph 11 apply to each of
the initializers in the list in paragraph 16 as well.</P>

<P>This appears to be an incompatibility between C and C++:
8.5.1 [dcl.init.aggr] paragraph 11 says,</P>

<BLOCKQUOTE>

If the <I>initializer-list</I> begins with a left brace, then the
succeeding comma-separated list of <I>initializer-clause</I>s
initializes the members of a subaggregate....

</BLOCKQUOTE>

<P>which clearly leaves the impression that only a subaggregate
may be initialized by a brace-enclosed <I>initializer-clause</I>.</P>

<P>Either the specification in 8.5.1 [dcl.init.aggr]
should be changed to allow a brace-enclosed initializer of a
scalar member of an aggregate, as in C, or this incompatibility
should be listed in Appendix C [diff].</P>

<P><B>Notes from the July, 2007 meeting:</B></P>

<P>It was noted that implementations differ in their handling of this
construct; however, the issue is long-standing and fairly obscure.</P>

<P><B>Notes from the October, 2007 meeting:</B></P>

<P>The initializer-list proposal will resolve this issue when it is
adopted.</P>

<BR><BR><HR><A NAME="291"></A><H4>291.
  
Overload resolution needed when binding reference to class rvalue
</H4><B>Section: </B>8.5.3&#160; [dcl.init.ref]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Andrei Iltchenko
 &#160;&#160;&#160;

 <B>Date: </B>15 Jun 2001<BR>


<P>[Voted into WP at October 2005 meeting.]</P>

<P>There is a place in the Standard where overload resolution is implied
but the way that a set of candidate functions is to be formed is
omitted. See below.</P>

<P>According to the Standard, when initializing a reference to a
non-volatile const class type (<I>cv1</I> <TT>T1</TT>) with an rvalue
expression (<I>cv2</I> <TT>T2</TT>) where <I>cv1</I> <TT>T1</TT> is
reference compatible with <I>cv2</I> <TT>T2</TT>, the implementation
shall proceed in one of the following
ways (except when initializing the implicit object parameter of a
copy constructor) 8.5.3 [dcl.init.ref] paragraph 5 bullet 2
sub-bullet 1:</P>

<UL>
<LI>
The reference is bound to the object represented by the rvalue (see
3.10 [basic.lval]) or to a sub-object within that object.
</LI>
<LI>
A temporary of type "<I>cv1</I> <TT>T2</TT>" [sic] is created, and a
constructor is called to copy the entire rvalue object into the temporary...
</LI>
</UL>

<P>While the first case is quite obvious, the second one is a bit unclear
as it says "a constructor is called to copy the entire rvalue object
into the temporary" without specifying how the temporary is created --
by direct-initialization or by copy-initialization? As stated in DR
152, this can make a difference when the copy constructor is declared
as explicit. How should the set of candidate functions be formed? The
most appropriate guess is that it shall proceed as per
13.3.1.3 [over.match.ctor].</P>

<P>Another detail worth of note is that in the draft version of the
Standard as of 2 December 1996 the second bullet read:</P>

<UL>
<LI>
A temporary of type "<I>cv1</I> <TT>T2</TT>" [sic] is created, and a copy
constructor is called to copy the entire rvalue object into the
temporary...
</LI>
</UL>

<P>J. Stephen Adamczyk replied that the reason for changing "a copy
constructor" to "a constructor" was to allow for member template
converting constructors.</P>

<P>However, the new wording is somewhat in conflict with the footnote #93
that says that when initializing the implicit object parameter of a
copy constructor an implementation must eventually choose the first
alternative (binding without copying) to avoid infinite recursion.
This seems to suggest that a copy constructor is always used for
initializing the temporary of type "<I>cv1</I> <TT>T2</TT>".</P>

<P>Furthermore, now that the set of candidate functions is not limited to
only the copy constructors of <TT>T2</TT>, there might be some unpleasant
consequences.
Consider a rather contrived sample below:</P>

<PRE>
    int   * pi = ::new(std::nothrow) int;
    const std::auto_ptr&lt;int&gt;   &amp; ri = std::auto_ptr&lt;int&gt;(pi);
</PRE>

<P>In this example the initialization of the temporary of type
'<TT>&lt;TT&gt;const std::auto_ptr&lt;int&gt;</TT>'
(to which '<TT>ri</TT>' is meant to be subsequently bound)
doesn't fail, as it would had the approach with copy constructors been
retained, instead, a yet another temporary gets created as the
well-known sequence:</P>
<PRE>
    std::auto_ptr&lt;int&gt;::operator std::auto_ptr_ref&lt;int&gt;()
    std::auto_ptr&lt;int&gt;(std::auto_ptr_ref&lt;int&gt;)
</PRE>
<P>is called (assuming, of course, that the set of candidate functions is
formed as per 13.3.1.3 [over.match.ctor]). The second temporary
is transient and gets
destroyed at the end of the initialization. I doubt that this is the
way that the committee wanted this kind of reference binding to go.</P>

<P>Besides, even if the approach restricting the set of candidates to copy
constructors is restored, it is still not clear how the initialization
of the temporary (to which the reference is intended to be bound) is
to be performed -- using direct-initialization or copy-initialization.</P>

<P>Another place in the Standard that would benefit from a similar
clarification is the creation of an exception object, which is
delineated in 15.1 [except.throw].</P>

<P><U>David Abrahams (February 2004):</U>
It appears, looking at core 291, that there may be a need to tighten
up 8.5.3 [dcl.init.ref]/5.  </P>

<P>Please see the attached example file, which demonstrates "move
semantics" in C++98.  Many compilers fail to compile test 10 because
of the way 8.5.3/5 is interpreted.  My problem with that
interpretation is that test 20:
<PRE>
    typedef X const XC;
    sink2(XC(X()));
</PRE>
does compile.  In other words, it *is* possible to construct the const
temporary from the rvalue.  IMO, that is the proper test.</P>

<P>8.5.3/5 doesn't demand that a "copy constructor" is used to copy the
temporary, only that a constructor is used "to copy the temporary".
I hope that when the language is tightened up to specify direct (or
copy initialization), that it also unambiguously allows the enclosed
test to compile.  Not only is it, I believe, within the scope of
reasonable interpretation of the current standard, but it's an
incredibly important piece of functionality for library writers and
users alike.</P>

<PRE>
#include &lt;iostream&gt;
#include &lt;cassert&gt;

template &lt;class T, class X&gt;
struct enable_if_same
{
};

template &lt;class X&gt;
struct enable_if_same&lt;X, X&gt;
{
    typedef char type;
};

struct X
{
    static int cnt;  // count the number of Xs
    
    X()
      : id(++cnt)
      , owner(true)
    {
        std::cout &lt;&lt; "X() #" &lt;&lt; id &lt;&lt; std::endl;
    }
    
    // non-const lvalue - copy ctor
    X(X&amp; rhs)
      : id(++cnt)
      , owner(true)
    {
        std::cout &lt;&lt; "copy #" &lt;&lt; id &lt;&lt; " &lt;- #" &lt;&lt; rhs.id &lt;&lt; std::endl;
    }

    // const lvalue - T will be deduced as X const
    template &lt;class T&gt;
    X(T&amp; rhs, typename enable_if_same&lt;X const,T&gt;::type = 0)
      : id(++cnt)
      , owner(true)
    {
        std::cout &lt;&lt; "copy #" &lt;&lt; id &lt;&lt; " &lt;- #" &lt;&lt; rhs.id &lt;&lt; " (const)" &lt;&lt; std::endl;
    }

    ~X()
    {
        std::cout &lt;&lt; "destroy #" &lt;&lt; id &lt;&lt; (owner?"":" (EMPTY)") &lt;&lt; std::endl;
    }
    
 private:    // Move stuff
    struct ref { ref(X*p) : p(p) {} X* p; };

 public:    // Move stuff
    operator ref() {
        return ref(this);
    }

    // non-const rvalue
    X(ref rhs)
      : id(++cnt)
      , owner(rhs.p-&gt;owner)
    {
        std::cout &lt;&lt; "MOVE #" &lt;&lt; id &lt;&lt; " &lt;== #" &lt;&lt; rhs.p-&gt;id &lt;&lt; std::endl;
        rhs.p-&gt;owner = false;
        assert(owner);
    }
    
 private:   // Data members
    int id;
    bool owner;
};

int X::cnt;


X source()
{
    return X();
}

X const csource()
{
    return X();
}

void sink(X)
{
    std::cout &lt;&lt; "in rvalue sink" &lt;&lt; std::endl;
}

void sink2(X&amp;)
{
    std::cout &lt;&lt; "in non-const lvalue sink2" &lt;&lt; std::endl;
}

void sink2(X const&amp;)
{
    std::cout &lt;&lt; "in const lvalue sink2" &lt;&lt; std::endl;
}

void sink3(X&amp;)
{
    std::cout &lt;&lt; "in non-const lvalue sink3" &lt;&lt; std::endl;
}

template &lt;class T&gt;
void tsink(T)
{
    std::cout &lt;&lt; "in templated rvalue sink" &lt;&lt; std::endl;
}

int main()
{
    std::cout &lt;&lt; " ------ test 1, direct init from rvalue ------- " &lt;&lt; std::endl;
#ifdef __GNUC__ // GCC having trouble parsing the extra parens
    X z2((0, X() ));
#else
    X z2((X()));
#endif 

    std::cout &lt;&lt; " ------ test 2, copy init from rvalue ------- " &lt;&lt; std::endl;
    X z4 = X();

    std::cout &lt;&lt; " ------ test 3, copy init from lvalue ------- " &lt;&lt; std::endl;
    X z5 = z4;

    std::cout &lt;&lt; " ------ test 4, direct init from lvalue ------- " &lt;&lt; std::endl;
    X z6(z4);
    
    std::cout &lt;&lt; " ------ test 5, construct const ------- " &lt;&lt; std::endl;
    X const z7;
    
    std::cout &lt;&lt; " ------ test 6, copy init from lvalue ------- " &lt;&lt; std::endl;
    X z8 = z7;

    std::cout &lt;&lt; " ------ test 7, direct init from lvalue ------- " &lt;&lt; std::endl;
    X z9(z7);
    
    std::cout &lt;&lt; " ------ test 8, pass rvalue by-value ------- " &lt;&lt; std::endl;
    sink(source());
    
    std::cout &lt;&lt; " ------ test 9, pass const rvalue by-value ------- " &lt;&lt; std::endl;
    sink(csource());

    std::cout &lt;&lt; " ------ test 10, pass rvalue by overloaded reference ------- " &lt;&lt; std::endl;
    // This one fails in Comeau's strict mode due to 8.5.3/5.  GCC 3.3.1 passes it.
    sink2(source());

    std::cout &lt;&lt; " ------ test 11, pass const rvalue by overloaded reference ------- " &lt;&lt; std::endl;
    sink2(csource());

#if 0    // These two correctly fail to compile, just as desired
    std::cout &lt;&lt; " ------ test 12, pass rvalue by non-const reference ------- " &lt;&lt; std::endl;
    sink3(source());

    std::cout &lt;&lt; " ------ test 13, pass const rvalue by non-const reference ------- " &lt;&lt; std::endl;
    sink3(csource());
#endif 

    std::cout &lt;&lt; " ------ test 14, pass lvalue by-value ------- " &lt;&lt; std::endl;
    sink(z5);
    
    std::cout &lt;&lt; " ------ test 15, pass const lvalue by-value ------- " &lt;&lt; std::endl;
    sink(z7);

    std::cout &lt;&lt; " ------ test 16, pass lvalue by-reference ------- " &lt;&lt; std::endl;
    sink2(z4);

    std::cout &lt;&lt; " ------ test 17, pass const lvalue by const reference ------- " &lt;&lt; std::endl;
    sink2(z7);

    std::cout &lt;&lt; " ------ test 18, pass const lvalue by-reference ------- " &lt;&lt; std::endl;
#if 0   // correctly fails to compile, just as desired
    sink3(z7);
#endif 

    std::cout &lt;&lt; " ------ test 19, pass rvalue by value to template param ------- " &lt;&lt; std::endl;
    tsink(source());

    std::cout &lt;&lt; " ------ test 20, direct initialize a const A with an A ------- " &lt;&lt; std::endl;
    typedef X const XC;
    sink2(XC(X()));
}
</PRE>

<P><B>Proposed Resolution:</B></P>

<P>(As proposed by N1610 section 5, with editing.)</P>

<P>Change  paragraph 5, second bullet,
first sub-bullet, second sub-sub-bullet as follows:</P>
<BLOCKQUOTE>
A temporary of type "<I>cv1</I> <TT>T2</TT>" [sic] is created<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, and a
constructor is called to copy the entire rvalue object into the temporary</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">via copy-initialization from the entire rvalue object</SPAN>.
The  reference  is  bound  to  the  temporary or to a sub-object
within the temporary.
</BLOCKQUOTE>

<P>The text immediately following that is changed as follows:</P>
<BLOCKQUOTE>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The  constructor  that  would  be  used  to make the copy shall be
callable whether or not the copy is actually done.</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">The constructor and any conversion function that would be used in the
initialization shall be callable whether or not the temporary is
actually created. </SPAN>
</BLOCKQUOTE>

<P>Note, however, that the way the core working group is leaning
on <A HREF="
     cwg_defects.html#391">issue 391</A> (i.e., requiring direct
binding) would make this change unnecessary.</P>

<P><B>Proposed resolution (April, 2005):</B></P>

<P>This issue is resolved by the resolution of <A HREF="
     cwg_defects.html#391">issue 391</A>.</P>

<BR><BR><HR><A NAME="391"></A><H4>391.
  
Require direct binding of short-lived references to rvalues
</H4><B>Section: </B>8.5.3&#160; [dcl.init.ref]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Raoul Gough
 &#160;&#160;&#160;

 <B>Date: </B>14 Nov 2002<BR>


<P>[Voted into WP at October 2005 meeting.]</P>

<P>After some email exchanges with Rani Sharoni, I've come up
with the following proposal to allow reference binding to
non-copyable rvalues in some cases. Rationale and some
background appear afterwards.</P>

<P><B>---- proposal ----</B></P>

<P>Replace the section of 8.5.3 [dcl.init.ref] paragraph 5
that begins "If the initializer expression is an rvalue" with the
following:</P>
<UL>
<LI>
If the initializer expression is an rvalue, with T2 a
class type, and ``cv1 T1'' is reference-compatible with
``cv2 T2,'' the reference is bound as follows:
<UL>
<LI>
If the lifetime of the reference does not extend
beyond the end of the full expression containing the
initializer expression, the reference is bound to
the object represented by the rvalue (see 3.10 [basic.lval]) or
to a sub-object within that object.
</LI>
<LI>
otherwise, the reference is bound in one of the
following ways (the choice is implementation-defined):
<UL>
<LI>
[... continues as before - the original wording applies
unchanged to longer-lived references]
</LI>
</UL>
</LI>
</UL>
</LI>
</UL>

<P><B>---- rationale ----</B></P>

<OL>
<LI>
The intention of the current wording is to provide the
   implementation freedom to construct an rvalue of class
   type at an arbitrary location and copy it zero <U>or more</U>
   times before binding any reference to it.
</LI>
<LI>
The standard allows code to call a member function on an
   rvalue of class type (in 5.2.5 [expr.ref], I guess).
This means that
   the implementation can be forced to bind the reference
   directly, with no freedom to create any temporary
   copies. e.g.
<PRE>
   class nc {
     nc (nc const &amp;);  // private, nowhere defined
   public:
     nc ();
     nc const &amp;by_ref () const { return *this; }
   };

   void f () {
     void g (nc const &amp;);

     g (nc());          // Ill-formed
     g (nc().by_ref()); // Ok - binds directly to rvalue
   }
</PRE>

   Forcing a direct binding in this way is possible wherever
   the lifetime of the reference does not extend beyond the
   containing full expression, since the reference returned
   by the member function remains valid for this long.
</LI>
<LI>
As demonstrated above, existing implementations must
   already be capable of constructing an rvalue of class
   type in the "right" place the first time. Some compilers
   already silently allow the direct binding of references
   to non-copyable rvalues.
</LI>
<LI>
The change will not break any portable user code. It
   would break any platform-specific user code that relies
   on copies being performed by the particular
   implementation.
</LI>
</OL>

<P><B>---- background ----</B></P>

<P>The proposal is based on a recent discussion in this
group. I originally wanted to leave the implementation free
to copy the rvalue if there was a callable copy constructor,
and only <B>have</B> to bind directly if none was callable.
Unfortunately, a traditional compiler can't always tell
whether a function is callable or not, e.g. if the copy
constructor is declared but not defined. Rani pointed this
out in an example, and suggested that maybe trivial copy
constructors should still be allowed (by extension, maybe
wherever the compiler can determine callability). I've gone
with this version because it's simpler, and I also figure
the "as if" rule gives the compiler some freedom with POD
types anyway.</P>

<P><B>Notes from April 2003 meeting:</B></P>

<P>We agreed generally with the proposal.  We were unsure about the
need for the restriction regarding long-lived references.
We will check with the proposer about that.</P>

<P>Jason Merrill points out that the test case in
<A HREF="
     cwg_defects.html#86">issue 86</A> may be a case where we
do not want to require direct binding.</P>

<P><B>Further information from Rani Sharoni (April 2003):</B></P>

<P>I wasn't aware about the latest suggestion of Raoul as it appears in
core issue 391. In our discussions we tried to formulate a different
proposal.</P>
<P>The rational, as we understood, behind the implementation freedom to
make an extra copying (8.5.3/5/2/12) of the rvalue is to allow return
values in registers which on some architectures are not addressable.
The example that Raoul and I presented shows that this implementation
freedom is not always possible since we can "force" the rvalue to be
addressable using additional member function (by_ref). The example
only works for short lived rvalues and this is probably why Raoul
narrow the suggestion.</P>
<P>I had different rational which was related to the implementation of
conditional operator in VC. It seems that when conditional operator is
involved VC does use an extra copying when the lifetime of the
temporary is extended:</P>
<PRE>
  struct A { /* ctor with side effect */};

  void f(A&amp; x) {
    A const&amp; r = cond ? A(1) : x; // VC actually make an extra copy of
                                  // the rvalue A(1)
  }
</PRE>
<P>I don't know what the consideration behind the VC implementation was
(I saw open bug on this issue) but it convinced me to narrow the
suggestion.</P>

<P>IMHO such limitation seems to be too strict because it might limit the
optimizer since returning class rvalues in registers might be useful
(although I'm not aware about any implementation that actually does
it). My suggestion was to forbid the extra copying if the ctor is not
viable (e.g. A::A(A&amp;) ). In this case the implementation "freedom"
doesn't exist (since the code might not compile) and only limits the
programmer freedom (e.g. Move Constructors -
<A HREF="http://www.cuj.com/experts/2102/alexandr.htm">
http://www.cuj.com/experts/2102/alexandr.htm</A>).</P>

<P><A HREF="
     cwg_defects.html#291">Core issue 291</A> is strongly related to
the above issue and I personally
prefer to see it resolved first. It seems that VC already supports the
resolution I prefer.</P>

<P><B>Notes from October 2003 meeting:</B></P>

<P>We ended up feeling that this is just one of a number of cases
of optimizations that are widely done by compilers
and allowed but not required by the standard.  We don't see any
strong reason to require compilers to do this particular
optimization.</P>

<P><B>Notes from the March 2004 meeting:</B></P>

<P>After discussing <A HREF="
     cwg_defects.html#450">issue 450</A>, we
found ourselves reconsidering this, and we are now inclined to
make a change to require the direct binding in all cases,
with no restriction on long-lived references.  Note that such
a change would eliminate the need for a change for
<A HREF="
     cwg_defects.html#291">issue 291</A>.</P>

<P><B>Proposed resolution (October, 2004):</B></P>

<P>Change 8.5.3 [dcl.init.ref] paragraph 5 bullet 2
sub-bullet 1 as follows:</P>

<BLOCKQUOTE>
If the initializer expression is an rvalue, with <TT>T2</TT> a class type,
and "<I>cv1</I> <TT>T1</TT>" is reference-compatible with
"<I>cv2</I> <TT>T2</TT>", the reference is bound <SPAN style="font-weight:bold;background-color:#A0FFA0">to the
object represented by the rvalue (see 3.10 [basic.lval]) or to a sub-object within that object.</SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">in one of the following ways (the choice is
implementation-defined):
<UL>

<LI>
The reference is bound to the object represented by the
rvalue (see 3.10 [basic.lval]) or to a sub-object
within that object.  </LI>

<LI>
A temporary of type "<I>cv1</I> <TT>T2</TT>" [sic] is created, and a
constructor is called to copy the entire rvalue object into the
temporary. The reference is bound to the temporary or to a
sub-object within the temporary.
</LI>

</UL>

The constructor that would be used to make the copy shall be
callable whether or not the copy is actually done.</SPAN>
[<I>Example:</I>

<PRE>
  struct A { };
  struct B : public A { } b;
  extern B f();
  const A&amp; rca = f ();  // <SPAN style="font-weight:bold;background-color:#A0FFA0">Bound</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">Either bound</SPAN> to the A sub-object of the B rvalue<SPAN style="text-decoration:line-through;background-color:#FFA0A0">,
                        // or the entire B object is copied and the reference
                        // is bound to the A sub-object of the copy</SPAN>
</PRE>
&#8212;<I>end example</I>]
</BLOCKQUOTE>

<P><I>[This resolution also resolves <A HREF="
     cwg_defects.html#291">issue 291</A>.]</I></P>

<BR><BR><HR><A NAME="450"></A><H4>450.
  
Binding a reference to const to a cv-qualified array rvalue
</H4><B>Section: </B>8.5.3&#160; [dcl.init.ref]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>16 Jan 2004<BR>


<P>[Voted into WP at October 2005 meeting.]</P>

<P>It's unclear whether the following is valid:</P>
<PRE>
const int N = 10;
const int M = 20;
typedef int T;
void f(T const (&amp;x)[N][M]){}

struct X {
	int i[10][20];
};

X g();

int main()
{
	f(g().i);
}
</PRE>
<P>When you run this through 8.5.3 [dcl.init.ref], you sort of end up
falling off the end of the standard's description of reference
binding.  The standard says in the final bullet of paragraph 5
that an array temporary should be created and copy-initialized
from the rvalue array, which seems implausible.</P>

<P> I'm not sure what the right answer is.  I think I'd be happy with
allowing the binding in this case.  We would have to introduce
a special case like the one for class rvalues.</P>

<P><B>Notes from the March 2004 meeting:</B></P>

<P>g++ and EDG give an error.  Microsoft (8.0 beta) and Sun accept
the example.  Our preference is to allow the direct binding (no copy).
See the similar issue with class rvalues in
<A HREF="
     cwg_defects.html#391">issue 391</A>.</P>

<P><B>Proposed resolution (October, 2004):</B></P>

<OL>

<LI><P>Insert a new bullet in 8.5.3 [dcl.init.ref]
paragraph 5 bullet 2 before sub-bullet 2 (which begins,
&#8220;Otherwise, a temporary of type &#8216;<I>cv1</I>
<TT>T1</TT>&#8217; is created...&#8221;):</P>

<BLOCKQUOTE>

If the initializer expression is an rvalue, with <TT>T2</TT> an
array type, and &#8220;<I>cv1</I> <TT>T1</TT>&#8221; is
reference-compatible with &#8220;<I>cv2</I> <TT>T2</TT>&#8221;,
the reference is bound to the object represented by the rvalue
(see 3.10 [basic.lval]).

</BLOCKQUOTE>

</LI>

<LI><P>Change 3.10 [basic.lval] paragraph 2 as
follows:</P>

<BLOCKQUOTE>

An lvalue refers to an object or function. Some rvalue
expressions &#8212; those of <SPAN style="font-weight:bold;background-color:#A0FFA0">(possibly cv-qualified)</SPAN> class
<SPAN style="font-weight:bold;background-color:#A0FFA0">or array type</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or cv-qualified class type</SPAN> &#8212;
also refer to objects.

</BLOCKQUOTE>

</LI>

</OL>

<BR><BR><HR><A NAME="175"></A><H4>175.
  
Class name injection and base name access
</H4><B>Section: </B>9&#160; [class]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>21 February 1999<BR>



<P>[Moved to DR at 10/01 meeting.]</P>

<P>With class name injection, when a base class name is used in a derived
class, the name found is the injected name in the base class, not the
name of the class in the scope containing the base class.
Consequently, if the base class name is not accessible (e.g., because
is is in a private base class), the base class name cannot be used
unless a qualified name is used to name the class in the class or
namespace of which it is a member.</P>

<P>Without class name injection the following example is valid.  With
class name injection, <TT>A</TT> is inaccessible in class <TT>C</TT>.</P>

<PRE>
    class A { };
    class B: private A { };
    class C: public B {
        A* p;    // error: A inaccessible
    };
</PRE>

<P>At the least, the standard should be more explicit that this is, in
fact, ill-formed.</P>

<P>(See paper J16/99-0010 = WG21 N1187.)</P>

<P><B>Proposed resolution (04/01):</B></P>

<P>Add to the end of 11.1 [class.access.spec] paragraph 3:</P>

<BLOCKQUOTE>

<P>[<I>Note:</I> In a derived class, the lookup of a base class name
will find the injected-class-name instead of the name of the base
class in the scope in which it was declared.  The
injected-class-name might be less accessible than the name of the
base class in the scope in which it was declared.] [<I>Example:</I></P>

<PRE>
    class A { };
    class B : private A { };
    class C : public B {
        A* p;    // error: injected-class-name A is inaccessible
        ::A* q;  // OK
    };
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>
<BR><BR><HR><A NAME="273"></A><H4>273.
  
POD classes and <TT>operator&amp;()</TT>
</H4><B>Section: </B>9&#160; [class]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Andrei Iltchenko
 &#160;&#160;&#160;

 <B>Date: </B>10 Mar 2001<BR>


<P>[Moved to DR at October 2002 meeting.]</P>

<P>I think that the definition of a POD class in the current version
of the Standard is overly permissive in that it allows for POD classes
for which a user-defined operator function <TT>operator&amp;</TT> may
be defined. Given that the idea behind POD classes was to achieve
compatibility with C structs and unions, this makes 'Plain old'
structs and unions behave not quite as one would expect them to.</P>

<P>In the C language, if <TT>x</TT> and <TT>y</TT> are variables of
struct or union type <TT>S</TT> that has a member <TT>m</TT>, the
following expression are allowed: <TT>&amp;x</TT>, <TT>x.m</TT>, <TT>x
= y</TT>.  While the C++ standard guarantees that if <TT>x</TT> and
<TT>y</TT> are objects of a POD class type <TT>S</TT>, the expressions
<TT>x.m</TT>, <TT>x = y</TT> will have the same effect as they would
in C, it is still possible for the expression <TT>&amp;x</TT> to be
interpreted differently, subject to the programmer supplying an
appropriate version of a user-defined operator function
<TT>operator&amp;</TT> either as a member function or as a non-member
function.</P>

<P>This may result in surprising effects. Consider:</P>

<PRE>
    // POD_bomb is a POD-struct. It has no non-static non-public data members,
    // no virtual functions, no base classes, no constructors, no user-defined
    // destructor, no user-defined copy assignment operator, no non-static data
    // members of type pointer to member, reference, non-POD-struct, or
    // non-POD-union.
    struct  POD_bomb  {
       int   m_value1;
       int   m_value2;
       int  operator&amp;()
       {   return  m_value1++;   }
       int  operator&amp;() const
       {   return  m_value1 + m_value2;   }
    };
</PRE>

<P>3.9 [basic.types] paragraph 2 states:</P>

<BLOCKQUOTE>

For any complete POD object type <TT>T</TT>, whether or not the object
holds a valid value of type <TT>T</TT>, the underlying bytes
(1.7 [intro.memory]) making up the object can be copied into
an array of <TT>char</TT> or <TT>unsigned char</TT> [<I>footnote</I>:
By using, for example, the library functions (17.6.1.2 [headers]) <TT>memcpy</TT> or <TT>memmove</TT>]. If the
content of the array of <TT>char</TT> or <TT>unsigned char</TT> is
copied back into the object, the object shall subsequently hold its
original value. [<I>Example</I>:

<PRE>
    #define N sizeof(T)
    char buf[N];
    T obj;   // obj initialized to its original value
    memcpy(buf, &amp;obj, N);
		// between these two calls to memcpy,
		// obj might be modified
    memcpy(&amp;obj, buf, N);
		// at this point, each subobject of obj of scalar type
		// holds its original value
</PRE>
&#8212;<I>end example</I>]
</BLOCKQUOTE>

<P>Now, supposing that the complete POD object type <TT>T</TT> in the
example above is <TT>POD_bomb</TT>, and we cannot any more count on
the assertions made in the comments to the example. Given a standard
conforming implementation, the code will not even compile. And I see
no legal way of copying the contents of an object of a complete object
type <TT>POD_bomb</TT> into an array of <TT>char</TT> or <TT>unsigned
char</TT> with <TT>memcpy</TT> or <TT>memmove</TT> without making use
of the unary <TT>&amp;</TT> operator. Except, of course, by means of
an ugly construct like:</P>

<PRE>
    struct  POD_without_ampersand  {
       POD_bomb   a_bomb;
    }  obj;
    #define N sizeof(POD_bomb)
    char buf[N];
    memcpy(buf, &amp;obj, N);
    memcpy(&amp;obj, buf, N);
</PRE>

<P>The fact that the definition of a POD class allows for POD classes
for which a user-defined <TT>operator&amp;</TT> is defined, may also
present major obstacles to implementers of the offsetof macro from
&lt;cstddef&gt;</P>

<P>18.2 [support.types] paragraph 5 says:</P>

<BLOCKQUOTE>

The macro <TT>offsetof</TT> accepts a restricted set of type arguments
in this International Standard. <TT>type</TT> shall be a POD structure
or a POD union (clause 9 [class]). The result of
applying the <TT>offsetof</TT> macro to a field that is a static data
member or a function is undefined."

</BLOCKQUOTE>

<P>Consider a well-formed C++ program below:</P>

<PRE>
    #include &lt;cstddef&gt;
    #include &lt;iostream&gt;


    struct  POD_bomb  {
       int   m_value1;
       int   m_value2;
       int  operator&amp;()
       {   return  m_value1++;   }
       int  operator&amp;() const
       {   return  m_value1 + m_value2;   }
    };


    // POD_struct is a yet another example of a POD-struct.
    struct  POD_struct  {
       POD_bomb   m_nonstatic_bomb1;
       POD_bomb   m_nonstatic_bomb2;
    };


    int  main()
    {

       std::cout &lt;&lt; "offset of m_nonstatic_bomb2: " &lt;&lt; offsetof(POD_struct,
           m_nonstatic_bomb2) &lt;&lt; '\n';
       return  0;

    }
</PRE>

<P>See Jens Maurer's paper 01-0038=N1324 for an analysis of this issue.</P>

<P><B>Notes from 10/01 meeting:</B></P>

<P>A consensus was forming around the idea of disallowing
<TT>operator&amp;</TT> in POD classes when it was noticed that it is
permitted to declare global-scope <TT>operator&amp;</TT> functions,
which cause the same problems.  After more discussion, it was
decided that such functions should not be prohibited in POD classes,
and implementors should simply be required to "get the right answer"
in constructs such as <TT>offsetof</TT> and <TT>va_start</TT> that
are conventionally implemented using macros that use the "<TT>&amp;</TT>"
operator.  It was noted that one can cast the original operand to
<TT>char &amp;</TT> to de-type it, after which one can use the
built-in "<TT>&amp;</TT>" safely.</P>

<P><B>Proposed resolution:</B></P>

<UL>
<LI>Add a footnote in 18.2 [support.types] paragraph 5:
<BLOCKQUOTE>
[<EM>Footnote:</EM> Note that <TT>offsetof</TT> is required to
work as specified even if unary <TT>operator&amp;</TT> is
overloaded for any of the types involved.]
</BLOCKQUOTE>
</LI>
<LI>Add a footnote in 18.10 [support.runtime] paragraph 3:
<BLOCKQUOTE>
[<EM>Footnote:</EM> Note that <TT>va_start</TT> is required to
work as specified even if unary <TT>operator&amp;</TT> is
overloaded for the type of <TT>parmN</TT>.]
</BLOCKQUOTE>
</LI>
</UL>

<BR><BR><HR><A NAME="284"></A><H4>284.
  
<I>qualified-id</I>s in class declarations
</H4><B>Section: </B>9&#160; [class]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>01 May 2001<BR>


<P>[Moved to DR at October 2002 meeting.]</P>

<P>Although 8.3 [dcl.meaning] requires that a declaration of
a <I>qualified-id</I> refer to a member of the specified namespace or
class and that the member not have been introduced by a
<I>using-declaration</I>, it applies only to names declared in a
declarator.  It is not clear whether there is existing wording
enforcing the same restriction for <I>qualified-id</I>s in
<I>class-specifier</I>s and <I>elaborated-type-specifier</I>s or
whether additional wording is required.  Once such wording is
found/created, the proposed resolution of
<A HREF="
     cwg_defects.html#275">issue 275</A> must be modified accordingly.</P>

<P><B>Notes from 10/01 meeting:</B></P>

<P>The sentiment was that this should be required on class definitions, but
not on elaborated type specifiers in general (which are references, not
declarations).  We should also make sure we consider explicit instantiations,
explicit specializations, and friend declarations.</P>


<P><B>Proposed resolution (10/01):</B></P>

<P>Add after the end of 9.1 [class.name] paragraph 3:</P>
<BLOCKQUOTE>
When a <I>nested-name-specifier</I> is specified in a
<I>class-head</I> or in an
<I>elaborated-type-specifier</I>, the resulting qualified name
shall refer to a previously declared member of the class or namespace to
which the <I>nested-name-specifier</I> refers, and
the member shall not have been introduced by a
using-declaration in the scope of the class or namespace
nominated by the <I>nested-name-specifier</I>.
</BLOCKQUOTE>

<BR><BR><HR><A NAME="327"></A><H4>327.
  
Use of "structure" without definition
</H4><B>Section: </B>9&#160; [class]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>James Kanze
 &#160;&#160;&#160;

 <B>Date: </B>9 Dec 2001<BR>


<P>[Voted into WP at April, 2007 meeting.]</P>


<P>In 9 [class] paragraph 4, the first sentence says
"A structure is a class
definition defined with the <I>class-key</I> <TT>struct</TT>".
As far as I know,
there is no such thing as a structure in C++; it certainly isn't
listed as one of the possible compound types in 3.9.2 [basic.compound].
And defining structures opens the question of whether a forward
declaration is a structure or not.  The parallel here with union
(which follows immediately) suggests that structures and classes are
really different things, since the same wording is used, and classes
and unions do have some real differences, which manifest themselves
outside of the definition.  It also suggests that since one can't
forward declare union with class and vice versa, the same should
hold for struct and class -- I believe that the intent was that one
could use struct and class interchangeably in forward declaration.</P>

<P><B>Suggested resolution:</B></P>

<P>I suggest something like the following:</P>
<BLOCKQUOTE>
If a class is defined with the <I>class-key</I> <TT>class</TT>, its members and
base classes are private by default.  If a class is defined with
the <I>class-key</I> <TT>struct</TT>,
its members and base classes are public by
default.  If a class is defined with the <I>class-key</I> <TT>union</TT>, its
members are public by default, and it holds only one data member
at a time.  Such classes are called unions, and obey a number of
additional restrictions, see 9.5 [class.union].
</BLOCKQUOTE>

<P><B>Proposed resolution (April, 2006):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#538">issue 538</A>.</P>

<BR><BR><HR><A NAME="379"></A><H4>379.
  
Change "class declaration" to "class definition"
</H4><B>Section: </B>9&#160; [class]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jens Maurer
 &#160;&#160;&#160;

 <B>Date: </B>21 Oct 2002<BR>


<P>[Voted into WP at March 2004 meeting.]</P>

<P>The ARM used the term "class declaration" to refer to what
would usually be termed the definition of the class.  The standard
now often uses "class definition", but there are some surviving uses
of "class declaration" with the old meaning.  They should be found
and changed.</P>

<P><B>Proposed resolution (April 2003):</B></P>

<P>
Replace in 3.1 [basic.def] paragraph 2</P>

<BLOCKQUOTE>
A declaration is a <I>definition</I> unless it declares a function
without specifying the function's body
(8.4 [dcl.fct.def]), it contains the
<TT>extern</TT> specifier (7.1.1 [dcl.stc]) or
a <I>linkage-specification</I>
[Footnote: Appearing inside the braced-enclosed
<I>declaration-seq</I> in a <I>linkage-specification</I> does not
affect whether a declaration is a definition.  --- end
footnote]
(7.5 [dcl.link]) and neither an
<I>initializer</I> nor a <I>function-body</I>, it declares a static
data member in a class <SPAN style="text-decoration:line-through;background-color:#FFA0A0">declaration</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">definition</SPAN>
(9.4 [class.static]), it is a class name
declaration (9.1 [class.name]), or it is
a <TT>typedef</TT> declaration
(7.1.3 [dcl.typedef]), a
<I>using-declaration</I>
(7.3.3 [namespace.udecl]), or a
<I>using-directive</I>
(7.3.4 [namespace.udir]).
</BLOCKQUOTE>

<P>
Replace in 7.1.2 [dcl.fct.spec] paragraphs 5 and 6</P>

<BLOCKQUOTE>
<P>The <TT>virtual</TT> specifier shall only be used in declarations of
nonstatic class member functions that appear within a
<I>member-specification</I> of a class <SPAN style="text-decoration:line-through;background-color:#FFA0A0">declaration</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">definition</SPAN>; see
10.3 [class.virtual].</P>
<P>
The <TT>explicit</TT> specifier shall be used only in declarations of
constructors within a class <SPAN style="text-decoration:line-through;background-color:#FFA0A0">declaration</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">definition</SPAN>; see
12.3.1 [class.conv.ctor].</P>
</BLOCKQUOTE>

<P>
Replace in 7.1.3 [dcl.typedef] paragraph 4</P>

<BLOCKQUOTE>
A
<I>typedef-name</I>
that names a class is a
<I>class-name</I>
(9.1 [class.name]).
If a <I>typedef-name</I> is used following the <I>class-key</I>
in an <I>elaborated-type-specifier</I>
(7.1.6.3 [dcl.type.elab]) or in the
<I>class-head</I>
of a class <SPAN style="text-decoration:line-through;background-color:#FFA0A0">declaration</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">definition</SPAN>
(9 [class]),
or is used as the <I>identifier</I> in the declarator for a
constructor or destructor declaration
(12.1 [class.ctor],
12.4 [class.dtor]), the program is ill-formed.
</BLOCKQUOTE>

<P>
Replace in 7.3.1.2 [namespace.memdef] paragraph 3</P>

<BLOCKQUOTE>
The name of the friend is not found by simple name lookup until a
matching declaration is provided in that namespace scope (either
before or after the class <SPAN style="text-decoration:line-through;background-color:#FFA0A0">declaration</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">definition</SPAN> granting friendship).
</BLOCKQUOTE>

<P>
Replace in 8.3.2 [dcl.ref] paragraph 4</P>

<BLOCKQUOTE>
There shall be no references to references, no arrays of references,
and no pointers to references.  The declaration of a reference shall
contain an <I>initializer</I>
(8.5.3 [dcl.init.ref]) except when
the declaration contains an explicit <TT>extern</TT> specifier
(7.1.1 [dcl.stc]), is a class member
(9.2 [class.mem]) declaration within a
class <SPAN style="text-decoration:line-through;background-color:#FFA0A0">declaration</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">definition</SPAN>, or is the
declaration of a parameter or a return type
(8.3.5 [dcl.fct]); see
3.1 [basic.def].
</BLOCKQUOTE>

<P>
Replace in 8.5.3 [dcl.init.ref] paragraph 3</P>
<BLOCKQUOTE>
The initializer can be omitted for a reference only in a parameter
declaration (8.3.5 [dcl.fct]), in the
declaration of a function return type, in the declaration of a class
member within its class <SPAN style="text-decoration:line-through;background-color:#FFA0A0">declaration</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">definition</SPAN>
(9.2 [class.mem]), and where the
<TT>extern</TT> specifier is explicitly used.
</BLOCKQUOTE>

<P>
Replace in 9.1 [class.name] paragraph 2</P>
<BLOCKQUOTE>
A class <SPAN style="text-decoration:line-through;background-color:#FFA0A0">definition</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">declaration</SPAN> introduces the
class name into the scope where it is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">defined</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">declared</SPAN> and hides any class, object, function, or other
declaration of that name in an enclosing scope
(3.3 [basic.scope]).  If a class name
is declared in a scope where an object, function, or enumerator of the
same name is also declared, then when both declarations are in scope,
the class can be referred to only using an
<I>elaborated-type-specifier</I>
(3.4.4 [basic.lookup.elab]).
</BLOCKQUOTE>

<P>
Replace in 9.4 [class.static] paragraph 4</P>
<BLOCKQUOTE>
Static members obey the usual class member access rules (clause
11 [class.access]).  When used
in the declaration of a class member, the <TT>static</TT> specifier
shall only be used in the member declarations that appear within the
<I>member-specification</I> of the class <SPAN style="text-decoration:line-through;background-color:#FFA0A0">declaration</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">definition</SPAN>.
</BLOCKQUOTE>

<P>Replace in 9.7 [class.nest] paragraph 1</P>
<BLOCKQUOTE>
A class can be <SPAN style="text-decoration:line-through;background-color:#FFA0A0">defined</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">declared</SPAN> within another
class.  A class <SPAN style="text-decoration:line-through;background-color:#FFA0A0">defined</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">declared</SPAN> within
another is called a <I>nested</I> class.  The name of a nested class
is local to its enclosing class.  The nested class is in the scope of
its enclosing class.  Except by using explicit pointers, references,
and object names, declarations in a nested class can use only type
names, static members, and enumerators from the enclosing class.
</BLOCKQUOTE>

<P>
Replace in 9.8 [class.local] paragraph 1</P>
<BLOCKQUOTE>
A class can be <SPAN style="text-decoration:line-through;background-color:#FFA0A0">defined</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">declared</SPAN> within a
function definition; such a class is called a <I>local</I> class.  The
name of a local class is local to its enclosing scope.  The local
class is in the scope of the enclosing scope, and has the same access
to names outside the function as does the enclosing function.
Declarations in a local class can use only type names, static
variables, <TT>extern</TT> variables and functions, and enumerators
from the enclosing scope.
</BLOCKQUOTE>

<P>
Replace in 10 [class.derived] paragraph 1</P>
<BLOCKQUOTE>
... The <I>class-name</I> in a <I>base-specifier</I> shall not be an
incompletely defined class (clause 9 [class]);
this class is called a
<I>direct</I> <I>base</I> <I>class</I> for the class being
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">declared</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">defined</SPAN>.  During the lookup for a
base class name, non-type names are ignored
(3.3.10 [basic.scope.hiding]).  
If the name found is not a <I>class-name</I>, the program is ill-formed.
A class <TT>B</TT> is a base class of a class <TT>D</TT> if it is a
direct base class of <TT>D</TT> or a direct base class of one of
<TT>D</TT>'s base classes.  A class is an <I>indirect</I> base class
of another if it is a base class but not a direct base class.  A class
is said to be (directly or indirectly) <I>derived</I> from its (direct
or indirect) base classes.  [<I>Note:</I> See clause
11 [class.access]
for the meaning of <I>access-specifier</I>.]  Unless
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">redefined</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">redeclared</SPAN> in the
derived class, members of a base class are also considered to be
members of the derived class.  The base class members are said to be
<I>inherited</I> by the derived class.  Inherited members can be
referred to in expressions in the same manner as other members of the
derived class, unless their names are hidden or ambiguous
(10.2 [class.member.lookup]).
[<I>Note:</I> the scope resolution operator <TT>::</TT>
(5.1.1 [expr.prim.general])
can be used to refer to a direct or indirect base member explicitly.
This allows access to a name that has been <SPAN style="text-decoration:line-through;background-color:#FFA0A0">redefined</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">redeclared</SPAN> in the derived class.  A derived class can itself
serve as a base class subject to access control; see
11.2 [class.access.base].  
A pointer to a derived class can be implicitly converted to a pointer
to an accessible unambiguous base class
(4.10 [conv.ptr]).
An lvalue of a derived class type can be bound to a reference to an
accessible unambiguous base class
(8.5.3 [dcl.init.ref]).]
</BLOCKQUOTE>

<P>
Replace in 10.1 [class.mi] paragraph 5</P>
<BLOCKQUOTE>
For another example,
<BLOCKQUOTE><TT><PRE>
class V { /* ... */ };
class A : virtual public V { /* ... */ };
class B : virtual public V { /* ... */ };
class C : public A, public B { /* ... */ };
</PRE></TT></BLOCKQUOTE>
for an object <TT>c</TT> of class type <TT>C</TT>, a single subobject
of type <TT>V</TT> is shared by every base subobject of <TT>c</TT>
that <SPAN style="text-decoration:line-through;background-color:#FFA0A0">is declared to have</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">has</SPAN> a
<TT>virtual</TT> base class of type <TT>V</TT>.
</BLOCKQUOTE>

<P>
Replace in the example in 10.2 [class.member.lookup]
paragraph 6 (the whole paragraph was turned into a note by the
resolution of <A HREF="
     cwg_defects.html#39">core issue 39</A>)</P>
<BLOCKQUOTE>
The names <SPAN style="text-decoration:line-through;background-color:#FFA0A0">defined</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">declared</SPAN> in <TT>V</TT> and
the left hand instance of <TT>W</TT> are hidden by those in
<TT>B</TT>, but the names <SPAN style="text-decoration:line-through;background-color:#FFA0A0">defined</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">declared</SPAN> in
the right hand instance of <TT>W</TT> are not hidden at all.
</BLOCKQUOTE>

<P>
Replace in 10.4 [class.abstract] paragraph 2</P>
<BLOCKQUOTE>
... A virtual function is specified <I>pure</I> by using a
<I>pure-specifier</I> (9.2 [class.mem])
in the function declaration in the class <SPAN style="text-decoration:line-through;background-color:#FFA0A0">declaration</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">definition</SPAN>. ...
</BLOCKQUOTE>

<P>
Replace in the footnote at the end of 11.2 [class.access.base]
paragraph 1</P>
<BLOCKQUOTE>
[Footnote: As specified previously in clause
11 [class.access], private members of
a base class remain inaccessible even to derived classes unless
<TT>friend</TT> declarations within the base class
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">declaration</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">definition</SPAN> are used to grant access
explicitly.]
</BLOCKQUOTE>

<P>
Replace in _N3225_.11.3 [class.access.dcl] paragraph 1</P>
<BLOCKQUOTE>
The access of a member of a base class can be changed in the derived
class by mentioning its <I>qualified-id</I> in the derived class
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">declaration</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">definition</SPAN>.  Such mention is
called an <I>access</I> <I>declaration</I>. ...
</BLOCKQUOTE>

<P>
Replace in the example in 13.4 [over.over] paragraph 5</P>
<BLOCKQUOTE>
The initialization of <TT>pfe</TT> is ill-formed because no
<TT>f()</TT> with type <TT>int(...)</TT> has been
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">defined</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">declared</SPAN>, and not because of any
ambiguity.
</BLOCKQUOTE>

<P>
Replace in C.1.6 [diff.dcl] paragraph 1</P>
<BLOCKQUOTE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">Rationale:</SPAN> Storage class specifiers don't have any meaning when
associated with a type.  In C++, class members can be
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">defined</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">declared</SPAN> with the <TT>static</TT>
storage class specifier.  Allowing storage class specifiers on type
declarations could render the code confusing for users.
</BLOCKQUOTE>

<P>
Replace in C.1.8 [diff.class] paragraph 3</P>
<BLOCKQUOTE>
In C++, a typedef name may not be <SPAN style="text-decoration:line-through;background-color:#FFA0A0">redefined</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">redeclared</SPAN> in a class
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">declaration</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">definition</SPAN> after being used in <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the
declaration</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">that definition</SPAN>
</BLOCKQUOTE>

<I>Drafting notes:</I>
<P>
The resolution of <A HREF="
     cwg_defects.html#45">core issue 45</A> (DR)
deletes 11.7 [class.access.nest] paragraph 2.</P>

<P>
The following occurrences of "class declaration" are not changed:</P>
<UL>
<LI>5.3.4 [expr.new] paragraph 4
</LI>

<LI>7.1.3 [dcl.typedef] paragraph 1
</LI>

<LI>9.1 [class.name] paragraphs 3 and 4
</LI>

<LI>11.3 [class.friend] paragraph 9
</LI>

<LI>C.1.8 [diff.class] paragraph 1
</LI>

</UL>

<BR><BR><HR><A NAME="383"></A><H4>383.
  
Is a class with a declared but not defined destructor a POD?
</H4><B>Section: </B>9&#160; [class]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Gennaro Prota
 &#160;&#160;&#160;

 <B>Date: </B>18 Sep 2002<BR>


<P>[Voted into WP at March 2004 meeting.]</P>

<P>The standard (9 [class] par. 4) says that
"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-defined copy assignment operator and no user-defined destructor."</P>

<P>Note that it says 'user-defined', not 'user-declared'. Is it the
intent that if e.g. a copy assignment operator is declared but not
defined, this does not (per se) prevent the class to be a POD-struct?</P>

<P><B>Proposed resolution (April 2003):</B></P>

<P>
Replace in 9 [class] paragraph 4</P>

<BLOCKQUOTE>
A <I>POD-struct</I> 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-<SPAN style="text-decoration:line-through;background-color:#FFA0A0">defined</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">declared</SPAN>
copy assignment operator and no user-<SPAN style="text-decoration:line-through;background-color:#FFA0A0">defined</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">declared</SPAN> destructor.  Similarly, a <I>POD-union</I> 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-<SPAN style="text-decoration:line-through;background-color:#FFA0A0">defined</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">declared</SPAN> copy
assignment operator and no user-<SPAN style="text-decoration:line-through;background-color:#FFA0A0">defined</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">declared</SPAN> destructor.
</BLOCKQUOTE>

<P><I>Drafting note: The changes are shown relative to TC1, incorporating
the changes from the resolution of
<A HREF="
     cwg_defects.html#148">core issue 148</A>.</I></P>

<BR><BR><HR><A NAME="413"></A><H4>413.
  
Definition of "empty class"
</H4><B>Section: </B>9&#160; [class]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Pete Becker
 &#160;&#160;&#160;

 <B>Date: </B>30 Apr 2003<BR>


<P>[Voted into WP at April, 2007 meeting.]</P>



<P>The proposal says that value is true if "T is an empty class (10)".
Clause 10 doesn't define an empty class, although it has a note that
says a base class may "be of zero size (clause 9)" 9/3 says "Complete
objects and member subobjects of class type shall have nonzero size."
This has a footnote, which says "Base class subobjects are not so
constrained."</P>

<P>The standard uses the term "empty class" in two places
(8.5.1 [dcl.init.aggr]), but neither of
those places defines it. It's also listed in the index, which refers to
the page that opens clause 9, i.e. the nonzero size stuff cited above.</P>

<P>So, what's the definition of "empty class" that determines whether the
predicate is_empty is true?</P>

<P>The one place where it's used is
8.5.1 [dcl.init.aggr] paragraph 8, which says (roughly paraphrased) 
that an aggregate initializer for an empty class must be "{}", and when 
such an initializer is used for an aggregate that is not an empty class the 
members are default-initialized. In this context it's pretty clear what's 
meant. In the type traits proposal it's not as clear, and it was probably 
intended to have a different meaning. The boost implementation, after it 
eliminates non-class types, determines whether the trait is true by 
comparing the size of a class derived from T to the size of an 
otherwise-identical class that is not derived from T.</P>

<P><U>Howard Hinnant:</U>
<TT>is_empty</TT> was created to find out whether a type could be derived from 
and have the empty base class optimization successfully applied.  It 
was created in part to support <TT>compressed_pair</TT> which attempts to 
optimize away the space for one of its members in an attempt to reduce 
spatial overhead.  An example use is:</P>
<PRE>
  template &lt;class T, class Compare = std::less&lt;T&gt; &gt;
  class SortedVec
  {
  public:
  ...
  private:
    T* data_;
    compressed_pair&lt;Compare, size_type&gt; comp_;

    Compare&amp;       comp()       {return comp_.first();}
    const Compare&amp; comp() const {return comp_.first();}
    size_type&amp;     sz()         {return comp_.second();}
    size_type      sz() const   {return comp_.second();}
  };
</PRE>
<P>Here the compare function is optimized away via the empty base 
optimization if Compare turns out to be an "empty" class.  If Compare 
turns out to be a non-empty class, or a function pointer, the space is 
not optimized away.  <TT>is_empty</TT> is key to making this work.</P>

<P>This work built on Nathan's article:
<A HREF="http://www.cantrip.org/emptyopt.html">
http://www.cantrip.org/emptyopt.html</A>.</P>

<P><U>Clark Nelson:</U>
I've been looking at issue 413, and I've reached the conclusion that
there are two different kinds of empty class. A class containing only
one or more anonymous bit-field members is empty for purposes of
aggregate initialization, but not (necessarily) empty for purposes of
empty base-class optimization.</P>

<P>Of course we need to add a definition of emptiness for purposes of
aggregate initialization. Beyond that, there are a couple of questions:</P>
<OL>
<LI>
Should the definition of emptiness used by the is_empty predicate be
defined in a language clause or a library clause?
</LI>
<LI>
Do we need to open a new core issue pointing out the fact that the
section on aggregate initialization does not currently say that unnamed
bit-fields are skipped?
</LI>
</OL>

<P><B>Notes from the October, 2005 meeting:</B></P>

<P>There are only two places in the Standard where the phrase
&#8220;empty class&#8221; appears, both in 8.5.1 [dcl.init.aggr] paragraph 8.  Because it is not clear whether the
definition of &#8220;empty for initialization purposes&#8221; is
suitable for use in defining the <TT>is_empty</TT> predicate, it would
be better just to avoid using the phrase in the language clauses.  The
requirements of 8.5.1 [dcl.init.aggr] paragraph 8 appear to be
redundant; paragraph 6 says that an <I>initializer-list</I> must have
no more initializers than the number of elements to initialize, so an
empty class already requires an empty <I>initializer-list</I>, and
using an empty <I>initializer-list</I> with a non-empty class is
covered adequately by paragraph 7's description of the handling of an
<I>initializer-list</I> with fewer <I>initializer</I>s than the
number of members to initialize.</P>

<P><B>Proposed resolution (October, 2005):</B></P>

<OL>

<LI><P>Change <xection_ref ref="8.5.1">8.5.1 [dcl.init.aggr]</xection_ref> paragraph 5 by inserting
the indicated text:</P></LI>

<BLOCKQUOTE>

<P>Static data members <SPAN style="font-weight:bold;background-color:#A0FFA0">and anonymous bit fields</SPAN> are not
considered members of the class for purposes of aggregate
initialization. [<I>Example:</I></P>

<PRE>
    struct A {
        int i;
        static int s;
        int j;<SPAN style="font-weight:bold;background-color:#A0FFA0">
        int :17;
        int k;</SPAN>
    } a = { 1 , 2<SPAN style="font-weight:bold;background-color:#A0FFA0"> , 3</SPAN> };
</PRE>

<P>Here, the second initializer 2 initializes <TT>a.j</TT> and not the
static data member <TT>A::s</TT><SPAN style="font-weight:bold;background-color:#A0FFA0">, and the third initializer 3
initializes <TT>a.k</TT> and not the padding before it.</SPAN>
&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<LI><P>Delete 8.5.1 [dcl.init.aggr] paragraph 8:</P></LI>

<BLOCKQUOTE>

<P>An <I>initializer</I> for an aggregate member that is an empty
class shall have the form of an empty <I>initializer-list</I>
<TT>{}</TT>.  [<I>Example:</I></P>

<PRE>
    struct S { };
    struct A {
        S s;
        int i;
    } a = { { } , 3 };
</PRE>

<P>&#8212;<I>end example</I>] An empty initializer-list can be used to
initialize any aggregate. If the aggregate is not an empty class, then
each member of the aggregate shall be initialized with a value of the
form <TT>T()</TT> (5.2.3 [expr.type.conv]), where <TT>T</TT>
represents the type of the uninitialized member.</P>

</BLOCKQUOTE>

</OL>

<P><I>This resolution also resolves
<A HREF="
     cwg_defects.html#491">issue 491</A>.</I></P>

<P><B>Additional note (October, 2005):</B></P>

<P>Deleting 8.5.1 [dcl.init.aggr] paragraph 8 altogether may
not be a good idea.  It would appear that, in its absence, the
initializer elision rules of paragraph 11 would allow the initializer
for <TT>a</TT> in the preceding example to be written <TT>{ 3 }</TT>
(because the empty-class member <TT>s</TT> would consume no
<I>initializer</I>s from the list).</P>

<P><B>Proposed resolution (October, 2006):</B></P>

<P><I>(Drafting note: this resolution also cleans up incorrect
references to syntactic non-terminals in the nearby paragraphs.)</I></P>

<OL>

<LI><P>Change 8.5.1 [dcl.init.aggr] paragraph 4 as indicated:</P>

<BLOCKQUOTE>

An array of unknown size initialized with a brace-enclosed
<I>initializer-list</I> containing <TT>n</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>initializer</I>s</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>initializer-clause</I>s</SPAN>, where <TT>n</TT> shall be greater
than zero... An empty initializer list <TT>{}</TT> shall not be used as the
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">initializer</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>initializer-clause</I></SPAN> for an array of
unknown bound.

</BLOCKQUOTE>

</LI>

<LI><P>Change <xection_ref ref="8.5.1">8.5.1 [dcl.init.aggr]</xection_ref> paragraph 5 by inserting
the indicated text:</P>

<BLOCKQUOTE>

<P>Static data members <SPAN style="font-weight:bold;background-color:#A0FFA0">and anonymous bit fields</SPAN> are not
considered members of the class for purposes of aggregate
initialization. [<I>Example:</I></P>

<PRE>
    struct A {
        int i;
        static int s;
        int j;<SPAN style="font-weight:bold;background-color:#A0FFA0">
        int :17;
        int k;</SPAN>
    } a = { 1 , 2<SPAN style="font-weight:bold;background-color:#A0FFA0"> , 3</SPAN> };
</PRE>

<P>Here, the second initializer <TT>2</TT> initializes <TT>a.j</TT>
and not the static data member <TT>A::s</TT><SPAN style="font-weight:bold;background-color:#A0FFA0">, and the third
initializer <TT>3</TT> initializes <TT>a.k</TT> and not the anonymous
bit field before it.</SPAN> &#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

</LI>

<LI><P>Change 8.5.1 [dcl.init.aggr] paragraph 6 as indicated:</P>

<BLOCKQUOTE>

An <I>initializer-list</I> is ill-formed if the number of
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>initializer</I>s</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>initializer-clause</I>s</SPAN>
exceeds the number of members...

</BLOCKQUOTE>

</LI>

<LI><P>Change 8.5.1 [dcl.init.aggr] paragraph 7 as indicated:</P>

<BLOCKQUOTE>

If there are fewer <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>initializer</I>s</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>initializer-clause</I>s</SPAN> in the list than there are members...

</BLOCKQUOTE>

</LI>

<LI><P>Replace 8.5.1 [dcl.init.aggr] paragraph 8:</P>

<BLOCKQUOTE>

<P>An <I>initializer</I> for an aggregate member that is an empty
class shall have the form of an empty <I>initializer-list</I>
<TT>{}</TT>.  [<I>Example:</I></P>

<PRE>
    struct S { };
    struct A {
        S s;
        int i;
    } a = { { } , 3 };
</PRE>

<P>&#8212;<I>end example</I>] An empty initializer-list can be used to
initialize any aggregate. If the aggregate is not an empty class, then
each member of the aggregate shall be initialized with a value of the
form <TT>T()</TT> (5.2.3 [expr.type.conv]), where <TT>T</TT>
represents the type of the uninitialized member.</P>

</BLOCKQUOTE>

<P>with:</P>

<BLOCKQUOTE>

<P>If an aggregate class <TT>C</TT> contains a subaggregate
member <TT>m</TT> that has no members for purposes of aggregate
initialization, the <I>initializer-clause</I> for <TT>m</TT> shall not
be omitted from an <I>initializer-list</I> for an object of type
<TT>C</TT> unless the <I>initializer-clause</I>s for all members
of <TT>C</TT> following <TT>m</TT> are also omitted.  [<I>Example:</I></P>

<PRE>
    struct S { } s;
    struct A {
        S s1;
        int i1;
        S s2;
        int i2;
        S s3;
        int i3;
    } a = {
        { },   //<SPAN style="font-family:Times;font-style:italic"> Required initialization</SPAN>
        0,
        s,     //<SPAN style="font-family:Times;font-style:italic"> Required initialization</SPAN>
        0
    };         //<SPAN style="font-family:Times;font-style:italic"> Initialization not required for </SPAN>A::s3<SPAN style="font-family:Times;font-style:italic"> because </SPAN>A::i3<SPAN style="font-family:Times;font-style:italic"> is also not initialized</SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

</LI>

<LI><P>Change 8.5.1 [dcl.init.aggr] paragraph 10 as indicated:</P>

<BLOCKQUOTE>

When initializing a multi-dimensional array, the <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>initializer</I>s</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>initializer-clause</I>s</SPAN> initialize the elements...

</BLOCKQUOTE>

</LI>

<LI><P>Change 8.5.1 [dcl.init.aggr] paragraph 11 as indicated:</P>

<BLOCKQUOTE>

Braces can be elided in an <I>initializer-list</I> as follows. If the
<I>initializer-list</I> begins with a left brace, then the succeeding
comma-separated list of <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>initializer</I>s</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>initializer-clause</I>s</SPAN> initializes the members of a
subaggregate; it is erroneous for there to be more <SPAN style="text-decoration:line-through;background-color:#FFA0A0">initializers</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>initializer-clause</I>s</SPAN> than members. If, however,
the <I>initializer-list</I> for a subaggregate does not begin with a
left brace, then only enough <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>initializer</I>s</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>initializer-clause</I>s</SPAN> from the list are taken to
initialize the members of the subaggregate; any
remaining <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>initializer</I>s</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>initializer-clause</I>s</SPAN>
are left to initialize the next member of the aggregate of which the
current subaggregate is a member. [<I>Example:</I>...

</BLOCKQUOTE>

</LI>

<LI><P>Change 8.5.1 [dcl.init.aggr] paragraph 12 as indicated:</P>

<BLOCKQUOTE>

All implicit type conversions (clause 4 [conv]) are
considered when initializing the aggregate member with an <SPAN style="text-decoration:line-through;background-color:#FFA0A0">initializer
from an <I>initializer-list</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>assignment-expression</I></SPAN>. If
the <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>initializer</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>assignment-expression</I></SPAN> can
initialize a member, the member is initialized. Otherwise, if the
member is itself a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-empty</SPAN> subaggregate, brace elision is
assumed and the <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>initializer</I></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>assignment-expression</I></SPAN> is considered for the
initialization of the first member of the
subaggregate. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> As specified above, brace elision
cannot apply to subaggregates with no members for purposes of
aggregate initialization; an <I>initializer-clause</I> for the entire
subobject is required.  &#8212;<I>end note</I>]</SPAN>
[<I>Example:</I>...  Braces are elided around
the <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>initializer</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>initializer-clause</I></SPAN> for
<TT>b.a1.i</TT>...

</BLOCKQUOTE>

</LI>

<LI><P>Change 8.5.1 [dcl.init.aggr] paragraph 15 as indicated:</P>

<BLOCKQUOTE>

When a union is initialized with a brace-enclosed initializer, the
braces shall only contain an <SPAN style="text-decoration:line-through;background-color:#FFA0A0">initializer</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>initializer-clause</I></SPAN> for the first member of the
union...

</BLOCKQUOTE>

</LI>

<LI><P>Change 8.5.1 [dcl.init.aggr] paragraph 16 as indicated:</P>

<BLOCKQUOTE>

[<I>Note:</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">as</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">As</SPAN> described above, the braces around
the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">initializer</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>initializer-clause</I></SPAN> for a union
member can be omitted if the union is a member of another
aggregate. &#8212;<I>end note</I>]

</BLOCKQUOTE>

</LI>

</OL>

<P><I>(Note: this resolution also resolves
<A HREF="
     cwg_defects.html#491">issue 491</A>.)</I></P>

<BR><BR><HR><A NAME="538"></A><H4>538.
  
Definition and usage
of <I>structure</I>, <I>POD-struct</I>, <I>POD-union</I>,
and <I>POD class</I>
</H4><B>Section: </B>9&#160; [class]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>10 August 2005<BR>


<P>[Voted into WP at April, 2007 meeting.]</P>

<P>There are several problems with the terms defined in
9 [class] paragraph 4:</P>

<BLOCKQUOTE>

A <I>structure</I> is a class defined with
the <I>class-key</I> <TT>struct</TT>; its members and base classes
(clause 10 [class.derived]) are public by default (clause
11 [class.access]). A <I>union</I> is a class defined with the
<I>class-key</I> <TT>union</TT>; its members are public by default and
it holds only one data member at a time (9.5 [class.union]). [<I>Note:</I> aggregates of class type are described
in 8.5.1 [dcl.init.aggr]. &#8212;<I>end note</I>]
A <I>POD-struct</I> 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 <I>POD-union</I> 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 <I>POD class</I> is a class that is either a POD-struct
or a POD-union.

</BLOCKQUOTE>

<OL>

<LI><P>Although the term <I>structure</I> is defined here, it is
used only infrequently throughout the Standard, often apparently
inadvertently and consequently incorrectly:</P>

<UL>

<LI><P>5.2.5 [expr.ref] paragraph 4: the use is in a
note and is arguably correct and helpful.</P></LI>

<LI><P>9.2 [class.mem] paragraph 11: the term is used
(three times) in an example.  There appears to be no reason to use
it instead of &#8220;class,&#8221; but its use is not
problematic.</P></LI>

<LI><P>17.3 [definitions] &#8220;<B>iostream class templates</B>:&#8221;
the <TT>traits</TT> argument
to the iostream class templates is (presumably unintentionally)
constrained to be a structure, i.e., to use the <TT>struct</TT>
keyword and not the <TT>class</TT> keyword in its definition.</P></LI>

<LI><P>B [implimits] paragraph 2: the minimum number of
declarator operators is given for structures and unions but not
for classes defined using the <TT>class</TT> keyword.</P></LI>

<LI><P>B [implimits] paragraph 2: class, structure,
and union are used as disjoint terms in describing nesting
levels.  (The nonexistent nonterminal <I>struct-declaration-list</I>
is used, as well.)</P></LI>

</UL>

<P>There does not appear to be a reason for defining the term
<I>structure</I>.  The one reference where it is arguably useful,
in the note in 5.2.5 [expr.ref], could be rewritten
as something like, &#8220;'class objects' may be defined using the
<TT>class</TT>, <TT>struct</TT>, or <TT>union</TT>
<I>class-key</I>s; see clause 9 [class].&#8221;</P>

</LI>

<LI><P>Based on its usage later in the paragraph and elsewhere,
&#8220;POD-struct&#8221; appears to be intended to exclude unions.
However, the definition of &#8220;aggregate class&#8221; in
8.5.1 [dcl.init.aggr] paragraph 1 includes unions.
Furthermore, the name itself is confusing, leading to the question of
whether it was intended that only classes defined
using <TT>struct</TT> could be POD-structs or
if <TT>class</TT>-classes are included.  The definition should
probably be rewritten as, &#8220;A <I>POD-struct</I> is an aggregate
class <SPAN style="font-weight:bold;background-color:#A0FFA0">defined with the <I>class-key</I> <TT>struct</TT> or
the <I>class-key</I> <TT>class</TT></SPAN> that has no...</P>

</LI>

<LI><P>In most references outside clause 9 [class],
POD-struct and POD-union are mentioned together and treated
identically.  These references should be changed to refer to the
unified term, &#8220;POD class.&#8221;</P></LI>

<LI><P>Noted in passing: 18.2 [support.types] paragraph 4
refers to the undefined terms &#8220;POD structure&#8221; and
(unhyphenated) &#8220;POD union;&#8221; the pair should be replaced
by a single reference to &#8220;POD class.&#8221;</P></LI>

</OL>

<P><B>Proposed resolution (April, 2006):</B></P>

<OL>

<LI><P>Change 9 [class] paragraph 4 as indicated:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A <I>structure</I> is a class defined with
the <I>class-key</I> <TT>struct</TT>; its members and base classes
(clause 10 [class.derived]) are public by default (clause
11 [class.access]).</SPAN> A <I>union</I> is a class defined with the
<I>class-key</I> <TT>union</TT>; <SPAN style="text-decoration:line-through;background-color:#FFA0A0">its members are public by default
and</SPAN> it holds only one data member at a time (9.5 [class.union]).  [<I>Note:</I> aggregates of class type are described
in 8.5.1 [dcl.init.aggr].  &#8212;<I>end note</I>]
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A <I>POD-struct</I> 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 <I>POD-union</I> 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 <I>POD class</I> is a class that is either a POD-struct
or a POD-union.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">A <I>POD class</I> is an aggregate class that
has no non-static data members of non-POD type (or array of such a
type) or reference, and has no user-declared copy assignment operator
and no user-declared destructor. A <I>POD-struct</I> is a POD class
defined with the <I>class-key</I> <TT>struct</TT> or
the <I>class-key</I> <TT>class</TT>. A <I>POD-union</I> is a POD class
defined with the <I>class-key</I> <TT>union</TT>.</SPAN>

</BLOCKQUOTE>

</LI>

<LI><P>Change 11.2 [class.access.base] paragraph 2 as indicated:</P>

<BLOCKQUOTE>

In the absence of an <I>access-specifier</I> for a base
class, <TT>public</TT> is assumed when the derived class is
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">declared</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">defined with
the <I>class-key</I></SPAN> <TT>struct</TT> and <TT>private</TT> is
assumed when the class is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">declared</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">defined with the
<I>class-key</I></SPAN> <TT>class</TT>. [<I>Example:</I>...

</BLOCKQUOTE>

</LI>

<LI><P>Delete the note in 5.2.5 [expr.ref] paragraph 4:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">[<I>Note:</I> &#8220;class objects&#8221; can be structures
(9.2 [class.mem]) and unions (9.5 [class.union]). Classes are discussed in clause 9 [class].
&#8212;<I>end note</I>]</SPAN>

</BLOCKQUOTE>

</LI>

<LI><P>Change the commentary in the example in 9.2 [class.mem]
paragraph 11 as indicated:</P>

<BLOCKQUOTE>

<P>...an integer, and two pointers to <SPAN style="text-decoration:line-through;background-color:#FFA0A0">similar structures</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">objects of the same type</SPAN>. Once this definition...</P>

<P>...the <TT>count</TT> member of the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">structure</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">object</SPAN>
to which <TT>sp</TT> points; <TT>s.left</TT> refers to
the <TT>left</TT> subtree pointer of the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">structure</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">object</SPAN> <TT>s</TT>; and...</P>

</BLOCKQUOTE>

</LI>

<LI><P>Change 17.3 [definitions] &#8220;<B>iostream class
templates</B>&#8221; as indicated:</P>

<BLOCKQUOTE>

...the argument <TT>traits</TT> is a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">structure</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">class</SPAN>
which defines additional characteristics...

</BLOCKQUOTE>

</LI>

<LI><P>Change 18.6 [support.dynamic] paragraph 4 as indicated:</P>

<BLOCKQUOTE>

If <I>type</I> is not a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">POD structure or a POD union</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">POD class</SPAN> (clause 9), the results are undefined.

</BLOCKQUOTE>

</LI>

<LI><P>Change the third bullet of B [implimits] paragraph 2 as
indicated:</P>

<UL><LI><P>

Pointer, array, and function declarators (in any combination)
modifying <SPAN style="text-decoration:line-through;background-color:#FFA0A0">an</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">a class,</SPAN> arithmetic, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">structure,
union,</SPAN> or incomplete type in a declaration [256].

</P></LI></UL>

</LI>

<LI><P>Change the nineteenth bullet of B [implimits] paragraph 2
as indicated:</P>

<UL><LI><P>

Data members in a single class<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, structure, or union</SPAN> [16 384].

</P></LI></UL>

</LI>

<LI><P>Change the twenty-first bullet of B [implimits] paragraph 2
as indicated:</P>

<UL><LI><P>

Levels of nested class<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, structure, or union</SPAN> definitions in a
single <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>struct-declaration-list</I></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>member-specification</I></SPAN> [256].

</P></LI></UL>

</LI>

<LI><P>Change C.4 [diff.library] paragraph 6 as indicated:</P>

<BLOCKQUOTE>

The C++ Standard library provides 2 standard <SPAN style="text-decoration:line-through;background-color:#FFA0A0">structures</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>struct</TT>s</SPAN> from the C library, as shown in Table 126.

</BLOCKQUOTE>

</LI>

<LI><P>Change the last sentence of 3.9 [basic.types]
paragraph 10 as indicated:</P>

<BLOCKQUOTE>

Scalar types, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">POD-struct types, POD-union types</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">POD
classes</SPAN> (clause 9 [class]), arrays of such types
and <I>cv-qualified</I> versions of these types (3.9.3 [basic.type.qualifier]) are collectively called
<I>POD types</I>.

</BLOCKQUOTE>

<P><I>Drafting note:</I> Do not change 3.9 [basic.types]
paragraph 11, because it's a note and the definition of
&#8220;layout-compatible&#8221; is separate for POD-struct and
POD-union in 9.2 [class.mem].</P>

</LI>

</OL>

<P>(This resolution also resolves <A HREF="
     cwg_defects.html#327">issue 327</A>.)</P>

<BR><BR><HR><A NAME="568"></A><H4>568.
  
Definition of POD is too strict
</H4><B>Section: </B>9&#160; [class]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Matt Austern
 &#160;&#160;&#160;

 <B>Date: </B>20 March 2006<BR>


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

<P>A POD struct (9 [class] paragraph 4) is &#8220;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.&#8221; Meanwhile, an aggregate class
(8.5.1 [dcl.init.aggr] paragraph 1) must have &#8220;no
user-declared constructors, no private or protecte non-static data
members, no base classes, and no virtual functions.&#8221;</P>

<P>This is too strict. The whole reason we define the notion of POD is
for the layout compatibility guarantees in 9.2 [class.mem]
paragraphs 14-17 and the byte-for-byte copying guarantees of
3.9 [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&#8217;s silly for the standard to make layout and memcpy
guarantees for this class:</P>

<PRE>
 struct A {
    int n;
 };
</PRE>

<P>but not for this one:</P>

<PRE>
  struct B {
    int n;
    B(n_) : n(n_) { }
  };
</PRE>

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

<P>Suggested resolution:</P>

<P>The following doesn&#8217;t fix all problems (in particular it
still doesn&#8217;t let us treat <TT>pair&lt;int, int&gt;</TT> as a
POD), but at least it goes a long way toward fixing the problem: in
8.5.1 [dcl.init.aggr] paragraph 1, change &#8220;no
user-declared constructors&#8221; to &#8220;no nontrivial default
constructor and no user-declared copy constructor.&#8221;</P>

<P>(Yes, I&#8217;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.)</P>

<P><U>Mike Miller</U>: I agree that something needs to be done about
&#8220;POD,&#8221; but I&#8217;m not sure that this is it.  My own
take is that &#8220;POD&#8221; is used for too many different things
&#8212; things that are related but not identical &#8212; and the
concept should be split.  The current definition is useful, as is, for
issues regarding initialization and lifetime.  For example, I
wouldn&#8217;t want to relax the prohibition of jumping over a
constructor call in 6.7 [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 &#8220;memcpy initialization&#8221; (for
want of a better term) with object lifetime, etc.</P>

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

<P><B>Proposed resolution (April, 2007):</B></P>

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

<BR><BR><HR><A NAME="417"></A><H4>417.
  
Using derived-class qualified name in out-of-class nested class definition
</H4><B>Section: </B>9.1&#160; [class.name]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jon Caves
 &#160;&#160;&#160;

 <B>Date: </B>19 May 2003<BR>


<P>[Voted into WP at October 2004 meeting.]</P>

<P>We had a user complain that our compiler was allowing the
following code:</P>
<PRE>
  struct B {
    struct S;
  };

  struct D : B { };

  struct D::S {
  };
</PRE>

<P>We took one look at the code and made the reasonable (I would claim)
assumption that this was
indeed a bug in our compiler. Especially as we had just fixed a very
similar issue with the
definition of static data members.</P>

<P>Imagine our surprise when code like this showed up in Boost and that
every other compiler we tested accepts this code. So is this
indeed legal (it seems like
it must be) and if so is there any justification for this beyond
3.4.3.1 [class.qual]?</P>

<P><U>John Spicer:</U>
The equivalent case for a member function is covered by the declarator
rules in 8.3 [dcl.meaning] paragraph 1.  The committee has
previously run into cases where a restriction should apply to both
classes and non-classes, but fails to do so because there is no 
equivalent of 8.3 [dcl.meaning] paragraph 1 for classes.</P>

<P>Given that, by the letter of the standard, I would say that this
case is allowed.</P>

<P><B>Notes from October 2003 meeting:</B></P>

<P>We feel this case should get an error.</P>

<P><B>Proposed Resolution (October 2003):</B></P>

<P>Note that the change here interacts with
<A HREF="
     cwg_defects.html#432">issue 432</A>.</P>

<P>Add the following as a new paragraph immediately following
3.3.2 [basic.scope.pdecl] paragraph 2:</P>
<BLOCKQUOTE>
The point of declaration for a class first declared by a
<I>class-specifier</I> is 
immediately after the <I>identifier</I>
or <I>template-id</I> (if any) in its <I>class-head</I>
(Clause 9 [class]). 
The point of declaration for an enumeration is immediately after
the <I>identifier</I> (if any) in its <I>enum-specifier</I>
(7.2 [dcl.enum]). 
</BLOCKQUOTE>

<P>Change point 1 of 3.3.7 [basic.scope.class] paragraph 1 to read: </P>
<BLOCKQUOTE>
The potential scope of a name declared in a class consists not only of the 
declarative region following the name's
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">declarator</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">point of declaration</SPAN>, but also 
of all function bodies, default arguments, and constructor
<I>ctor-initializer</I>s in that 
class (including such things in nested classes). 
</BLOCKQUOTE>

<P><I>[Note that the preceding change duplicates one of the changes
in the proposed resolution of issue 432.]</I></P>

<P>Change 14.7.2 [temp.explicit] paragraph 2 to read: </P>
<BLOCKQUOTE>
If the explicit instantiation is for a member function, a member
class or a static 
data member of a class template specialization, the name of
the class template 
specialization in the <I>qualified-id</I> for the member <SPAN style="text-decoration:line-through;background-color:#FFA0A0">declarator</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">name</SPAN> shall be a <I>template-id</I>.
</BLOCKQUOTE>

<P>Add the following as paragraph 5 of Clause 9 [class]:</P>
<BLOCKQUOTE> 
If a <I>class-head</I> contains a <I>nested-name-specifier</I>,
the <I>class-specifier</I> shall refer to a 
class that was previously declared directly in the class or namespace
to which the <I>nested-name-specifier</I> refers (i.e., neither
inherited nor introduced by a <I>using-declaration</I>), 
and the <I>class-specifier</I> shall appear in a namespace enclosing the 
previous declaration. 
</BLOCKQUOTE>

<P>Delete 9.1 [class.name] paragraph 4 (this was added
by <A HREF="
     cwg_defects.html#284">issue 284</A>):</P>
<BLOCKQUOTE>
When a <I>nested-name-specifier</I> is specified in a
<I>class-head</I> or in an
<I>elaborated-type-specifier</I>, the resulting qualified name
shall refer to a previously declared member of the class or namespace to
which the <I>nested-name-specifier</I> refers, and
the member shall not have been introduced by a
using-declaration in the scope of the class or namespace
nominated by the <I>nested-name-specifier</I>.
</BLOCKQUOTE>

<BR><BR><HR><A NAME="328"></A><H4>328.
  
Missing requirement that class member types be complete
</H4><B>Section: </B>9.2&#160; [class.mem]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Michiel Salters
 &#160;&#160;&#160;

 <B>Date: </B>10 Dec 2001<BR>


<P>[Voted into WP at March 2004 meeting.]</P>

<P>Is it legal to use an incomplete type (3.9 [basic.types]
paragraph 6) as a
class member, if no object of such class is ever created ?</P>

<P>And as a class template member, even if the template is instantiated,
but no object of the instantiated class is created?</P>

<P>The consensus seems to be NO, but no wording was found in the standard
which explicitly disallows it.</P>

<P>The problem seems to be that most of the restrictions on incomplete types
are on their use in objects, but class members are not objects.</P>

<P>A possible resolution, if this is considered a defect, is to add to 
3.2 [basic.def.odr] paragraph 4, (situations when T must be complete),
the use of T as a member of a class or instantiated class template.</P>

<P>The thread on comp.std.c++ which brought up the issue was 
"Compiler differences: which is correct?", started 2001 11 30.
&lt;3c07c8fb$0$8507$ed9e5944@reading.news.pipex.net&gt;</P>

<P><B>Proposed Resolution (April 2002, revised April 2003):</B></P>

<P>Change the first bullet of the note in 3.2 [basic.def.odr]
paragraph 4 and add two new bullets following it, as follows:</P>
<UL>
<LI>an object of type <TT>T</TT> is defined
(3.1 [basic.def]<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, 5.3.4 [expr.new]</SPAN>), or</LI>
<LI>a non-static class data member of type <TT>T</TT> is declared
(9.2 [class.mem]), or</LI>
<LI><TT>T</TT> is used as the object type or array element type
in a <I>new-expression</I> (5.3.4 [expr.new]), or</LI>
</UL>

<P>
Replace 9.2 [class.mem] paragraph 8 by:</P>
<BLOCKQUOTE>
Non-<TT>static</TT> (9.4 [class.static]) data members shall
not have incomplete types.
In particular, a class <TT>C</TT> shall not contain a non-<TT>static</TT>
member of class <TT>C</TT>, but it can contain a pointer or reference to
an object of class <TT>C</TT>.
</BLOCKQUOTE>

<P>See also 3.9 [basic.types] paragraph 6, which is relevant
but not changed by the Proposed Resolution.</P>

<BR><BR><HR><A NAME="437"></A><H4>437.
  
Is type of class allowed in member function exception specification?
</H4><B>Section: </B>9.2&#160; [class.mem]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Cary Coutant
 &#160;&#160;&#160;

 <B>Date: </B>10 Oct 2003<BR>


<P>[Voted into WP at April 2005 meeting.]</P>

<P>I've encountered a C++ program in which a member function wants to 
declare that it may throw an object of its own class, e.g.:</P>
<PRE>
  class Foo {
  private:
     int val;
  public:
     Foo( int &amp;initval ) { val = initval; };
     void throwit() throw(Foo) { throw (*this); };
  };
</PRE>
<P>The compiler is complaining that Foo is an incomplete type, and can't be 
used in the exception specification.</P>

<P>My reading of the standard [basic.types] is inconclusive.  Although it 
does state that the class declaration is considered complete when the 
closing brace is read, I believe it also intends that the member 
function declarations should not be semantically validated until the 
class has been completely declared.</P>

<P>If this isn't allowed, I don't know how else a member function could be 
declared to throw an object of its own class.</P>

<P><U>John Spicer</U>:
The type is considered complete within function bodies, but not in their 
declaration (see 9.2 [class.mem] paragraph 2).</P>

<P><B>Proposed Resolution:</B></P>

<P>Change 9.2 [class.mem] paragraph 2 as follows:</P>
<BLOCKQUOTE>
Within the class <I>member-specification</I>, the class is regarded
as complete within function bodies, default arguments<B>,
<I>exception-specification</I>s,</B> and constructor
<I>ctor-initializer</I>s (including such things in nested classes).
</BLOCKQUOTE>

<P><B>Rationale:</B> Taken with 8.3.5 [dcl.fct] paragraph 6, the
<I>exception-specification</I> is the <I>only</I> part of a function
declaration/definition in which the class name cannot be used because
of its putative incompleteness.  There is no justification for
singling out exception specifications this way; both in the function
body and in a <TT>catch</TT> clause, the class type will be complete,
so there is no harm in allowing the class name to be used in the
<I>exception-specification</I>.
</P>

<BR><BR><HR><A NAME="613"></A><H4>613.
  
Unevaluated uses of non-static class members
</H4><B>Section: </B>9.2&#160; [class.mem]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Herb Sutter
 &#160;&#160;&#160;

 <B>Date: </B>28 October 2006<BR>


<P>[Voted into WP at April, 2007 meeting.]</P>



<P>According to 9.2 [class.mem] paragraph 9, the name of a
non-static data member can only be used with an object reference
(explicit or implied by the <TT>this</TT> pointer of a non-static
member function) or to form a pointer to member.  This restriction
applies even in the operand of <TT>sizeof</TT>, although the
operand is not evaluated and thus no object is needed to perform the
operation.  Consequently, determining the size of a non-static class
member often requires a circumlocution like
</P>

<PRE>
    sizeof ((C*) 0)-&gt;m
</PRE>

<P>instead of the simpler and more obvious (but incorrect)</P>

<PRE>
    sizeof (C::m)
</PRE>

<P>The CWG considered this question as part of
<A HREF="
     cwg_defects.html#198">issue 198</A> and decided at that time to
retain the restriction on consistency grounds: the rule was
viewed as applying uniformly to expressions, and making an
exception for <TT>sizeof</TT> would require introducing a
special-purpose &#8220;wart.&#8221;</P>

<P>The issue has recently resurfaced, in part due to the fact that
the restriction would also apply to the <TT>decltype</TT> operator.
Like the unary <TT>&amp;</TT> operator to form a pointer to member,
<TT>sizeof</TT> and <TT>decltype</TT> need neither an lvalue nor
an rvalue, requiring solely the declarative information of the
named operand.  One possible approach would be to define the concept
of &#8220;unevaluated operand&#8221; or the like, exempt unevaluated
operands from the requirement for an object reference in
9.2 [class.mem] paragraph 9, and then define the operands
of these operators as &#8220;unevaluated.&#8221;</P>

<P><B>Proposed resolution (April, 2007):</B></P>

<P>The wording is given in paper J16/07-0113 = WG21 N2253.</P>

<BR><BR><HR><A NAME="620"></A><H4>620.
  
Declaration order in layout-compatible POD structs
</H4><B>Section: </B>9.2&#160; [class.mem]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Martin Sebor
 &#160;&#160;&#160;

 <B>Date: </B>1 March 2007<BR>


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



<P>It should be made clear in 9.2 [class.mem] paragraph 15,</P>

<BLOCKQUOTE>

Two POD-struct (clause 9 [class]) 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 [basic.types]).

</BLOCKQUOTE>

<P>that &#8220;corresponding... (in order)&#8221; refers to declaration
order and not the order in which the members are laid out in memory.</P>

<P>However, this raises the point that, in cases where an
<I>access-specifier</I> is involved, the declaration and layout
order can be different (see paragraph 12).  Thus, for two POD-struct
classes <TT>A</TT> and <TT>B</TT>,</P>

<PRE>
    struct A {
        char c;
        int i;
    }
    struct B {
        char c;
      public:
        int i;
    };
</PRE>

<P>a compiler could move <TT>B::i</TT> before <TT>B::c</TT>, but
<TT>A::c</TT> must precede <TT>A::i</TT>.  It does not seem
reasonable that these two POD-structs would be considered
layout-compatible, even though they satisfy the requirement that
corresponding members in declaration order are layout-compatible.</P>

<P>One possibility would be to require that neither POD-struct have
an <I>access-specifier</I> in order to be considered
layout-compatible.  (It's not sufficient to require that they have
the same <I>access-specifier</I>s, because the compiler is not
required to lay out the storage the same way for different classes.)</P>

<P>8.5.1 [dcl.init.aggr] paragraph 2 should also be clarified
to make explicit that &#8220;increasing... member order&#8221; refers
to declaration order.</P>

<P><B>Proposed resolution (April, 2007):</B></P>

<P>This issue will be resolved by the adoption of the POD proposal
(currently J16/07-0090 = WG21 N2230).  That paper does not propose
a change to the wording of 8.5.1 [dcl.init.aggr] paragraph 2,
but the CWG feels that the intent of that paragraph (that the
initializers are used in declaration order) is clear enough not to
require revision.</P>

<BR><BR><HR><A NAME="452"></A><H4>452.
  
Wording nit on description of <TT>this</TT>
</H4><B>Section: </B>9.3.2&#160; [class.this]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Gennaro Prota
 &#160;&#160;&#160;

 <B>Date: </B>8 Jan 2004<BR>


<P>[Voted into WP at July, 2007 meeting.]</P>

<P>9.3.2 [class.this] paragraph 1, which specifies the
meaning of the
keyword 'this', seems to limit its usage to the *body* of non-static
member functions. However 'this' is also usable in ctor-initializers
which, according to the grammar in
8.4 [dcl.fct.def] par. 1, are not
part of the body.</P>

<P>Proposed resolution: Changing the first part of
9.3.2 [class.this] par. 1 to:</P>
<BLOCKQUOTE>
  In the body of a nonstatic (9.3) member function <SPAN style="font-weight:bold;background-color:#A0FFA0">or in a
   ctor-initializer (12.6.2)</SPAN>, the keyword <TT>this</TT> is a non-lvalue
   expression whose value is the address of the object for which
   the function is called.
</BLOCKQUOTE>
<P>NOTE: I'm talking of constructors as functions that are "called";
there have been discussions on c.l.c++.m as to whether constructors
are "functions" and to whether this terminology is correct or not; I
think it is both intuitive and in agreement with the standard wording.</P>

<P><U>Steve Adamczyk:</U> See also <A HREF="
     cwg_defects.html#397">issue 397</A>,
which is defining a new syntax term for the body of a function
including the ctor-initializers.</P>

<P><B>Notes from the March 2004 meeting:</B></P>

<P>This will be resolved when
<A HREF="
     cwg_defects.html#397">issue 397</A> is resolved.</P>

<P><B>Proposed resolution (October, 2005):</B></P>

<OL>

<LI><P>Change 8.4 [dcl.fct.def] paragraph 1 as indicated:</P></LI>

<BLOCKQUOTE>

<P>Function definitions have the form</P>

<P><UL><I>function-definition:</I>
<UL><I>decl-specifier-seq<SUB>opt</SUB> declarator <SPAN style="text-decoration:line-through;background-color:#FFA0A0">ctor-initializer<SUB>opt</SUB></SPAN> function-body</I></UL>
<UL><I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">decl-specifier-seq<SUB>opt</SUB> declarator function-try-block</SPAN></I></UL>
<I>function-body:</I>
<UL><I><SPAN style="font-weight:bold;background-color:#A0FFA0">ctor-initializer<SUB>opt</SUB></SPAN> compound-statement</I></UL>
<UL><I><SPAN style="font-weight:bold;background-color:#A0FFA0">function-try-block</SPAN></I></UL></UL></P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">An informal reference to the body of a function should be
interpreted as a reference to the nonterminal <I>function-body</I>.</SPAN></P>

</BLOCKQUOTE>

<LI><P>Change the definition of <I>function-try-block</I> in
15 [except] paragraph 1:</P></LI>

<BLOCKQUOTE>

<UL><I>function-try-block:</I>
<UL><TT>try</TT><I> ctor-initializer<SUB>opt</SUB> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">function-body</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">compound-statement</SPAN> handler-seq</I></UL></UL>

</BLOCKQUOTE>

<LI><P>Change 3.3.7 [basic.scope.class] paragraph 1, point 1, as
indicated:</P></LI>

<BLOCKQUOTE>

The potential scope of a name declared in a class consists not only of
the declarative region following the name's point of declaration, but
also of all function <SPAN style="text-decoration:line-through;background-color:#FFA0A0">bodies,</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">bodies and</SPAN> default
arguments<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, and constructor <I>ctor-initializer</I>s</SPAN> in that
class (including such things in nested classes).

</BLOCKQUOTE>

<LI><P>Change 3.3.7 [basic.scope.class] paragraph 1, point 5, as
indicated:</P></LI>

<BLOCKQUOTE>

The potential scope of a declaration that extends to or past the end
of a class definition also extends to the regions defined by its
member definitions, even if the members are defined lexically outside
the class (this includes static data member definitions, nested class
definitions, member function definitions (including the member
function body <SPAN style="text-decoration:line-through;background-color:#FFA0A0">and, for constructor functions (12.1 [class.ctor]), the ctor-initializer (<sectionj_ref ref="12.6.2">12.6.2 [class.base.init]</sectionj_ref>)</SPAN>)
and any portion of the declarator part of such definitions which
follows the identifier, including a <I>parameter-declaration-clause</I>
and any default arguments (8.3.6 [dcl.fct.default]).
[<I>Example:</I>...

</BLOCKQUOTE>

<LI><P>Change footnote 32 in 3.4.1 [basic.lookup.unqual] paragraph 8
as indicated:</P></LI>

<BLOCKQUOTE>

That is, an unqualified name that occurs, for instance, in a type or
default argument expression in the <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>parameter-declaration-clause</I>,</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>parameter-declaration-clause</I> or</SPAN> in the function body<SPAN style="text-decoration:line-through;background-color:#FFA0A0">,
or in an expression of a <I>mem-initializer</I> in a constructor
definition</SPAN>.

</BLOCKQUOTE>

<LI><P>Change 5.1.1 [expr.prim.general] paragraph 3 as indicated:</P></LI>

<BLOCKQUOTE>

...The keyword <TT>this</TT> shall be used only inside a non-static
class member function body (9.3 [class.mfct]) <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or in a
constructor <I>mem-initializer</I> (12.6.2 [class.base.init])</SPAN>...

</BLOCKQUOTE>

<LI><P>Change 9.2 [class.mem] paragraph 2 as indicated:</P></LI>

<BLOCKQUOTE>

...Within the class <I>member-specification</I>, the class is regarded as
complete within function bodies, default arguments, <SPAN style="font-weight:bold;background-color:#A0FFA0">and</SPAN>
<I>exception-specification</I>s<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, and constructor
<I>ctor-initializer</I>s</SPAN> (including such things in nested classes)...

</BLOCKQUOTE>

<LI><P>Change 9.2 [class.mem] paragraph 9 as indicated:</P></LI>

<BLOCKQUOTE>

Each occurrence in an expression of the name of a non-static data
member or non-static member function of a class shall be expressed as
a class member access (5.2.5 [expr.ref]), except when it
appears in the formation of a pointer to member (5.3.1 [expr.unary.op])<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, or</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">or</SPAN> when it appears in the body of
a non-static member function of its class or of a class derived from
its class (9.3.1 [class.mfct.non-static])<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, or when it appears in
a <I>mem-initializer</I> for a constructor for its class or for a
class derived from its class (12.6.2 [class.base.init])</SPAN>.

</BLOCKQUOTE>

<LI><P>Change the note in 9.3 [class.mfct] paragraph 5 as
indicated:</P></LI>

<BLOCKQUOTE>

[<I>Note:</I> a name used in a member function definition (that is, in the
<I>parameter-declaration-clause</I> including the default arguments
(8.3.6 [dcl.fct.default])<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, or</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">or</SPAN> in the member
function body<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, or, for a constructor function (12.1 [class.ctor]), in a <TT>mem-initializer</TT> expression (12.6.2 [class.base.init])</SPAN>) is looked up as described in 3.4 [basic.lookup]. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Change 9.3.1 [class.mfct.non-static] paragraph 1 as indicated:</P></LI>

<BLOCKQUOTE>

<P>...A non-static member function may also be called directly using
the function call syntax (5.2.2 [expr.call], 13.3.1.1 [over.match.call]) <SPAN style="font-weight:bold;background-color:#A0FFA0">from within the body of a member function of its class or of a class derived from its class.</SPAN></P>

<UL><SPAN style="text-decoration:line-through;background-color:#FFA0A0">
<LI>from within the body of a member function of its class or of a
class derived from its class, or</LI>
<LI>from a <I>mem-initializer</I> (12.6.2 [class.base.init]) for
a constructor for its class or for a class derived from its class.</LI>
</SPAN></UL>

</BLOCKQUOTE>

<LI><P>Change 9.3.1 [class.mfct.non-static] paragraph 3 as indicated:</P></LI>

<BLOCKQUOTE>

When an <I>id-expression</I> (5.1.1 [expr.prim.general]) that is not
part of a class member access syntax (5.2.5 [expr.ref])
and not used to form a pointer to member (5.3.1 [expr.unary.op]) is used in the body of a non-static member function
of class <TT>X</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or used in the <I>mem-initializer</I> for a
constructor of class <TT>X</TT></SPAN>, if name lookup (3.4.1 [basic.lookup.unqual]) resolves the name in the <I>id-expression</I> to a
non-static non-type member of class <TT>X</TT> or of a base class
of <TT>X</TT>, the <I>id-expression</I> is transformed into a class
member access expression (5.2.5 [expr.ref])
using <TT>(*this)</TT> (9.3.2 [class.this]) as the
<I>postfix-expression</I> to the left of the <TT>.</TT>  operator...

</BLOCKQUOTE>

<LI><P>Change 12.1 [class.ctor] paragraph 7 as indicated:</P></LI>

<BLOCKQUOTE>

...The implicitly-defined default constructor performs the set of
initializations of the class that would be performed by a user-written
default constructor for that class with <SPAN style="text-decoration:line-through;background-color:#FFA0A0">an
empty <I>mem-initializer-list</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">no <I>ctor-initializer</I></SPAN> (12.6.2 [class.base.init])
and an empty <SPAN style="text-decoration:line-through;background-color:#FFA0A0">function body</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>compound-statement</I></SPAN>...

</BLOCKQUOTE>

<LI><P>Change 12.6.2 [class.base.init] paragraph 4 as indicated:</P></LI>

<BLOCKQUOTE>

...After the call to a constructor for class <TT>X</TT> has completed, if a
member of <TT>X</TT> is neither specified in the constructor's
<I>mem-initializer</I>s, nor default-initialized, nor
value-initialized, nor given a value during execution
of <SPAN style="font-weight:bold;background-color:#A0FFA0">the <I>compound-statement</I> of</SPAN> the body of the
constructor, the member has indeterminate value.

</BLOCKQUOTE>

<LI><P>Change the last bullet of 12.6.2 [class.base.init]
paragraph 5 as indicated:</P></LI>

<UL><LI><P>Finally, the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">body</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>compound-statement</I></SPAN> of the
constructor <SPAN style="font-weight:bold;background-color:#A0FFA0">body</SPAN> is executed.</P></LI></UL>

<LI><P>Change 15 [except] paragraph 4 as indicated:</P></LI>

<BLOCKQUOTE>

<P>A <I>function-try-block</I> associates a <I>handler-seq</I> with the
<I>ctor-initializer</I>, if present, and the <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>function-body</I></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>compound-statement</I></SPAN>. An exception thrown during the
execution of the initializer expressions in
the <I>ctor-initializer</I> or during the execution of
the <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>function-body</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>compound-statement</I></SPAN>
transfers control to a handler in a
<I>function-try-block</I> in the same way as an exception thrown
during the execution of a <I>try-block</I> transfers control to other
handlers. [<I>Example:</I></P>

<PRE>
    int f(int);
    class C {
        int i;
        double d;
    public:
        C(int, double);
    };

    C::C(int ii, double id)
    try
        : i(f(ii)), d(id)
    {
        //<SPAN style="font-family:Times;font-style:italic"> constructor <SPAN style="text-decoration:line-through;background-color:#FFA0A0">function body</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">statements</SPAN></SPAN>
    }
    catch (...)
    {
        //<SPAN style="font-family:Times;font-style:italic"> handles exceptions thrown from the ctor-initializer</SPAN>
        //<SPAN style="font-family:Times;font-style:italic"> and from the constructor <SPAN style="text-decoration:line-through;background-color:#FFA0A0">function body</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">statements</SPAN></SPAN>
    }
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<LI><P>Change 15.2 [except.ctor] paragraph 2 as indicated:</P></LI>

<BLOCKQUOTE>

When an exception is thrown, control is transferred to the nearest
handler with a matching type (15.3 [except.handle]);
&#8220;nearest&#8221; means the handler for which the
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>compound-statement</I>,</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>compound-statement</I>
or</SPAN> <I>ctor-initializer</I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">, or <I>function-body</I></SPAN> following
the <TT>try</TT> keyword was most recently entered by the thread of
control and not yet exited.

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="406"></A><H4>406.
  
Static data member in class with name for linkage purposes
</H4><B>Section: </B>9.4.2&#160; [class.static.data]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jorgen Bundgaard
 &#160;&#160;&#160;

 <B>Date: </B>12 Mar 2003<BR>


<P>[Voted into WP at March 2004 meeting.]</P>

<P> The following test program is claimed to be a negative C++ 
test case for "Unnamed classes shall not contain static data members", 
c.f. ISO/IEC 14882 section 9.4.2 [class.static.data] paragraph 5.</P>

<PRE> 
  struct B {
         typedef struct {
                 static int i;          // Is this legal C++ ?
         } A;
  };
 
  int B::A::i = 47;      // Is this legal C++ ?
</PRE>
 
<P> We are not quite sure about what an "unnamed class" is. 
There is no exact definition in ISO/IEC 14882; the closest we can come to a 
hint is the wording of section 7.1.3 [dcl.typedef]
paragraph 5, where it seems to be understood that a class-specifier with no
identifier between "class" and "{" is unnamed. The identifier provided after
"}" ( "A" in the test case above) is there for "linkage purposes" only.</P>
 
<P>To us, class B::A in the test program above seems "named" 
enough, and there is certainly a mechanism to provide the definition for
B::A::i (in contrast to the note in section 9.4.2 [class.static.data]
paragraph 5).</P>
 
<P>Our position is therefore that the above test program is 
indeed legal C++. Can you confirm or reject this claim?</P>

<P><U>Herb Sutter replied to the submitter as follows:</U>
Here are my notes based on a grep for
"unnamed class" in the standard:</P>
<UL>
<LI>
3.5 [basic.link] paragraph 4, bullet 3, makes a note that
does not directly speak to your question but which draws the same distinction:
<BLOCKQUOTE>
a named class (clause class), or an unnamed class defined in a
typedef declaration in which the class has the typedef name for
linkage purposes (7.1.3 [dcl.typedef]);
</BLOCKQUOTE>
Likewise in your example, you have an unnamed class defined in a
typedef declaration.
</LI>
<LI>
9.4.2 [class.static.data] paragraph 5 does indeed appear to
me to make your example not supported by ISO C++ (although implementations
could allow it as an extension, and many implementation do happen to allow it).
</LI>
<LI>
7.1.3 [dcl.typedef] paragraph 5 does indeed likewise confirm
the interpretation you give of an unnamed class.
</LI>
</UL>

<P>So yes, an unnamed class is one where there is no identifier (class
name) between the class-key and the {. This is also in harmony with the
production for class-name in 9 [class] paragraph 1:</P>

<UL><I>class-name</I><TT>:</TT>
<UL><I>identifier</I><BR>
    <I>template-id</I>
</UL>
</UL>

<P><B>Notes from the October 2003 meeting:</B></P>

<P>We agree that the example is not valid; this is an unnamed class.
We will add wording to define an unnamed class.  The note in
9.4.2 [class.static.data] paragraph 5 should be corrected
or deleted.</P>

<P><B>Proposed Resolution (October 2003):</B></P>

<P>
At the end of clause 9 [class],
paragraph 1, add the following:</P>

<BLOCKQUOTE>
A <I>class-specifier</I> where the <I>class-head</I> omits
the optional <I>identifier</I> defines an unnamed class.
</BLOCKQUOTE>

<P>
Delete the following from 9.4.2 [class.static.data] paragraph 5:</P>

<BLOCKQUOTE>
[ <I>Note:</I> this is because there is no mechanism to provide the
definitions for such static data members. ]
</BLOCKQUOTE>

<BR><BR><HR><A NAME="454"></A><H4>454.
  
When is a definition of a static data member required?
</H4><B>Section: </B>9.4.2&#160; [class.static.data]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Gennaro Prota
 &#160;&#160;&#160;

 <B>Date: </B>18 Jan 2004<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>

<P>As a result of the resolution of <A HREF="
     cwg_defects.html#48">core issue 48</A>, the current C++ standard is not in sync with existing
practice and with user expectations as far as definitions of static
data members having const integral or const enumeration type are
concerned. Basically what current implementations do is to require a
definition only if the address of the constant is taken. Example:</P>
<PRE>
void f() {

  std::string s;
  ... 

  // current implementations don't require a definition
  if (s.find('a', 3) == std::string::npos) {
   ...
  }
</PRE>
<P>To the letter of the standard, though, the above requires a
definition of <TT>npos</TT>, since the
expression <TT>std::string::npos</TT> is potentially evaluated. I
think this problem would be easily solved with simple changes to
9.4.2 [class.static.data] paragraph 4, 9.4.2 [class.static.data] paragraph 5 and 3.2 [basic.def.odr] paragraph
3.</P>


<P>Suggested resolution:</P>

<P>Replace 9.4.2 [class.static.data] paragraph 4 with:</P>
<BLOCKQUOTE>
<P>If a static data member is of const integral or const enumeration
type, its declaration in the class definition can specify a
constant-initializer which shall be [note1] an integral constant
expression (5.19). In that case, the member can appear in integral
constant expressions. No definition of the member is required, unless
an lvalue expression that designates it is potentially evaluated and
either used as operand to the built-in unary &amp; operator [note 2] or
directly bound to a reference.</P>

<P>If a definition exists, it shall be at namespace scope and shall not
contain an initializer.</P>
</BLOCKQUOTE>

<P>In 9.4.2 [class.static.data] paragraph 5 change</P>
<BLOCKQUOTE>
There shall be exactly one definition of a static data member that is
used in a program; no diagnostic is required; see 3.2.
</BLOCKQUOTE>
<P>to</P>
<BLOCKQUOTE>
Except as allowed by 9.4.2 par. 4, there shall be exactly one
definition of a static data member that is potentially evaluated (3.2)
in a program; no diagnostic is required.
</BLOCKQUOTE>

<P>In 3.2 [basic.def.odr] paragraph 3 add, at the beginning:</P>
<BLOCKQUOTE>
Except for the omission allowed by 9.4.2, par. 4, ...
</BLOCKQUOTE>


<P>[note 1] Actually it shall be a "= followed by a constant-expression".
This could probably be an editorial fix, rather than a separate DR.</P>


<P>[note 2] Note that this is the case when reinterpret_cast-ing to a
reference, like in
<PRE>
struct X { static const int value = 0; };
const char &amp; c = reinterpret_cast&lt;const char&amp;&gt;(X::value);
</PRE>
 
See 5.2.10 [expr.reinterpret.cast]/10</P>

<P><I>More information, in response to a question about why
<A HREF="
     cwg_defects.html#48">issue 48</A> does not resolve the problem:</I></P>

<P>The problem is that the issue was settled in a way that solves much
less than it was supposed to solve; that's why I decided to file, so
to speak, a DR on a DR.</P>

<P>I understand this may seem a little 'audacious' on my part, but please
keep reading. Quoting from the text of DR 48 (emphasis mine):</P>
<BLOCKQUOTE>
 <P>
 Originally, all static data members still had to be defined
  outside the class whether they were used or not.</P>

  <P>But that restriction was supposed to be lifted [...]</P>

  <P>In particular, if an integral/enum const static data member is
  initialized within the class, <I>and its address is never taken</I>,
  we agreed that no namespace-scope definition was required.</P>
</BLOCKQUOTE>

<P>The corresponding resolution doesn't reflect this intent, with the
definition being still required in most situations anyway: it's enough
that the constant appears outside a place where constants are
<I>required</I> (ignoring the obvious cases of sizeof and typeid) and you
have to provide a definition. For instance:</P>
<PRE>
  struct X {
   static const int c = 1;
  };

  void f(int n)
  {
   if (n == X::c)   // &lt;-- potentially evaluated
    ...
  }
</PRE>

<P>&lt;start digression&gt;</P>

<P>Most usages of non-enum BOOST_STATIC_COSTANTs, for instance, are (or
were, last time I checked) non-conforming. If you recall, Paul
Mensonides pointed out that the following template</P>
<PRE>
// map_integral

template&lt;class T, T V&gt; struct map_integral : identity&lt;T&gt; {
  static const T value = V;
};

template&lt;class T, T V&gt; const T map_integral&lt;T, V&gt;::value;
</PRE>

<P>whose main goal is to map the same couples (type, value) to the same
storage, also solves the definition problem. In this usage it is an
excellent hack (if your compiler is good enough), but IMHO still a
hack on a language defect.</P>

<P>&lt;end digression&gt;</P>

<P>What I propose is to solve the issue according to the original intent,
which is also what users expect and all compilers that I know of
already do. Or, in practice, we would have a rule that exists only as
words in a standard document.</P>

<P>PS: I've sent a copy of this to Mr. Adamczyk to clarify an important
doubt that occurred to me while writing this reply:</P>

<P>if no definition is provided for an integral static const data member
is that member an object? Paragraph 1.8/1 seems to say no, and in fact
it's difficult to think it is an object without assuming/pretending
that a region of storage exists for it (an object *is* a region of
storage according to the standard).</P>

<P>I would think that when no definition is required we have to assume
that it could be a non-object. In that case there's nothing in 3.2
which says what 'used' means for such an entity and the current
wording would thus be defective. Also, since the name of the member is
an lvalue and 3.10/2 says an lvalue refers to an object we would have
another problem.</P>

<P>OTOH the standard could pretend it is always an object (though the
compiler can optimize it away) and in this case it should probably
make a special case for it in 3.2/2.</P>

<P><B>Notes from the March 2004 meeting:</B></P>

<P>We sort of like this proposal, but we don't feel it has very
high priority.  We're not going to spend time discussing it, but
if we get drafting for wording we'll review it.</P>

<P><B>Proposed resolution (October, 2005):</B></P>

<OL><LI><P>Change the first two sentences of 3.2 [basic.def.odr]
paragraph 2 from:</P>

<BLOCKQUOTE>

An expression is <I>potentially evaluated</I> unless it appears where
an integral constant expression is required (see 5.19 [expr.const]), is the operand of the <TT>sizeof</TT> operator
(5.3.3 [expr.sizeof]), or is the operand of
the <TT>typeid</TT> operator and the expression does not designate an
lvalue of polymorphic class type (5.2.8 [expr.typeid]). An
object or non-overloaded function is <I>used</I> if its name appears
in a potentially-evaluated expression.

</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>

An expression that is the operand of the <TT>sizeof</TT> operator
(5.3.3 [expr.sizeof]) is <I>unevaluated</I>, as is an
expression that is the operand of the <TT>typeid</TT> operator if it
is not an lvalue of a polymorphic class type (5.2.8 [expr.typeid]); all other expressions are <I>potentially
evaluated</I>. An object or non-overloaded function whose name appears
as a potentially-evaluated expression is <I>used</I>, unless it is an
object that satisfies the requirements for appearing in an integral
constant expression (5.19 [expr.const]) and the lvalue-to-rvalue
conversion (4.1 [conv.lval]) is immediately applied.

</BLOCKQUOTE>

</LI>

<LI><P>Change the first sentence of 9.4.2 [class.static.data]
paragraph 2 as indicated:</P></LI>

<BLOCKQUOTE>

If a static data member is of const integral or const enumeration
type, its declaration in the class definition can specify a
<I>constant-initializer</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">which</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">whose <I>constant-expression</I></SPAN>
shall be an integral constant expression (5.19 [expr.const]).

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="58"></A><H4>58.
  
Signedness of bit fields of enum type
</H4><B>Section: </B>9.6&#160; [class.bit]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>13 Oct 1998<BR>



<P>[Voted into WP at the October, 2006 meeting.]</P>

<P>Section 9.6 [class.bit]

paragraph 4 needs to be more specific about the signedness of bit
fields of enum type. How much leeway does an implementation have
in choosing the signedness of a bit field? In particular, does the
phrase "large enough to hold all the values of the enumeration" mean "the
implementation decides on the signedness, and then we see whether all the
values will fit in the bit field", or does it require the implementation
to make the bit field signed or unsigned if that's what it takes to make
it "large enough"?</P>

<P>(See also <A HREF="
     cwg_defects.html#172">issue 172</A>.)</P>



<P><B>Note (March, 2005):</B> Clark Nelson observed that there is
variation among implementations on this point.  </P>

<P><B>Notes from April, 2005 meeting:</B></P>

<P>Although implementations enjoy a great deal of latitude in handling
bit-fields, it was deemed more user-friendly to ensure that the
example in paragraph 4 will work by requiring implementations to use
an unsigned underlying type if the enumeration type has no negative
values.  (If the implementation is allowed to choose a signed
representation for such bit-fields, the comparison against
<TT>TRUE</TT> will be <TT>false</TT>.)</P>

<P>In addition, it was observed that there is an apparent circularity
between 7.2 [dcl.enum] paragraph 7 and 9.6 [class.bit] paragraph 4 that should be resolved.
</P>

<P><B>Proposed resolution (April, 2006):</B></P>

<OL>

<LI><P>Replace 7.2 [dcl.enum] paragraph 7, deleting the
embedded footnote 85, with the following:</P>

<BLOCKQUOTE>

For an enumeration where <I>e<SUB>min</SUB></I> is the smallest
enumerator and <I>e<SUB>max</SUB></I> is the largest, the values of
the enumeration are the values in the range <I>b<SUB>min</SUB></I> to
<I>b<SUB>max</SUB></I>, defined as follows: Let <I>K</I> be 1 for a
two's complement representation and 0 for a one's complement or
sign-magnitude representation.  <I>b<SUB>max</SUB></I> is the smallest
value greater than or equal to
max(|<I>e<SUB>min</SUB></I>|-<I>K</I>,|<I>e<SUB>max</SUB></I>|) and
equal to 2<I><SUP>M</SUP></I>-1, where <I>M</I> is a non-negative
integer.  <I>b<SUB>min</SUB></I> is zero if <I>e<SUB>min</SUB></I> is
non-negative and -(<I>b<SUB>max</SUB></I>+<I>K</I>) otherwise.  The
size of the smallest bit-field large enough to hold all the values of
the enumeration type is max(<I>M</I>,1) if <I>b<SUB>min</SUB></I> is
zero and <I>M</I>+1 otherwise.  It is possible to define an
enumeration that has values not defined by any of its enumerators.

</BLOCKQUOTE>
</LI>

<LI><P>Add the indicated text to the second sentence of
9.6 [class.bit] paragraph 4:</P>

<BLOCKQUOTE>

If the value of an enumerator is stored into a bit-field of the same
enumeration type and the number of bits in the bit-field is large
enough to hold all the values of that enumeration type
<SPAN style="font-weight:bold;background-color:#A0FFA0">(7.2 [dcl.enum])</SPAN>, the original enumerator value and
the value of the bit-field shall compare equal.

</BLOCKQUOTE>

</LI>
</OL>

<BR><BR><HR><A NAME="436"></A><H4>436.
  
Problem in example in 9.6 paragraph 4
</H4><B>Section: </B>9.6&#160; [class.bit]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Roberto Santos
 &#160;&#160;&#160;

 <B>Date: </B>10 October 2003<BR>


<P>[Voted into WP at October 2004 meeting.]</P>

<P>It looks like the example on 9.6 [class.bit]
paragraph 4 has both the enum and function
contributing the identifier "f" for the same scope.</P>
<PRE>
  enum BOOL { f=0, t=1 };
  struct A {
    BOOL b:1;
  };
  A a;
  void f() {
    a.b = t;
    if (a.b == t) // shall yield true
    { /* ... */ }
  }
</PRE>

<P><B>Proposed resolution:</B></P>

<P>Change the example at the end of 9.6 [class.bit]/4 from:</P>
<PRE>
  enum BOOL { f=0, t=1 };
  struct A {
    BOOL b:1;
  };
  A a;
  void f() {
    a.b = t;
    if (a.b == t) // shall yield true
    { /* ... */ }
  }

</PRE>
<P>To:</P>
<PRE>
  enum BOOL { FALSE=0, TRUE=1 };
  struct A {
    BOOL b:1;
  };
  A a;
  void f() {
    a.b = TRUE;
    if (a.b == TRUE) // shall yield true
    { /* ... */ }
  }

</PRE>

<BR><BR><HR><A NAME="198"></A><H4>198.
  
Definition of "use" in local and nested classes
</H4><B>Section: </B>9.8&#160; [class.local]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Erwin Unruh
 &#160;&#160;&#160;

 <B>Date: </B>27 Jan 2000<BR>



<P>[Voted into WP at April 2003 meeting.]</P>



<P>9.8 [class.local]
 paragraph 1 says,</P>

<BLOCKQUOTE>
Declarations in a local class can use only type names, static
variables, <TT>extern</TT> variables and functions, and enumerators
from the enclosing scope.
</BLOCKQUOTE>

The definition of when an object or function is "used" is found in
3.2 [basic.def.odr]
 paragraph 2 and
essentially says that the operands of <TT>sizeof</TT> and
non-polymorphic <TT>typeid</TT> operators are not used.  (The
resolution for <A HREF="
     cwg_defects.html#48">issue 48</A> will add
contexts in which integral constant expressions are required to the
list of non-uses.)

<P>This definition of "use" would presumably allow code like</P>

<PRE>
    void foo() {
        int i;
        struct S {
            int a[sizeof(i)];
        };
    };
</PRE>

which is required for C compatibility.

<P>However, the restrictions on nested classes in
9.7 [class.nest]
 paragraph 1 are very
similar to those for local classes, and the example there explicitly
states that a reference in a <TT>sizeof</TT> expression is a forbidden
use (abbreviated for exposition):</P>

<PRE>
    class enclose {
    public:
        int x;
        class inner {
            void f(int i)
            {
                int a = sizeof(x);  // <I>error: refers to </I>enclose::x
            }
        };
    };
</PRE>

<P>[As a personal note, I have seen real-world code that was exactly like
this; it was hard to persuade the author that the required
writearound, <TT>sizeof(((enclose*) 0)-&gt;x)</TT>, was an improvement
over <TT>sizeof(x)</TT>. <I>&#8212;wmm</I>]</P>

<P>Similarly, 9.2 [class.mem] paragraph 9 would appear to
prohibit examples like the following:</P>

<PRE>
    struct B {
        char x[10];
    };
    struct D: B {
        char y[sizeof(x)];
    };
</PRE>

<P><B>Suggested resolution:</B> Add cross-references to
3.2 [basic.def.odr]
 following the word
"use" in both 9.7 [class.nest]
 and
9.8 [class.local]
, and change the example
in 9.7 [class.nest]
 to indicate that a
reference in a <TT>sizeof</TT> expression is permitted.  In
9.2 [class.mem] paragraph 9, "referred to" should be
changed to "used" with a cross_reference to
3.2 [basic.def.odr].</P>

<P><B>Notes from 10/01 meeting:</B></P>

<P>It was noted that the suggested resolution did not make the
<TT>sizeof()</TT> example in 9.7 [class.nest] valid.
Although the reference to the argument of <TT>sizeof()</TT> is not regarded
as a use, the right syntax must be used nonetheless to reference a non-static
member from the enclosing class. The use of the member name by itself is not
valid. The consensus within the core working group was that nothing should be
done about this case. It was later discovered that
9.4 [class.static] paragraph 3 states that</P>
<BLOCKQUOTE>
<P>The
definition of a <TT>static</TT>
member shall not use directly the names of the nonstatic members of its class
or of a base class of its class (including as operands of the <TT>sizeof</TT>
operator). The definition of a <TT>static</TT> member may only refer to
these members to
form pointer to members (5.3.1 [expr.unary.op]) or
with the class member access syntax (5.2.5 [expr.ref]).</P>
</BLOCKQUOTE>

<P>This seems to
reinforce the decision of the working group.</P>

<P>The use of "use" should still be cross-referenced. The
statements in 9.7 [class.nest] and 9.8 [class.local]
should also be rewritten to state the requirement
positively rather than negatively as the list of "can't"s is already missing
some cases such as template parameters. </P>

<P><B>Notes from the 4/02 meeting:</B></P>

<P>We backed away from "use" in the technical sense, because the
requirements on the form of reference are the same whether or not
the reference occurs inside a <TT>sizeof</TT>.</P>

<P><B>Proposed Resolution (revised October 2002):</B></P>

<P>In 9.2 [class.mem] paragraph 9, replace </P>
<BLOCKQUOTE>
  <P>Except when used to form a pointer to member
(5.3.1 [expr.unary.op]), when used in the body of a
 nonstatic member function of 
  its class or of a class derived from its class
 (9.3.1 [class.mfct.non-static]), or when used in
 a <I>mem-initializer</I> for a 
  constructor for its class or for a class derived from its class
(12.6.2 [class.base.init]), a nonstatic data or function member
 of a class shall only be referred to with the class member access syntax
(5.2.5 [expr.ref]).</P>
</BLOCKQUOTE>
<P>with the following paragraph</P>
<BLOCKQUOTE>
  <P>Each occurrence in an expression of the name of a nonstatic data 
  member or nonstatic member function of a class shall be expressed as a class 
  member access (5.2.5 [expr.ref]), except when it appears
  in the formation of a pointer to member 
  (5.3.1 [expr.unary.op]), when it appears in the body
  of a nonstatic member function 
  of its class or of a class derived from its class
(9.3.1 [class.mfct.non-static]), or when it appears in a
<I>mem-initializer</I> for 
  a constructor for its class or for a class derived from its class
(12.6.2 [class.base.init]).</P>
</BLOCKQUOTE>
<P>In 9.7 [class.nest]
 paragraph 1, replace the last sentence,</P>
<BLOCKQUOTE>
  <P>Except by using explicit pointers, references, and object names, 
  declarations in a nested class can use only type names, static members, and 
  enumerators from the enclosing class.</P>
</BLOCKQUOTE>
<P>with the following</P>
<BLOCKQUOTE>
  <P>[Note: In accordance with 9.2 [class.mem],
  except by using explicit pointers, 
  references, and object names, declarations in a nested class shall not use
  nonstatic data members or nonstatic member functions from the 
  enclosing class. This restriction applies in all constructs including the 
  operands of the <TT>sizeof</TT> operator.]</P>
</BLOCKQUOTE>
<P>In the example following 9.7 [class.nest]
paragraph 1, change the comment on the first statement of 
function <TT>f</TT> to emphasize that <TT>sizeof(x)</TT> is an error. The 
example reads in full:</P>
<PRE>
  int x;
  int y;
  class enclose {
  public:
    int x;
    static int s;
    class inner {
      void f(int i)
      {
        int a = sizeof(x);  // <I>error: direct use of</I> <TT>enclose::x</TT> <I>even in sizeof</I>
        x = i;              // <I>error: assign to </I><TT>enclose::x</TT>
        s = i;              // <I>OK: assign to </I><TT>enclose::s</TT>
        ::x = i;            // <I>OK: assign to global</I> <TT>x</TT>
        y = i;              // <I>OK: assign to global</I> <TT>y</TT>
      }
      void g(enclose* p, int i)
      {
        p-&gt;x = i;        // <I>OK: assign to</I> <TT>enclose::x</TT>
      }
    };
  };
   
  inner* p = 0;             // <I>error:</I> <TT>inner</TT><I> not in scope</I>
</PRE>

<BR><BR><HR><A NAME="484"></A><H4>484.
  
Can a <I>base-specifier</I> name a cv-qualified class type?
</H4><B>Section: </B>10&#160; [class.derived]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Corden
 &#160;&#160;&#160;

 <B>Date: </B>21 Oct 2004<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>

<P><A HREF="
     cwg_defects.html#298">Issue 298</A>, recently approved,
affirms that cv-qualified class types can be used as
<I>nested-name-specifier</I>s.  Should the same be true for
<I>base-specifier</I>s?</P>

<P><B>Rationale (April, 2005):</B></P>

<P>The resolution of <A HREF="
     cwg_defects.html#298">issue 298</A> added
new text to 9.1 [class.name] paragraph 5 making it
clear that a typedef that names a cv-qualified class type is a
<I>class-name</I>.  Because the definition of <I>base-specifier</I>
simply refers to <I>class-name</I>, it is already the case that
cv-qualified class types are permitted as <I>base-specifier</I>s.</P>

<P><B>Additional notes (June, 2005):</B></P>

<P>It's not completely clear what it means to have a cv-qualified
type as a <I>base-specifier</I>.  The original proposed resolution
for <A HREF="
     cwg_defects.html#298">issue 298</A> said that &#8220;the
cv-qualifiers are ignored,&#8221; but that wording is not in the
resolution that was ultimately approved.</P>

<P>If the cv-qualifiers are <I>not</I> ignored, does that mean that
the base-class subobject should be treated as always similarly
cv-qualified, regardless of the cv-qualification of the derived-class
lvalue used to access the base-class subobject?  For instance:</P>

<PRE>
    typedef struct B {
        void f();
        void f() const;
        int i;
    } const CB;

    struct D: CB { };

    void g(D* dp) {
        dp-&gt;f();    // which B::f?
        dp-&gt;i = 3;  // permitted?
    }
</PRE>

<P><B>Proposed resolution (October, 2005):</B></P>

<OL><LI><P>Change 9.1 [class.name] paragraph 5 as indicated:</P></LI>

<BLOCKQUOTE>

A <I>typedef-name</I> (7.1.3 [dcl.typedef]) that names a
class type, or a cv-qualified version thereof, is also
a <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>class-name</I>, but</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>class-name</I>. If
a <I>typedef-name</I> that names a cv-qualified class type is used
where a <I>class-name</I> is required, the cv-qualifiers are ignored.
A <I>typedef-name</I></SPAN> shall not be used as the <I>identifier</I>
in a
<I>class-head</I>.

</BLOCKQUOTE>

<LI><P>Delete 7.1.3 [dcl.typedef] paragraph 8:</P></LI>

<BLOCKQUOTE>

<P>[<I>Note:</I> if the <I>typedef-name</I> is used where
a <I>class-name</I> (or <I>enum-name</I>) is required, the program is
ill-formed. For example,</P>

<PRE>
    typedef struct {
        S();     //<SPAN style="font-family:Times;font-style:italic"> error: requires a return type because </SPAN>S<SPAN style="font-family:Times;font-style:italic"> is</SPAN>
                  //<SPAN style="font-family:Times;font-style:italic"> an ordinary member function, not a constructor</SPAN>
    } S;
</PRE>

<P>&#8212;<I>end note</I>]</P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="39"></A><H4>39.
  
Conflicting ambiguity rules
</H4><B>Section: </B>10.2&#160; [class.member.lookup]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Neal M Gafter
 &#160;&#160;&#160;

 <B>Date: </B>20 Aug 1998<BR>



<P>[Voted into WP at April 2005 meeting.]</P>



<P>The ambiguity text in 10.2 [class.member.lookup]

may not say what we intended. It makes the
following example ill-formed:</P>
<PRE>
    struct A {
        int x(int);
    };
    struct B: A {
        using A::x;
        float x(float);
    };
    
    int f(B* b) {
        b-&gt;x(3);  // ambiguous
    }
</PRE>
This is a name lookup ambiguity because of 10.2 [class.member.lookup]
 paragraph 2:
<BLOCKQUOTE>... Each of these declarations that was introduced by a using-declaration
is considered to be from each sub-object of C that is of the type containing
the declaration designated by the using-declaration. If the resulting set
of declarations are not all from sub-objects of the same type, or the set
has a nonstatic member and includes members from distinct sub-objects,
there is an ambiguity and the program is ill-formed.</BLOCKQUOTE>
This contradicts the text and example in paragraph 12 of 7.3.3 [namespace.udecl]
.

<P><B>Proposed Resolution (10/00):</B></P>

<OL>

<LI><P>Replace the two cited sentences from 10.2 [class.member.lookup]
paragraph 2 with the following:</P>

<BLOCKQUOTE>

The resulting set of declarations shall all be from sub-objects
of the same type, or there shall be a set of declarations from
sub-objects of a single type that contains <I>using-declaration</I>s
for the declarations found in all other sub-object types.
Furthermore, for nonstatic members, the resulting set of
declarations shall all be from a single sub-object, or there shall
be a set of declarations from a single sub-object that contains
<I>using-declarations</I> for the declarations found in all other
sub-objects.  Otherwise, there is an ambiguity and the program is
ill-formed.

</BLOCKQUOTE>

</LI>

<LI><P>Replace the examples in 10.2 [class.member.lookup]
paragraph 3 with the following:</P>

<PRE>
    struct A {
        int x(int);
        static int y(int);
    };
    struct V {
        int z(int);
    };
    struct B: A, virtual V {
        using A::x;
        float x(float);
        using A::y;
        static float y(float);
        using V::z;
        float z(float);
    };
    struct C: B, A, virtual V {
    };

    void f(C* c) {
        c-&gt;x(3);    // ambiguous -- more than one sub-object A
        c-&gt;y(3);    // not ambiguous
        c-&gt;z(3);    // not ambiguous
    }
</PRE>

</LI>

</OL>

<P><B>Notes from 04/01 meeting:</B></P>

<P>The following example should be accepted but is rejected by
the wording above:</P>

<PRE>
    struct A { static void f(); };

    struct B1: virtual A {
        using A::f;
    };

    struct B2: virtual A {
        using A::f;
    };

    struct C: B1, B2 { };

    void g() {
        C::f();        // OK, calls A::f()
    }
</PRE>

<P><B>Notes from 10/01 meeting (Jason Merrill):</B></P>

<P>The example in the issues list:

<PRE>
    struct A {
        int x(int);
    };
    struct B: A {
        using A::x;
        float x(float);
    };
    
    int f(B* b) {
        b-&gt;x(3);  // ambiguous
    }
</PRE>

Is broken under the existing wording:

<BLOCKQUOTE>
... Each of these declarations that was introduced by a using-declaration
is considered to be from each sub-object of C that is of the type containing
the declaration designated by the using-declaration. If the resulting set
of declarations are not all from sub-objects of the same type, or the set
has a nonstatic member and includes members from distinct sub-objects,
there is an ambiguity and the program is ill-formed.</BLOCKQUOTE>

Since the two x's are considered to be "from" different objects, looking up
x produces a set including declarations "from" different objects, and the
program is ill-formed.  Clearly this is wrong.  The problem with the
existing wording is that it fails to consider lookup context.</P>

<P>The first proposed solution:

<BLOCKQUOTE>

The resulting set of declarations shall all be from sub-objects
of the same type, or there shall be a set of declarations from
sub-objects of a single type that contains <I>using-declaration</I>s
for the declarations found in all other sub-object types.
Furthermore, for nonstatic members, the resulting set of
declarations shall all be from a single sub-object, or there shall
be a set of declarations from a single sub-object that contains
<I>using-declarations</I> for the declarations found in all other
sub-objects.  Otherwise, there is an ambiguity and the program is
ill-formed.

</BLOCKQUOTE>

breaks this testcase:

<PRE>
    struct A { static void f(); };

    struct B1: virtual A {
        using A::f;
    };

    struct B2: virtual A {
        using A::f;
    };

    struct C: B1, B2 { };

    void g() {
        C::f();        // OK, calls A::f()
    }
</PRE>

because it considers the lookup context, but not the definition context;
under this definition of "from", the two declarations found are the
using-declarations, which are "from" B1 and B2.</P>

<P>The solution is to separate the notions of lookup and definition context.
I have taken an algorithmic approach to describing the strategy.</P>

<P>Incidentally, the earlier proposal allows one base to have a superset of
the declarations in another base; that was an extension, and my proposal
does not do that.  One algorithmic benefit of this limitation is to
simplify the case of a virtual base being hidden along one arm and not
another ("domination"); if we allowed supersets, we would need to remember
which subobjects had which declarations, while under the following
resolution we need only keep two lists, of subobjects and declarations.</P>

<P><B>Proposed resolution (October 2002):</B></P>

<P>Replace 10.2 [class.member.lookup] paragraph 2 with: </P>
<BLOCKQUOTE>
<P>The following steps define the result of name lookup for a member
name f in a class scope C. </P>

<P>The <I>lookup set</I> for f in C, called S(f,C), consists of two
component sets: the <I>declaration set</I>, a set of members named f; and
the <I>subobject set</I>, a set of subobjects where declarations of these
members (possibly including using-declarations) were found.  In the
declaration set, using-declarations are replaced by the members they
designate, and type declarations (including injected-class-names) are
replaced by the types they designate.  S(f,C) is calculated as
follows. </P>

<P>If C contains a declaration of the name f, the declaration set contains
every declaration of f in C (excluding bases), the subobject set contains C
itself, and calculation is complete. </P>

<P>Otherwise, S(f,C) is initially empty. If C has base classes, calculate
the lookup set for f in each direct base class subjobject B<SUB>i</SUB>,
and merge each such lookup set S(f,B<SUB>i</SUB>) in turn into S(f,C). </P>

<P>The following steps define the result of merging lookup set
S(f,B<SUB>i</SUB>) into the intermediate S(f,C): </P>

<UL>
<LI>If each of the subobject members of S(f,B<SUB>i</SUB>) is a base
class subobject of at least one of the subobject members of S(f,C), S(f,C)
is unchanged and the merge is complete.  Conversely, if each of the
subobject members of S(f,C) is a base class subobject of at least one of
the subobject members of S(f,B<SUB>i</SUB>), the new S(f,C) is a copy of
S(f,B<SUB>i</SUB>).</LI>

<LI>Otherwise, if the declaration sets of S(f,B<SUB>i</SUB>) and S(f,C)
differ, the merge is ambiguous: the new S(f,C) is a lookup set with an
invalid declaration set and the union of the subobject sets. In subsequent
merges, an invalid declaration set is considered different from any
other.</LI>

<LI>Otherwise, consider each declaration d in the set, where d is a
member of class A.  If d is a nonstatic member, compare the A base class
subobjects of the subobject members of S(f,B<SUB>i</SUB>) and
S(f,C).  If they do not match, the merge is ambiguous, as in the
previous step.  [<I>Note:</I> It is not necessary to remember which A subobject
each member comes from, since using-declarations don't disambiguate. ]
</LI>

<LI> Otherwise, the new S(f,C) is a lookup set with the shared
set of declarations and the union of the subobject sets.</LI>
</UL>

<P>The result of name lookup for f in C is the declaration set of
S(f,C).  If it is an invalid set, the program is ill-formed. </P>

<P>[<I>Example:</I>
<PRE>
    struct A { int x; };                    // S(x,A) = {{ A::x }, { A }}
    struct B { float x; };                  // S(x,B) = {{ B::x }, { B }}
    struct C: public A, public B { };       // S(x,C) = { invalid, { A in C, B in C }}
    struct D: public virtual C { };         // S(x,D) = S(x,C)
    struct E: public virtual C { char x; }; // S(x,E) = {{ E::x }, { E }}
    struct F: public D, public E { };       // S(x,F) = S(x,E)

    int main() {
      F f;
      f.x = 0;   // OK, lookup finds { E::x }
    }
</PRE>

S(x,F) is unambiguous because the A and B base subobjects of D are also
base subobjects of E, so S(x,D) is discarded in the first merge step. --<I>end
example</I>]
</P>
</BLOCKQUOTE>

<P> Turn 10.2 [class.member.lookup] paragraphs 5 and 6 into notes.</P>

<P><B>Notes from October 2003 meeting:</B></P>

<P>Mike Miller raised some new issues in N1543, and we adjusted the
proposed resolution as indicated in that paper.</P>

<P><B>Further information from Mike Miller (January 2004):</B></P>

<P>Unfortunately, I've become aware of a minor glitch in
the proposed resolution for issue 39 in N1543, so I'd like to
suggest a change that we can discuss in Sydney.</P>

<P>A brief review and background of the problem: the major change we
agreed on in Kona was to remove detection of multiple-subobject
ambiguity from class lookup (10.2 [class.member.lookup]) and instead
handle it as part
of the class member access expression.  It was pointed out in
Kona that 11.2 [class.access.base]/5 has this effect:</P>
<BLOCKQUOTE>
    If a class member access operator, including an implicit
    "this-&gt;," is used to access a nonstatic data member or
    nonstatic member function, the reference is ill-formed if the
    left operand (considered as a pointer in the "." operator
    case) cannot be implicitly converted to a pointer to the
    naming class of the right operand.
</BLOCKQUOTE>
<P>After the meeting, however, I realized that this requirement is
not sufficient to handle all the cases.  Consider, for instance,</P>
<PRE>
    struct B {
        int i;
    };

    struct I1: B { };
    struct I2: B { };

    struct D: I1, I2 {
        void f() {
            i = 0;    // not ill-formed per 11.2p5
        }
    };
</PRE>
<P>Here, both the object expression ("this") and the naming class
are "D", so the reference to "i" satisfies the requirement in
11.2 [class.access.base]/5, even though it involves a
multiple-subobject ambiguity.</P>

<P>In order to address this problem, I proposed in N1543 to add a
paragraph following 5.2.5 [expr.ref]/4:</P>
<BLOCKQUOTE>
    If E2 is a non-static data member or a non-static member
    function, the program is ill-formed if the class of E1 cannot
    be unambiguously converted (10.2) to the class of which E2 is
    directly a member.
</BLOCKQUOTE>
<P>That's not quite right.  It does diagnose the case above as
written; however, it breaks the case where qualification is used
to circumvent the ambiguity:</P>
<PRE>
    struct D2: I1, I2 {
        void f() {
            I2::i = 0;    // ill-formed per proposal
        }
    };
</PRE>
<P>In my proposed wording, the class of "this" can't be converted to
"B" (the qualifier is ignored), so the access is ill-formed.
Oops.</P>

<P>I think the following is a correct formulation, so the proposed
resolution we discuss in Sydney should contain the following
paragraph instead of the one in N1543:</P>
<BLOCKQUOTE>
    If E2 is a nonstatic data member or a non-static member
    function, the program is ill-formed if <SPAN style="font-weight:bold;background-color:#A0FFA0">the naming class
    (11.2) of E2</SPAN> cannot be unambiguously converted (10.2) to
    the class of which E2 is directly a member.
</BLOCKQUOTE>
<P>This reformulation also has the advantage of pointing readers to
11.2 [class.access.base], where the the convertibility requirement
from the class of
E1 to the naming class is located and which might otherwise be
overlooked.</P>

<P><B>Notes from the March 2004 meeting:</B></P>

<P>We discussed this further and agreed with these latest
recommendations.  Mike Miller has produced a paper N1626 that gives
just the final collected set of changes.</P>

<P>(This resolution also resolves <A HREF="
     cwg_defects.html#306">isssue 306</A>.)</P>

<BR><BR><HR><A NAME="306"></A><H4>306.
  
Ambiguity by class name injection
</H4><B>Section: </B>10.2&#160; [class.member.lookup]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Clark Nelson
 &#160;&#160;&#160;

 <B>Date: </B>19 Jul 2001<BR>


<P>[Voted into WP at April 2005 meeting.]</P>

<P>Is the following well-formed?
<PRE>
    struct A {
        struct B { };
    };
    struct C : public A, public A::B {
        B *p;
    };
</PRE>
The lookup of <TT>B</TT> finds both the struct <TT>B</TT> in <TT>A</TT>
and the injected <TT>B</TT> from the <TT>A::B</TT> base class.
Are they the same thing?  Does the standard say so?</P>

<P>What if a struct is found along one path and a typedef to that
struct is found along another path?  That should probably be valid,
but does the standard say so?</P>

<P>This is resolved by <A HREF="
     cwg_defects.html#39">issue 39</A></P>

<P>February 2004: Moved back to "Review" status because
<A HREF="
     cwg_defects.html#39">issue 39</A> was moved back to "Review".</P>
<BR><BR><HR><A NAME="390"></A><H4>390.
  
Pure virtual must be defined when implicitly called
</H4><B>Section: </B>10.4&#160; [class.abstract]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Frey
 &#160;&#160;&#160;

 <B>Date: </B>14 Nov 2002<BR>


<P>[Voted into WP at March 2004 meeting.]</P>

<P>In clause 10.4 [class.abstract] paragraph 2, it reads:</P>
<BLOCKQUOTE>
A pure virtual function need be defined only if explicitly called with
the qualified-id syntax (5.1.1 [expr.prim.general]).
</BLOCKQUOTE>

<P>This is IMHO incomplete. A dtor is a function (well, a "special member
function", but this also makes it a function, right?) but it is called
implicitly and thus without a qualified-id syntax. Another alternative
is that the pure virtual function is called directly or indirectly from
the ctor. Thus the above sentence which specifies when a pure virtual
function need be defined ("...only if...") needs to be extended:</P>
<BLOCKQUOTE>
A pure virtual function need be defined only if explicitly called with
the qualified-id syntax (5.1.1 [expr.prim.general]) or if implicitly
called (12.4 [class.dtor] or 12.7 [class.cdtor]).
</BLOCKQUOTE>

<P><B>Proposed resolution:</B></P>

<P>Change 10.4 [class.abstract] paragraph 2 from</P>
<BLOCKQUOTE>
A pure virtual function need be defined only if explicitly called
with the <I>qualified-id</I> syntax (5.1.1 [expr.prim.general]).
</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>
A pure virtual function need be defined only if
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">explicitly</SPAN> called with<SPAN style="font-weight:bold;background-color:#A0FFA0">, or as if with
(12.4 [class.dtor]),</SPAN>
the <I>qualified-id</I> syntax (5.1.1 [expr.prim.general]).
</BLOCKQUOTE>

<P>Note: 12.4 [class.dtor] paragraph 6 defines the "as if"
cited.</P>

<BR><BR><HR><A NAME="8"></A><H4>8.
  
Access to template arguments used in a function return type and in the nested name specifier
</H4><B>Section: </B>11&#160; [class.access]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Ball
 &#160;&#160;&#160;

 <B>Date: </B>unknown<BR>



<P>[Moved to DR at 4/01 meeting.]</P>



<P>Consider the following example:</P>
<PRE>
    class A {
       class A1{};
       static void func(A1, int);
       static void func(float, int);
       static const int garbconst = 3;
     public:
       template &lt; class T, int i, void (*f)(T, int) &gt; class int_temp {};
       template&lt;&gt; class int_temp&lt;A1, 5, func&gt; { void func1() };
       friend int_temp&lt;A1, 5, func&gt;::func1();
       int_temp&lt;A1, 5, func&gt;* func2();
   };
   A::int_temp&lt;A::A1, A::garbconst + 2, &amp;A::func&gt;* A::func2() {...}
</PRE>
<B><U>ISSUE 1:</U></B>

<P>In 11 [class.access]
 paragraph 5 we have:
<UL>All access controls in clause 11 affect the ability to access a class
member name from a particular scope... In particular, access controls
apply as usual to member names accessed as part of a function return type,
even though it is not possible to determine the access privileges of that
use without first parsing the rest of the function declarator.</UL>
This means, if we take the loosest possible definition of "access from
a particular scope", that we have to save and check later the following
names</P>
<PRE>
      A::int_temp
      A::A1
      A::garbconst (part of an expression)
      A::func (after overloading is done)
</PRE>
I suspect that member templates were not really considered when this was
written, and that it might have been written rather differently if they
had been. Note that access to the template arguments is only legal because
the class has been declared a friend, which is probably not what most programmers
would expect.

<P><B>Rationale:</B></P>

<P>Not a defect. This behavior is as intended.</P>

<P><B><U>ISSUE 2:</U></B></P>

<P>Now consider <TT>void A::int_temp&lt;A::A1, A::garbconst + 2, &amp;A::func&gt;::func1()
{...}</TT> By my reading of 11.7 [class.access.nest]
, the references to
<TT>A::A1</TT>, <TT>A::garbconst</TT> and <TT>A::func</TT> are now illegal,
and there is no way to define this function outside of the class. Is there
any need to do anything about either of these Issues?</P>

<P><B>Proposed resolution (04/01):</B></P>

<P>The resolution for this issue is contained in the resolution
for <A HREF="
     cwg_defects.html#45">issue 45</A>.</P>
<BR><BR><HR><A NAME="494"></A><H4>494.
  
Problems with the resolution of issue 45
</H4><B>Section: </B>11&#160; [class.access]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Lloyd J. Lewins
 &#160;&#160;&#160;

 <B>Date: </B>17 Dec 2004<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>

<P>The proposed resolution for <A HREF="
     cwg_defects.html#45">issue 45</A> inserts the following sentence after 11 [class.access] paragraph 1:</P>

<BLOCKQUOTE>
A member of a class can also access all names as the class of
which it is a member.
</BLOCKQUOTE>

<P>I don't think that this is correctly constructed English. I see two
possibilities:</P>

<OL>
<LI><P>
This is a typo, and the correct change is:

<BLOCKQUOTE>
A member of a class can also access all names of the class of which
it is a member.
</BLOCKQUOTE></P></LI>

<LI><P>
The intent is something more like:

<BLOCKQUOTE>
A member of a nested class can also access all names accessible by
any other member of the class of which it is a member.
</BLOCKQUOTE></P></LI>
</OL>

<P>[Note: this was editorially corrected at the time defect
resolutions were being incorporated into the Working Paper to
read, &#8220;...can also access all the names declared in the
class of which it is a member,&#8221; which is essentially the
same as the preceding option 1.]</P>

<P>I would prefer to use the language proposed for 11.7 [class.access.nest]:</P>

<BLOCKQUOTE>
A nested class is a member and as such has the same access rights
as any other member.
</BLOCKQUOTE>

<P>A second problem is with the text in 11.3 [class.friend] paragraph 2:</P>

<BLOCKQUOTE>

[<I>Note:</I> this means that access to private and protected
names is also granted to member functions of the friend class (as
if the functions were each friends) and to the static data member
definitions of the friend class. This also means that private and
protected type names from the class granting friendship can be
used in the <I>base-clause</I> of a nested class of the friend
class. However, the declarations of members of classes nested
within the friend class cannot access the names of private and
protected members from the class granting friendship. Also,
because the <I>base-clause</I> of the friend class is not part of
its member declarations, the <I>base-clause</I> of the friend
class cannot access the names of the private and protected
members from the class granting friendship. For example,

<PRE>
    class A {
        class B { };
        friend class X;
    };
    class X : A::B {     //<SPAN style="font-family:Times;font-style:italic"> ill-formed: </SPAN>A::B<SPAN style="font-family:Times;font-style:italic"> cannot be accessed</SPAN>
                         //<SPAN style="font-family:Times;font-style:italic"> in the base-clause for </SPAN>X
        A::B mx;         //<SPAN style="font-family:Times;font-style:italic"> OK: </SPAN>A::B<SPAN style="font-family:Times;font-style:italic"> used to declare member of </SPAN>X
        class Y: A::B {  //<SPAN style="font-family:Times;font-style:italic"> OK: </SPAN>A::B<SPAN style="font-family:Times;font-style:italic"> used to declare member of </SPAN>X
            A::B my;     //<SPAN style="font-family:Times;font-style:italic"> ill-formed: </SPAN>A::B<SPAN style="font-family:Times;font-style:italic"> cannot be accessed</SPAN>
                         //<SPAN style="font-family:Times;font-style:italic"> to declare members of nested class of </SPAN>X
        };
    };
</PRE>
&#8212;<I>end note</I>]

</BLOCKQUOTE>

<P>
This seems to be an oversight. The proposed change to
11.7 [class.access.nest] paragraph 1 would appear to have
eliminated the restrictions on nested class access.  However, at
least one compiler (gcc 3.4.3) doesn't appear to take my view,
and continues with the restrictions on access by classes within a
friend class, while implementing the rest of the resolution of
<A HREF="
     cwg_defects.html#45">issue 45</A>.
</P>

<P><B>Note (March, 2005):</B></P>



<P><U>Andreas Hommel</U>: I think <A HREF="
     cwg_defects.html#45">issue 45</A>
requires an additional change in 9.7 [class.nest] paragraph
4:</P>

<BLOCKQUOTE>

Like a member function, a friend function (11.3 [class.friend])
defined within a nested class is in the lexical scope of that class;
it obeys the same rules for name binding as a static member function
of that class (9.4 [class.static]) and has no special access
rights to members of an enclosing class.

</BLOCKQUOTE>

<P>I believe the &#8220;no special access rights&#8221;
language should be removed.</P>

<P><B>Proposed resolution (October, 2005):</B></P>

<P>This issue is resolved by the resolution of <A HREF="
     cwg_defects.html#372">issue 372</A>.</P>

<BR><BR><HR><A NAME="9"></A><H4>9.
  
Clarification of access to base class members
</H4><B>Section: </B>11.2&#160; [class.access.base]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>unknown
 &#160;&#160;&#160;

 <B>Date: </B>unknown<BR>



<P>[Moved to DR at 4/01 meeting.]</P>



<P>11.2 [class.access.base]
 paragraph 4 says:</P>
<BLOCKQUOTE>A base class is said to be accessible if an invented public
member of the base class is accessible. If a base class is accessible,
one can implicitly convert a pointer to a derived class to a pointer to
that base class.</BLOCKQUOTE>
Given the above, is the following well-formed?
<PRE>
    class D;
     
    class B
    {
     protected:
       int b1;
 
       friend void foo( D* pd );
    };
     
    class D : protected B { };
     
    void foo( D* pd )
    {
       if ( pd-&gt;b1 &gt; 0 ); // Is 'b1' accessible?
    }
</PRE>
Can you access the protected member <TT>b1</TT> of <TT>B</TT> in <TT>foo</TT>?
Can you convert a <TT>D*</TT> to a <TT>B*</TT> in <TT>foo</TT>?

<P><U>1st interpretation:</U></P>

<P>A public member of <TT>B</TT> is accessible within <TT>foo</TT> (since
<TT>foo</TT> is a friend), therefore <TT>foo</TT> can refer to <TT>b1</TT> and convert
a <TT>D*</TT> to a <TT>B*</TT>.</P>

<P><U>2nd interpretation:</U></P>

<P><TT>B</TT> is a protected base class of <TT>D</TT>, and a public member of <TT>B</TT>
is a protected member of <TT>D</TT> and can only be accessed within members
of <TT>D</TT> and friends of <TT>D</TT>. Therefore <TT>foo</TT> cannot refer to
<TT>b1</TT> and cannot convert a <TT>D*</TT> to a <TT>B*</TT>.</P>

<P>(See J16/99-0042 = WG21 N1218.)</P>

<P><B>Proposed Resolution (04/01):</B></P>
<OL>
<LI>
Add preceding 11.2 [class.access.base]

paragraph 4:

<BLOCKQUOTE>
A base class <TT>B</TT> of <TT>N</TT> is <I>accessible</I> at <I>R</I>,
if
<UL>
<LI>
an invented public member of <TT>B</TT> would be a public member
of <TT>N</TT>, or</LI>
<LI>
<I>R</I> occurs in a member or friend of class <TT>N</TT>, and an
invented public member of <TT>B</TT> would be a private or protected
member of <TT>N</TT>, or</LI>
<LI>
<I>R</I> occurs in a member or friend of a class <TT>P</TT> derived
from <TT>N</TT>, and an invented public member of <TT>B</TT> would be
a private or protected member of <TT>P</TT>, or</LI>
<LI>
there exists a class <TT>S</TT> such that <TT>B</TT> is a base class
of <TT>S</TT> accessible at <I>R</I> and <TT>S</TT> is a base class
of <TT>N</TT> accessible at <I>R</I>. [<I>Example:</I>
<PRE>
    class B {
    public:
        int m;
    };

    class S: private B {
        friend class N;
    };

    class N: private S {
        void f() {
	    B* p = this;  // <I>OK because class S satisfies the</I>
			// <I>fourth condition above: B is a base</I>
			// <I>class of N accessible in f() because</I>
			// <I>B is an accessible base class of S</I>
			// <I>and S is an accessible base class of N.</I>
        }
    };
</PRE>
&#8212;<I>end example</I>]
</LI>
</UL>
</BLOCKQUOTE>
</LI>
<LI>
Delete the first sentence of
11.2 [class.access.base]
 paragraph 4:
<BLOCKQUOTE>
A base class is said to be accessible if an invented public member
of the base class is accessible.
</BLOCKQUOTE></LI>
<LI>
Replace the last sentence ("A member <I>m</I> is accessible...")
by the following:
<BLOCKQUOTE>
A member <TT>m</TT> is accessible at the point <I>R</I> when
named in class <TT>N</TT> if
<UL>
<LI>
<TT>m</TT> as a member of <TT>N</TT> is public, or</LI>
<LI>
<TT>m</TT> as a member of <TT>N</TT> is private, and <I>R</I>
occurs in a member or friend of class <TT>N</TT>, or</LI>
<LI>
<TT>m</TT> as a member of <TT>N</TT> is protected, and <I>R</I>
occurs in a member or friend of class <TT>N</TT>, or in a member
or friend of a class <TT>P</TT> derived from <TT>N</TT>, where
<TT>m</TT> as a member of <TT>P</TT> is private or protected, or</LI>
<LI>
there exists a base class <TT>B</TT> of <TT>N</TT> that is
accessible at <I>R</I>, and <TT>m</TT> is accessible at <I>R</I>
when named in class <TT>B</TT>. [<I>Example:</I>...
</LI>
</UL>
</BLOCKQUOTE>
</LI>
</OL>

<P>The resolution for <A HREF="
     cwg_defects.html#207">issue 207</A> modifies
this wording slightly.</P>

<BR><BR><HR><A NAME="16"></A><H4>16.
  
Access to members of indirect private base classes
</H4><B>Section: </B>11.2&#160; [class.access.base]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>unknown
 &#160;&#160;&#160;

 <B>Date: </B>unknown<BR>



<P>[Moved to DR at 4/01 meeting.]</P>



<P>The text in 11.2 [class.access.base]

paragraph 4 does not seem to handle the following cases:</P>
<PRE>
    class D;
     
    class B {
    private:
        int i;
        friend class D;
    };
     
    class C : private B { };
     
    class D : private C {
        void f() {
            B::i; //1: well-formed?
            i;    //2: well-formed?
        }
    };
</PRE>
The member <TT>i</TT> is not a member of <TT>D</TT> and cannot be
accessed in the
scope of <TT>D</TT>. What is the naming class of the member
<TT>i</TT> on line <TT>//1</TT>
and <TT>line //2</TT>?

<P><B>Proposed Resolution (04/01):</B> The resolution for this issue
is contained in the resolution for <A HREF="
     cwg_defects.html#9">issue 9</A>..</P>
<BR><BR><HR><A NAME="207"></A><H4>207.
  
<I>using-declaration</I>s and protected access
</H4><B>Section: </B>11.2&#160; [class.access.base]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>28 Feb 2000<BR>


<P>[Moved to DR at 10/01 meeting.]</P>



<P>Consider the following example:</P>

<PRE>
  class A {
  protected:
    static void f() {};
  };

  class B : A {
  public:
    using A::f;
    void g() {
      A::f();
    }
  };
</PRE>

<P>The standard says in 11.2 [class.access.base] paragraph 4 that
the call to <TT>A::f</TT> is ill-formed:</P>

<BLOCKQUOTE>
A member <I>m</I> is accessible when named in class <I>N</I> if

<UL>
<LI><I>m</I> as a member of <I>N</I> is public, or</LI>

<LI><I>m</I> as a member of <I>N</I> is private, and the reference
occurs in a member or friend of class <I>N</I>, or</LI>

<LI><I>m</I> as a member of <I>N</I> is protected, and the reference
occurs in a member or friend of class <I>N</I>, or in a member or
friend of a class <I>P</I> derived from <I>N</I>, where <I>m</I> as a
member of <I>P</I> is private or protected, or</LI>

<LI>there exists a base class <I>B</I> of <I>N</I> that is accessible
at the point of reference, and <I>m</I> is accessible when named in
class <I>B</I>.</LI>

</UL>
</BLOCKQUOTE>

<P>Here, <I>m</I> is <TT>A::f</TT> and <I>N</I> is <TT>A</TT>.</P>

<UL>
<LI><TT>f</TT> as a member of <TT>A</TT> is public?  <B>No</B>.</LI>

<LI><TT>f</TT> as a member of <TT>A</TT> is private? <B>No</B>.</LI>

<LI><TT>f</TT> as a member of <TT>A</TT> is protected?
<B>Yes</B>.</LI>

<UL>
<LI>reference in a member or friend of <TT>A</TT>? <B>No</B>.</LI>

<LI>reference in a member or friend of a class derived from
<TT>A</TT>? <B>Yes</B>, <TT>B</TT>.</LI>

<UL>
<LI><TT>f</TT> as a member of <TT>B</TT> private or protected?
<B>No</B>, public.</LI>

</UL>
</UL>

<LI>base of <TT>A</TT> accessible at point of reference? <B>No</B>.</LI>
</UL>

<P>It seems clear to me that the third bullet should say "public,
private or protected".</P>

<P><U>Steve Adamczyk</U>:The words were written before
<I>using-declaration</I>s existed, and therefore didn't anticipate
this case.
</P>

<P><B>Proposed resolution (04/01):</B></P>

<P>Modify  the third bullet of the third change ("A member <I>m</I>
is accessible...") in the resolution
of <A HREF="
     cwg_defects.html#9">issue 9</A> to read "public, private,
or protected" instead of "private or protected."</P>

<BR><BR><HR><A NAME="77"></A><H4>77.
  
The definition of friend does not allow nested classes to be friends
</H4><B>Section: </B>11.3&#160; [class.friend]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Judy Ward
 &#160;&#160;&#160;

 <B>Date: </B>15 Dec 1998<BR>



<P>[Moved to DR at 4/02 meeting.]</P>

<P>The definition of "friend" in
11.3 [class.friend]

says:</P>
<BLOCKQUOTE>A friend of a class is a function or class that is not a member
of the class but is permitted to use the private and protected member names
from the class. ...</BLOCKQUOTE>
A nested class, i.e. INNER in the example below, is a member of class OUTER.
The sentence above states that it cannot be a friend. I think this is a
mistake.
<PRE>
    class OUTER {
        class INNER;
        friend class INNER;
        class INNER {};
    };
</PRE>

<P><B>Proposed resolution (04/01):</B></P>

<P>Change the first sentence of 11.3 [class.friend]
as follows:</P>

<BLOCKQUOTE>

A friend of a class is a function or class that is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">not a
member of the class but is allowed</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">given permission</SPAN>
to use the private and protected member names from the class.
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The name of a friend is not in the scope of the class, and
the friend is not called with the member access operators
(5.2.5 [expr.ref]) unless it is a member of
another class.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">A class specifies its friends, if any,
by way of friend declarations.  Such declarations give special
access rights to the friends, but they do not make the nominated
friends members of the befriending class.</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="500"></A><H4>500.
  
Access in <I>base-specifier</I>s of friend and nested classes
</H4><B>Section: </B>11.3&#160; [class.friend]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Andreas Hommel
 &#160;&#160;&#160;

 <B>Date: </B>25 Jan 2005<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>



<P>I don't know the reason for this distinction, but it seems to be
surprising that <TT>Base::A</TT> is legal and <TT>D</TT> is illegal in
this example:
</P>

<PRE>
    class D;
    class Base 
    { 
        class A;
        class B;
        friend class D;
    }; 
    class Base::B 
    {
    };
    class Base::A : public Base::B  // OK because of issue 45
    { 
    };
    class D : public Base::B        // illegal because of 11.4p4
    { 
    };
</PRE>

<P>Shouldn't this be consistent (either way)?</P>

<P><B>Notes from the April, 2005 meeting:</B></P>

<P>In discussing <A HREF="
     cwg_defects.html#372">issue 372</A>, the CWG decided
that access in the <I>base-specifier</I>s of a class should be the
same as for its members, and that resolution will apply
to <TT>friend</TT> declarations, as well.</P>

<P><B>Proposed resolution (October, 2005):</B></P>

<P>This issue is resolved by the resolution of <A HREF="
     cwg_defects.html#372">issue 372</A>.</P>

<BR><BR><HR><A NAME="385"></A><H4>385.
  
How does protected member check of 11.5 interact with using-declarations?
</H4><B>Section: </B>11.4&#160; [class.protected]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Vincent Korstanje
 &#160;&#160;&#160;

 <B>Date: </B>24 Sep 2002<BR>


<P>[Voted into WP at October 2004 meeting.]</P>

<P>We consider it not unreasonable to do the following </P>
<PRE>
  class A { 
    protected: 
    void g();
  }; 
  class B : public A { 
    public: 
      using A::g; // B::g is a public synonym for A::g 
  }; 

  class C: public A {
    void foo();
  };

  void C::foo() { 
    B b; 
    b.g(); 
  } 
</PRE>
<P>However the EDG front-end does not like and gives the error</P>
<PRE>
  #410-D: protected function "A::g" is not accessible through a "B" pointer or  object 
    b.g();
      ^
</PRE>

<P><U>Steve Adamczyk</U>:
The error in this case is due to
11.4 [class.protected] of the standard, which is an additional
check on top of the other access checking.  When that section says
"a protected nonstatic member function ... of a base class" it doesn't
indicate whether the fact that there is a using-declaration is relevant.
I'd say the current wording taken at face value would suggest that
the error is correct -- the function is protected, even if the
using-declaration for it makes it accessible as a public function.
But I'm quite sure the wording in
11.4 [class.protected] was written before using-declarations
were invented and has not been reviewed since for consistency with
that addition.</P>

<P><B>Notes from April 2003 meeting:</B></P>

<P>We agreed that the example should be allowed.</P>

<P><B>Proposed resolution (April 2003, revised October 2003):</B></P>

<P>Change 11.4 [class.protected] paragraph 1 from</P>

<BLOCKQUOTE>
When a friend or a member function of a derived class references a
protected nonstatic member function or protected nonstatic data member
of a base class, an access check applies in addition to those
described earlier in clause 11 [class.access].
[Footnote: This
additional check does not apply to other members, <I>e.g. </I>static
data members or enumerator member constants.] Except
when forming a pointer to member (5.3.1 [expr.unary.op]),
the access must be through a
pointer to, reference to, or object of the derived class itself (or
any class derived from that class (5.2.5 [expr.ref]).
If the access is to form a
pointer to member, the <I>nested-name-specifier</I> shall name the
derived class (or any class derived from that class).
</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>
An additional access check beyond those described earlier in
clause 11 [class.access]
is applied when a nonstatic data member or nonstatic member
function is a protected member of its naming class
(11.2 [class.access.base]).
[Footnote: This additional check does not apply
to other members, e.g., static data members or enumerator member
constants.] As described 
earlier, access to a protected member is granted because the 
reference occurs in a friend or member of some
class <TT>C</TT>.  If the access is to form a pointer to member
(5.3.1 [expr.unary.op]), the
<I>nested-name-specifier</I> shall name <TT>C</TT> or a
class derived from <TT>C</TT>.  All other accesses involve a
(possibly implicit) object expression (5.2.5 [expr.ref]).
In this case, the
class of the object expression shall be <TT>C</TT> or a class derived
from <TT>C</TT>.
</BLOCKQUOTE>

<P><B>Additional discussion (September, 2004):</B></P>

<P><U>Steve Adamczyk:</U> I wonder if this wording is incorrect.  Consider:</P>

<PRE>
    class A {
    public:
      int p;
    };
    class B : protected A {
      // p is a protected member of B
    };
    class C : public B {
      friend void fr();
    };
    void fr() {
      B *pb = new B;
      pb-&gt;p = 1;  // Access okay?  Naming class is B, p is a protected member of B,
                  // the "C" of the issue 385 wording is C, but access is not via
                  // an object of type C or a derived class thereof.
    }
</PRE>

<P>I think the formulation that the member is a protected member
of its naming class is not what we want.  I think we intended
that the member is protected in the declaration that is found,
where the declaration found might be a <I>using-declaration</I>.
</P>

<P><U>Mike Miller:</U> I think the proposed wording makes the
access <TT>pb-&gt;p</TT> ill-formed, and I think that's the right
thing to do.</P>

<P>First, protected inheritance of <TT>A</TT> by <TT>B</TT> means
that <TT>B</TT> intends the public and protected members of
<TT>A</TT> to be part of <TT>B</TT>'s implementation, available
to <TT>B</TT>'s descendants only.  (That's why there's a
restriction on converting from <TT>B*</TT> to <TT>A*</TT>, to
enforce <TT>B</TT>'s intention on the use of members of
<TT>A</TT>.)  Consequently, I see no difference in access policy
between your example and</P>

<PRE>
    class B {
    protected:
        int p;
    };
</PRE>

<P>Second, the reason we have this rule is that <TT>C</TT>'s use
of inherited protected members might be different from their use
in a sibling class, say <TT>D</TT>.  Thus members and friends of
<TT>C</TT> can only use <TT>B::p</TT> in a manner consistent with
<TT>C</TT>'s usage, i.e., in <TT>C</TT> or
derived-from-<TT>C</TT> objects.  If we rewrote your example
slightly,</P>

<PRE>
    class D: public B { };

    void fr(B* pb) {
        pb-&gt;p = 1;
    }

    void g() {
        fr(new D);
    }
</PRE>

<P>it's clear that the intent of this rule is broken &#8212;
<TT>fr</TT> would be accessing <TT>B::p</TT> assuming
<TT>C</TT>'s policies when the object in question actually
required <TT>D</TT>'s policies.</P>

<P>(See also issues <A HREF="
     cwg_closed.html#471">471</A> and <A HREF="
     cwg_active.html#472">472</A>.)</P>

<BR><BR><HR><A NAME="10"></A><H4>10.
  
Can a nested class access its own class name as a qualified name if it is a private member of the enclosing class?
</H4><B>Section: </B>11.7&#160; [class.access.nest]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Josee Lajoie
 &#160;&#160;&#160;

 <B>Date: </B>unknown<BR>



<P>[Moved to DR at 4/01 meeting.]</P>



<P>Paragraph 1 says: "The members of a nested class have no special access
to members of an enclosing class..."</P>

<P>This prevents a member of a nested class from being defined outside
of its class definition. i.e. Should the following be well-formed?</P>
<PRE>
    class D {
        class E {
            static E* m;
        };
    };
     
    D::E* D::E::m = 1; // ill-formed
</PRE>
This is because the nested class does not have access to the member <TT>E</TT>
in <TT>D</TT>. 11 [class.access]

paragraph 5 says that access to <TT>D::E</TT> is checked with
member access to class <TT>E</TT>, but unfortunately that doesn't give
access to <TT>D::E</TT>. 11 [class.access]

paragraph 6 covers the access for <TT>D::E::m</TT>,
but it doesn't affect the <TT>D::E</TT> access. Are there any implementations
that are standard compliant that support this?

<P>Here is another example:</P>
<PRE>
    class C {
        class B
        {
            C::B *t; //2 error, C::B is inaccessible
        };
    };
</PRE>
This causes trouble for member functions declared outside of the class
member list. For example:
<PRE>
    class C {
        class B
        {
            B&amp; operator= (const B&amp;);
        };
    };
     
    C::B&amp; C::B::operator= (const B&amp;) { } //3
</PRE>
If the return type (i.e. <TT>C::B</TT>) is access checked in the scope
of class <TT>B</TT> (as implied by
11 [class.access]
 paragraph 5)
as a qualified name, then
the return type is an error just like referring to <TT>C::B</TT> in the
member list of class <TT>B</TT> above (i.e. //2) is ill-formed.

<P><B>Proposed resolution (04/01):</B></P>

<P>The resolution for this issue is incorporated into the
resolution for <A HREF="
     cwg_defects.html#45">issue 45</A>.</P>
<BR><BR><HR><A NAME="45"></A><H4>45.
  
Access to nested classes
</H4><B>Section: </B>11.7&#160; [class.access.nest]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>29 Sep 1998<BR>



<P>[Moved to DR at 4/01 meeting.]</P>



<P>Example:</P>
<PRE>
    #include &lt;iostream.h&gt;
    
    class C {  // entire body is private
        struct Parent {
            Parent() { cout &lt;&lt; "C::Parent::Parent()\n"; }
        };
    
        struct Derived : Parent {
            Derived() { cout &lt;&lt; "C::Derived::Derived()\n"; }
        };
    
        Derived d;
    };
    
    
    int main() {
        C c;      //  Prints message from both nested classes
        return 0;
    }
</PRE>
How legal/illegal is this? Paragraphs that seem to apply here are:
<P>11 [class.access]
 paragraph 1:</P>
<BLOCKQUOTE>
A member of a class can be
<UL><LI><TT>private</TT>; that is, its name can be used only by members and
friends of the class in which it is declared. [...]</LI></UL></BLOCKQUOTE>
and
11.7 [class.access.nest]

paragraph 1:
<BLOCKQUOTE>
The members of a nested class
have no special access to members of an enclosing class, nor to classes
or functions that have granted friendship to an enclosing class; the usual
access rules (clause 11 [class.access]
)
shall be obeyed. [...]</BLOCKQUOTE>
This makes me think that the '<TT>: Parent</TT>' part is OK by itself,
but that the implicit call of '<TT>Parent::Parent()</TT>' by '<TT>Derived::Derived()</TT>'
is not.

<P><U>From Mike Miller:</U></P>

<P>I think it is completely legal, by the reasoning given in the (non-normative)
11.7 [class.access.nest]

paragraph 2. The use of a private nested class as a base of another nested class
is explicitly declared to be acceptable there. I think the rationale in
the comments in the example ("// OK because of injection of name A in A")
presupposes that public members of the base class will be public members
in a (publicly-derived) derived class, regardless of the access of the
base class, so the constructor invocation should be okay as well.</P>

<P>I can't find anything normative that explicitly says that,
though.</P>

<P>(See also papers J16/99-0009 = WG21 N1186,
J16/00-0031 = WG21 N1254, and J16/00-0045 = WG21 N1268.)</P>

<P><B>Proposed Resolution (04/01):</B></P>

<OL>

<LI><P>Insert the following as a new paragraph following
11 [class.access] paragraph 1:</P>

<BLOCKQUOTE>

A member of a class can also access all names as the class of which
it is a member.  A local class of a member function may access the
same names that the member function itself may access.  [<I>Footnote:</I>
Access permissions are thus transitive and cumulative to nested and
local classes.]

</BLOCKQUOTE>
</LI>

<LI><P>Delete 11 [class.access] paragraph 6.</P>
</LI>

<LI><P>In 11.7 [class.access.nest] paragraph 1, change</P>

<BLOCKQUOTE>

The members of a nested class have no special access to members of an
enclosing class, nor to classes or functions that have granted
friendship to an enclosing class; the usual access rules
(clause 11 [class.access]) shall be obeyed.

</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>

A nested class is a member and as such has the same access rights
as any other member.

</BLOCKQUOTE>

<P>Change</P>

<PRE>
    B b;       // error: E::B is private
</PRE>

<P>to</P>

<PRE>
    B b;       // Okay, E::I can access E::B
</PRE>

<P>Change</P>

<PRE>
    p-&gt;x = i;      // error: E::x is private
</PRE>

<P>to</P>

<PRE>
    p-&gt;x = i;      // Okay, E::I can access E::x
</PRE>

</LI>

<LI><P>Delete 11.7 [class.access.nest] paragraph 2.</P></LI>

</OL>

<P>(This resolution also resolves issues
<A HREF="
     cwg_defects.html#8">8</A> and
<A HREF="
     cwg_defects.html#10">10</A>.</P>

<BR><BR><HR><A NAME="263"></A><H4>263.
  
Can a constructor be declared a friend?
</H4><B>Section: </B>12.1&#160; [class.ctor]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Martin Sebor
 &#160;&#160;&#160;

 <B>Date: </B>13 Nov 2000<BR>


<P>[Voted into WP at April 2003 meeting.]</P>



<P>According to 12.1 [class.ctor] paragraph 1, a
declaration of a constructor has a special limited syntax, in
which only <I>function-specifier</I>s are allowed.  A <TT>friend</TT>
specifier is not a <I>function-specifier</I>, so one interpretation
is that a constructor cannot be declared in a <TT>friend</TT>
declaration.</P>

<P>(It should also be noted, however, that neither <TT>friend</TT>
nor <I>function-specifier</I> is part of the <SPAN style="font-weight:bold;background-color:#A0FFA0">declarator</SPAN>
syntax, so it's not clear that anything conclusive can be derived
from the wording of 12.1 [class.ctor].)</P>

<P><B>Notes from 04/01 meeting:</B></P>

<P>The consensus of the core language working group was that it
should be permitted to declare constructors as <TT>friend</TT>s.</P>

<P><B>Proposed Resolution (revised October 2002):</B></P>

<P>Change paragraph 1a in 3.4.3.1 [class.qual] (added by
the resolution of issue 147) as follows:</P>
<BLOCKQUOTE>
If the <I>nested-name-specifier</I> nominates a class <TT>C</TT>, and the
name specified after the <I>nested-name-specifier</I>, when looked up in
<TT>C</TT>, is the injected-class-name of <TT>C</TT> (clause
9 [class]), the name is instead considered to name the
constructor of class <TT>C</TT>. Such a constructor name shall be used
only in the <I>declarator-id</I> of a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">constructor definition</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">declaration</SPAN> that <SPAN style="text-decoration:line-through;background-color:#FFA0A0">appears outside of the class definition</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">names a constructor</SPAN>.... 
</BLOCKQUOTE>

<P>Note: the above does not allow qualified names to be used for
in-class declarations; see 8.3 [dcl.meaning] paragraph 1.
Also note that <A HREF="
     cwg_defects.html#318">issue 318</A> updates the
same paragraph.</P>

<P>Change the example in 11.3 [class.friend], paragraph 4
as follows:</P>
<PRE>
class Y {
  friend char* X::foo(int);
  <SPAN style="font-weight:bold;background-color:#A0FFA0">friend X::X(char);   // constructors can be friends</SPAN>
  <SPAN style="font-weight:bold;background-color:#A0FFA0">friend X::~X();      // destructors can be friends</SPAN>
  //...
};
</PRE>

<BR><BR><HR><A NAME="326"></A><H4>326.
  
Wording for definition of trivial constructor
</H4><B>Section: </B>12.1&#160; [class.ctor]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>James Kanze
 &#160;&#160;&#160;

 <B>Date: </B>9 Dec 2001<BR>


<P>[Voted into WP at October 2003 meeting.]</P>



<P>In 12.1 [class.ctor] paragraph 5, the standard says
"A constructor is trivial if [...]", and goes on to define a trivial
default constructor.  Taken literally, this would mean that a copy
constructor can't be trivial (contrary to 12.8 [class.copy] paragraph 6).  I suggest changing this to "A default
constructor is trivial if [...]".  (I think the change is purely
editorial.)</P>

<P><B>Proposed Resolution (revised October 2002):</B></P>

<P>Change 12.1 [class.ctor] paragraph 5-6 as follows: </P>
<BLOCKQUOTE>
<P>
A <I>default</I> constructor for a class <TT>X</TT>
is a constructor of class <TT>X</TT>
that can be called without an argument.
If there is no
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>user-declared</I></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">user-declared</SPAN>
constructor for class <TT>X</TT>,
a default constructor is implicitly declared.
An
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>implicitly-declared</I></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">implicitly-declared</SPAN>
default constructor
is an <TT>inline public</TT> member of its class.
A
<SPAN style="font-weight:bold;background-color:#A0FFA0">default</SPAN>
constructor is <I>trivial</I>
if it is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">an</SPAN> implicitly-declared <SPAN style="text-decoration:line-through;background-color:#FFA0A0">default constructor</SPAN>
and if:
<UL>
<LI>
its class has no virtual functions (10.3 [class.virtual])
and no virtual base classes (10.1 [class.mi]), and
</LI>
<LI>
all the direct base classes of its class
have trivial
<SPAN style="font-weight:bold;background-color:#A0FFA0">default</SPAN>
constructors, and
</LI>
<LI>
for all the nonstatic data members of its class
that are of class type (or array thereof),
each such class has a trivial
<SPAN style="font-weight:bold;background-color:#A0FFA0">default</SPAN>
constructor.
</LI>
</UL>
</P>
<P>
Otherwise, the
<SPAN style="font-weight:bold;background-color:#A0FFA0">default</SPAN>
constructor is non-trivial.
</P>
</BLOCKQUOTE>
<P>
Change 12.4 [class.dtor] paragraphs 3-4 as follows (the main
changes are removing italics):</P>
<BLOCKQUOTE>
<P>If a class has no
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>user-declared</I></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">user-declared</SPAN>
destructor, a destructor  is  declared
implicitly.   An
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>implicitly-declared</I></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">implicitly-declared</SPAN>
destructor  is an <TT>inline public</TT>
member of its class.  A destructor is <I>trivial</I> if it is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">an</SPAN>
implicitly-declared <SPAN style="text-decoration:line-through;background-color:#FFA0A0">destructor</SPAN> and if:
<UL>
<LI>
all of the direct base classes of its class have trivial destructors and
</LI>
<LI>
for all of the non-static data members of  its  class  that  are  of
class  type  (or  array  thereof),  each  such  class  has a trivial
destructor.
</LI>
</UL>
</P>
<P>Otherwise, the destructor is
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>non-trivial</I></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">non-trivial</SPAN>.
</P>
</BLOCKQUOTE>

<P>
In 9.5 [class.union] paragraph 1, change "trivial constructor"
to "trivial default constructor".
</P>

<P>
In 12.2 [class.temporary] paragraph 3, add to the reference to
12.1 [class.ctor] a second reference, to
12.8 [class.copy].</P>

<BR><BR><HR><A NAME="331"></A><H4>331.
  
Allowed copy constructor signatures
</H4><B>Section: </B>12.1&#160; [class.ctor]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>8 Jan 2002<BR>


<P>[Voted into WP at October 2003 meeting.]</P>

<P>12.1 [class.ctor] paragraph 10 states</P>
<BLOCKQUOTE>
A copy constructor for a class X is a constructor with a
first parameter of type X &amp; or of type const X &amp;.  [Note:
see 12.8 [class.copy] for more information on copy constructors.]
</BLOCKQUOTE>

<P>No mention is made of constructors with first parameters of types
volatile X &amp; or const volatile X &amp;.  This statement seems to be
in contradiction with 12.8 [class.copy] paragraph 2 which states</P>
<BLOCKQUOTE>
A non-template constructor for class X is a copy constructor
if its first parameter is of type X &amp;, const X &amp;, volatile X &amp;
or const volatile X &amp;, ...
</BLOCKQUOTE>

<P>12.8 [class.copy] paragraph 5 also mentions the volatile
versions of the
copy constructor, and the comparable paragraphs for copy assignment
(12.8 [class.copy] paragraphs 9 and 10) all allow volatile
versions, so it seems that 12.1 [class.ctor] is at fault.</P>

<P><B>Proposed resolution (October 2002):</B></P>

<P>Change 12.1 [class.ctor] paragraph 10 from
<BLOCKQUOTE>
A <I>copy constructor</I> for a class <TT>X</TT> is a constructor with a
first parameter of type <TT>X&amp;</TT> or of type <TT>const X&amp;</TT>.
[<I>Note:</I> see 12.8 [class.copy] for more information on
copy constructors. ]
</BLOCKQUOTE>
to (note that the dropping of italics is intentional):
<BLOCKQUOTE>
A copy constructor (12.8 [class.copy]) is used to copy objects
of class type. 
</BLOCKQUOTE>
</P>

<BR><BR><HR><A NAME="86"></A><H4>86.
  
Lifetime of temporaries in query expressions
</H4><B>Section: </B>12.2&#160; [class.temporary]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>Jan 1999<BR>



<P>[Voted into WP at April, 2006 meeting.]</P>

<P>In
12.2 [class.temporary]

 paragraph 5,
should binding a reference to the result of a "<TT>?</TT>" operation, each
of whose branches is a temporary, extend both temporaries?</P>

<P>Here's an example:</P>
<PRE>
    const SFileName &amp;C = noDir ? SFileName("abc") : SFileName("bcd");
</PRE>
<P>Do the temporaries created by the <TT>SFileName</TT> conversions survive
the end of the full expression?</P>

<P><B>Notes from 10/00 meeting:</B></P>

<P>Other problematic examples include cases where the temporary
from one branch is a base class of the temporary from the other (i.e.,
where the implementation must remember which type of temporary must
be destroyed), or where one branch is a temporary and the other is
not.  Similar questions also apply to the comma operator.  The sense
of the core language working group was that implementations should
be required to support these kinds of code.</P>

<P><B>Notes from the March 2004 meeting:</B></P>

<P>We decided that the cleanest model is one in which any "?" operation
that returns a class rvalue always copies one of its operands to
a temporary and returns the temporary as the result of the operation.
(Note that this may involve slicing.)  An implementation would be
free to optimize this using the rules in 12.8 [class.copy]
paragraph 15, and in fact we would expect that in many cases
compilers would do such optimizations.  For example, the compiler
could construct both rvalues in the above example into a
single temporary, and thus avoid a copy.</P>

<P>See also <A HREF="
     cwg_defects.html#446">issue 446</A>.</P>

<P><B>Proposed resolution (October, 2004):</B></P>

<P>This issue is resolved by the resolutions of <A HREF="
     cwg_defects.html#446">issue 446</A>.</P>

<P><B>Note (October, 2005):</B></P>

<P>This issue was overlooked when <A HREF="
     cwg_defects.html#446">issue 446</A>
was moved to &#8220;ready&#8221; status and was thus inadvertently
omitted from the list of issues accepted as Defect Reports at the
October, 2005 meeting.</P>

<BR><BR><HR><A NAME="124"></A><H4>124.
  
Lifetime of temporaries in default initialization of class arrays
</H4><B>Section: </B>12.2&#160; [class.temporary]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jack Rouse
 &#160;&#160;&#160;

 <B>Date: </B>3 June 1999<BR>



<P>[Moved to DR at 4/01 meeting.]</P>



<P><U>Jack Rouse:</U>
12.2 [class.temporary]

states that temporary objects will normally be destroyed at the
end of the full expression in which they are created.  This can create
some unique code generation requirements when initializing a class
array with a default constructor that uses a default argument.  Consider
the code:</P>

<PRE>
    struct T {
       int i;
       T( int );
       ~T();
    };

    struct S {
       S( int = T(0).i );
       ~S();
    };

    S* f( int n )
    {
       return new S[n];
    }
</PRE>

The full expression allocating the array in <TT>f(int)</TT> includes the
default constructor for <TT>S</TT>.  Therefore according to
1.9 [intro.execution] paragraph 14, it
includes the default argument expression for <TT>S(int)</TT>.
So evaluation of
the full expression should include evaluating the default argument "n"
times and creating "n" temporaries of type <TT>T</TT>.  But the destruction of
the temporaries must be delayed until the end of the full expression
so this requires allocating space at runtime for "n" distinct
temporaries.  It is unclear how these temporaries are supposed to be
allocated and deallocated.  They cannot readily be autos because a
variable allocation is required.

<P>I believe that many existing implementations will destroy the
temporaries needed by the default constructor after each array element
is initialized.  But I can't find anything in the standard that allows
the temporaries to be destroyed early in this case.</P>

<P>I think the standard should allow the early destruction of temporaries
used in the default initialization of class array elements.  I believe
early destruction is the status quo, and I don't think the users of
existing C++ compilers have been adversely impacted by it.</P>

<P><B>Proposed resolution (04/01):</B></P>

<P>The proposed resolution is contained in the proposal for
<A HREF="
     cwg_defects.html#201">issue 201</A>.</P>
<BR><BR><HR><A NAME="199"></A><H4>199.
  
Order of destruction of temporaries
</H4><B>Section: </B>12.2&#160; [class.temporary]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Alan Nash
 &#160;&#160;&#160;

 <B>Date: </B>27 Jan 2000<BR>



<P>[Voted into the WP at the April, 2007 meeting as part of paper
J16/07-0099 = WG21 N2239.]</P>



<P>12.2 [class.temporary]
 paragraph 3 simply
states the requirement that temporaries created during the evaluation
of an expression</P>

<BLOCKQUOTE>
are destroyed as the last step in evaluating the
full-expression (1.9) that (lexically) contains the point where they
were created.
</BLOCKQUOTE>

There is nothing said about the relative order in which these
temporaries are destroyed.

<P>Paragraph 5, dealing with temporaries bound to references, says</P>

<BLOCKQUOTE>
the temporaries created during the evaluation of the expression
initializing the reference, except the temporary to which the
reference is bound, are destroyed at the end of the full-expression in
which they are created and in the reverse order of the completion of
their construction.
</BLOCKQUOTE>

Is this difference intentional?  May temporaries in expressions other
than those initializing references be deleted in non-LIFO order?

<P><B>Notes from 04/00 meeting:</B></P>

<P>Steve Adamczyk expressed concern about constraining implementations
that are capable of fine-grained parallelism -- they may be
unable to determine the order of construction without adding
undesirable overhead.</P>

<P><B>Proposed resolution (April, 2007):</B></P>

<P>As specified in paper J16/07-0099 = WG21 N2239.</P>

<BR><BR><HR><A NAME="201"></A><H4>201.
  
Order of destruction of temporaries in initializers
</H4><B>Section: </B>12.2&#160; [class.temporary]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Alan Nash
 &#160;&#160;&#160;

 <B>Date: </B>31 Jan 2000<BR>



<P>[Moved to DR at 4/01 meeting.]</P>



<P>According to 12.2 [class.temporary]

paragraph 4, an expression appearing as the initializer in an object
definition constitutes a context "in which temporaries are destroyed
at a different point than the end of the full-expression."  It goes on
to say that the temporary containing the value of the expression
persists until after the initialization is complete (see also
<A HREF="
     cwg_closed.html#117">issue 117</A>).  This seems to presume
that the end of the full-expression is a point earlier than the
completion of the initialization.</P>

<P>However, according to
1.9 [intro.execution]
 paragraphs 12-13, the
full-expression in such cases is, in fact, the entire initialization.
If this is the case, the behavior described for temporaries in an
initializer expression is simply the normal behavior of temporaries in
any expression, and treating it as an exception to the general rule is
both incorrect and confusing.</P>

<P><B>Proposed resolution (04/01):</B></P>

<P><I>[Note: this proposal also addresses <A HREF="
     cwg_defects.html#124">issue 124</A>.]</I></P>

<OL>

<LI><P>Add to the end of 1.9 [intro.execution] paragraph 12:</P>

<BLOCKQUOTE>

If the initializer for an object or
sub-object is a full-expression, the initialization of
the object or sub-object (e.g., by calling a constructor
or copying an expression value) is considered to be part
of the full-expression.

</BLOCKQUOTE>
</LI>

<LI><P>Replace 12.2 [class.temporary] paragraph 4 with:</P>

<BLOCKQUOTE>

There are two contexts in which temporaries are
destroyed at a different point than the end of the
full-expression.  The first context is when a
default constructor is called to initialize an
element of an array.  If the constructor has one
or more default arguments, any temporaries created
in the default argument expressions are destroyed
immediately after return from the constructor.

</BLOCKQUOTE>
</LI>

</OL>

<BR><BR><HR><A NAME="320"></A><H4>320.
  
Question on copy constructor elision example
</H4><B>Section: </B>12.2&#160; [class.temporary]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Clamage
 &#160;&#160;&#160;

 <B>Date: </B>2 Nov 2001<BR>


<P>[Voted into WP at April 2005 meeting.]</P>

<P>Section 12.2 [class.temporary] paragraph 2, abridged:</P>
<BLOCKQUOTE>
<PRE>
  X f(X);
  void g()
  {
	X a;
	a = f(a);
  }
</PRE>
<P>
<TT>a=f(a)</TT> requires a temporary for either the argument <TT>a</TT>
or the result of <TT>f(a)</TT> to avoid undesired aliasing of <TT>a</TT>.
</P>
</BLOCKQUOTE>

<P>The note seems to imply that an implementation is allowed to omit
copying "a" to f's formal argument, or to omit using a temporary for
the return value of f.  I don't find that license in normative text.</P>

<P>Function f returns an X by value, and in the expression the value is
assigned (not copy-constructed) to "a".  I don't see how that
temporary can be omitted.  (See also 12.8 [class.copy] p 15)</P>

<P>Since "a" is an lvalue and not a temporary, I don't see how copying
"a" to f's formal parameter can be avoided.</P>

<P>Am I missing something, or is 12.2 [class.temporary] p 2
misleading?</P>

<P><B>Proposed resolution (October, 2004):</B></P>

<P>In 12.2 [class.temporary] paragraph 2, change the last
sentence as indicated:</P>

<BLOCKQUOTE>

On the other hand, the expression <TT>a=f(a)</TT> requires a
temporary for <SPAN style="text-decoration:line-through;background-color:#FFA0A0">either the argument <TT>a</TT> or the result of
<TT>f(a)</TT> to avoid undesired aliasing of <TT>a</TT></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">the result of <TT>f(a)</TT>, which is then assigned to
<TT>a</TT></SPAN>.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="392"></A><H4>392.
  
Use of full expression lvalue before temporary destruction
</H4><B>Section: </B>12.2&#160; [class.temporary]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Stephen Clamage
 &#160;&#160;&#160;

 <B>Date: </B>21 Nov 2002<BR>


<P>[Voted into WP at March 2004 meeting.]</P>



<PRE>
class C {
public:
    C();
    ~C();
    int&amp; get() { return p; } // reference return
private:
    int p;
};

int main ()
{
    if ( C().get() ) // OK?
}
</PRE>

<P>Section 12.2 [class.temporary] paragraph 3 says a temp is
destroyed as the last step in
evaluating the full expression.  But the expression C().get() has a
reference type.  Does 12.2 [class.temporary] paragraph 3 require
that the dereference to get a
boolean result occur before the destructor runs, making the code
valid?  Or does the code have undefined behavior?</P>

<P><U>Bill Gibbons:</U>
It has undefined behavior, though clearly this wasn't intended.
The lvalue-to-rvalue conversion that occurs in the "if" statement is
not currently part of the full-expression.</P>

<P>From section 12.2 [class.temporary] paragraph 3:</P>
<BLOCKQUOTE>
   Temporary objects are destroyed as the last step in evaluating
   the full-expression (1.9 [intro.execution])
that (lexically) contains the point
   where they were created.
</BLOCKQUOTE>

<P>From section 1.9 [intro.execution] paragraph 12:</P>
<BLOCKQUOTE>
   A full-expression is an expression that is not a subexpression
   of another expression. If a language construct is defined to
   produce an implicit call of a function, a use of the language
   construct is considered to be an expression for the purposes
   of this definition.
</BLOCKQUOTE>

<P>The note in section 1.9 [intro.execution] paragraph 12 goes
on to explain that this covers
expressions used as initializers, but it does not discuss
lvalues within temporaries.</P>

<P>It is a small point but it is probably worth correcting
1.9 [intro.execution] paragraph 12.
Instead of the "implicit call of a function" wording, it might
be better to just say that a full-expression includes any implicit
use of the expression value in the enclosing language construct,
and include a note giving implicit calls and lvalue-to-rvalue
conversions as examples.</P>

<P>Offhand the places where this matters include:

   initialization (including member initializers),
   selection statements,
   iteration statements,
   return,
   throw
</P>

<P><B>Proposed resolution (April 2003):</B></P>

<P>Change 1.9 [intro.execution] paragraph 12-13 to read:</P>
<BLOCKQUOTE>
<P>A <I>full-expression</I> is an expression that is not a
subexpression of another expression.  If a language construct is
defined to produce an implicit call of a function, a use of the
language construct is considered to be an expression for the
purposes of this definition.  <SPAN style="font-weight:bold;background-color:#A0FFA0">Conversions applied to the result of
an expression in order to satisfy the requirements of the language
construct in which the expression appears are also considered to be
part of the full-expression.</SPAN></P>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">[<I>Note:</I> certain contexts in C++ cause the evaluation
of a full-expression that results from a syntactic construct other
than <I>expression</I> (5.18 [expr.comma]).  For example,
in 8.5 [dcl.init] one syntax for
<I>initializer</I> is

<UL><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>( </TT><I>expression-list</I><TT> )</TT></SPAN></UL>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">but the resulting construct is a function call upon a constructor
function with <I>expression-list</I> as an argument list; such a
function call is a full-expression.  For example, in
8.5 [dcl.init], another
syntax for <I>initializer</I> is

<UL><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>= </TT><I>initializer-clause</I></SPAN></UL>

but again the resulting construct might be a function call upon a
constructor function with one <I>assignment-expression</I> as an
argument; again, the function call is a full-expression. ]</SPAN></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Example:</I></SPAN></P>
<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  struct S {
      S(int i): I(i) { }
      int&amp; v() { return I; }
    private:
      int I;
  };

  S s1(1);           // <I>full-expression is call of S::S(int)</I>
  S s2 = 2;          // <I>full-expression is call of S::S(int)</I>

  void f() {
      if (S(3).v())  // <I>full-expression includes lvalue-to-rvalue and</I>
                     // int<I> to</I> bool<I> conversions, performed before</I>
                     // <I>temporary is deleted at end of full-expression</I>
      { }
  }
</SPAN></PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN>
</BLOCKQUOTE>

<BR><BR><HR><A NAME="443"></A><H4>443.
  
Wording nit in description of lifetime of temporaries
</H4><B>Section: </B>12.2&#160; [class.temporary]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Matthias Hofmann
 &#160;&#160;&#160;

 <B>Date: </B>2 Dec 2003<BR>


<P>[Voted into WP at April 2005 meeting.]</P>

<P>There seems to be a typo in
12.2 [class.temporary]/5, which says "The temporary to which
the reference is bound or the temporary that is the complete object TO a
subobject OF which the TEMPORARY is bound persists for the lifetime of the
reference except as specified below."</P>

<P>I think this should be "The temporary to which the reference is bound or the
temporary that is the complete object OF a subobject TO which the REFERENCE
is bound persists for the lifetime of the reference except as specified
below."</P>

<P>I used upper-case letters for the parts I think need to be
changed.</P>

<P><B>Proposed resolution (October, 2004):</B></P>

<P>Change 12.2 [class.temporary] paragraph 5 as
indicated:</P>

<BLOCKQUOTE>

The temporary to which the reference is bound or the temporary
that is the complete object <SPAN style="text-decoration:line-through;background-color:#FFA0A0">to</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">of</SPAN> a subobject
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">of</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">to</SPAN> which the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">temporary</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">reference</SPAN>
is bound persists for the lifetime of the reference except as
specified below.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="464"></A><H4>464.
  
Wording nit on lifetime of temporaries to which references are bound
</H4><B>Section: </B>12.2&#160; [class.temporary]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Allan Odgaard
 &#160;&#160;&#160;

 <B>Date: </B>21 Feb 2004<BR>


<P>[Voted into WP at April, 2006 meeting.]</P>

<P>Section 12.2 [class.temporary] paragraph 5 ends with this "rule":</P>
<BLOCKSCOPE>
    [...] if obj2 is an object with static or automatic
    storage  duration created  after  the temporary  is
    created,  the temporary  shall  be destroyed  after
    obj2 is destroyed.
</BLOCKSCOPE>
<P>For the temporary to be destroyed after obj2 is destroyed, when obj2 has
static storage, I would say that the reference to the temporary should
also have static storage, but that is IMHO not clear from the
paragraph.</P>

<P>Example:</P>
<PRE>
    void f ()
    {
       const T1&amp; ref = T1();
       static T2 obj2;
       ...
    }
</PRE>
<P>Here the temporary would be destoyed <I>before</I> obj2, contrary to the
rule above.</P>

<P><U>Steve Adamczyk:</U> I agree there's a minor issue here.  I think
the clause quoted above meant for obj1 and obj2 to have the same storage
duration.  Replacing "obj2 is an object with static or automatic
storage duration" by "obj2 is an object with the same storage duration as
obj1" would, I believe, fix the problem.</P>

<P><B>Notes from October 2004 meeting:</B></P>

<P>We agreed with Steve Adamczyk's suggestion.</P>

<P><B>Proposed resolution (October, 2005):</B></P>

<P>Change 12.2 [class.temporary] paragraph 5 as follows:</P>

<BLOCKQUOTE>

... In addition, the destruction of temporaries bound to references
shall take into account the ordering of destruction of objects with
static or automatic storage duration (3.7.1 [basic.stc.static],
3.7.3 [basic.stc.auto]); that is, if <TT>obj1</TT> is an object
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">with static or automatic storage duration</SPAN> created before the
temporary is created <SPAN style="font-weight:bold;background-color:#A0FFA0">with the same storage duration as the
temporary</SPAN>, the temporary shall be destroyed before <TT>obj1</TT>
is destroyed; if <TT>obj2</TT> is an object <SPAN style="text-decoration:line-through;background-color:#FFA0A0">with static or
automatic storage duration</SPAN> created after the temporary is
created <SPAN style="font-weight:bold;background-color:#A0FFA0">with the same storage duration as the temporary</SPAN>, the
temporary shall be destroyed after <TT>obj2</TT> is destroyed...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="296"></A><H4>296.
  
Can conversion functions be static?
</H4><B>Section: </B>12.3.2&#160; [class.conv.fct]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Scott Meyers
 &#160;&#160;&#160;

 <B>Date: </B>5 Jul 2001<BR>


<P>[Moved to DR at October 2002 meeting.]</P>

<P>May user-defined conversion functions be static?  That is, should this
compile?</P>
<PRE>
    class Widget {
    public:
      static operator bool() { return true; }
    };
</PRE>
<P>All my compilers hate it.  I hate it, too.  However, I don't see anything
in 12.3.2 [class.conv.fct] that makes it illegal.  Is this a
prohibition that arises from
the grammar, i.e., the grammar doesn't allow "static" to be followed by a
<I>conversion-function-id</I> in a member function declaration?  Or am I just
overlooking something obvious that forbids static conversion functions?</P>

<P><B>Proposed Resolution (4/02):</B></P>

<P>Add to 12.3.2 [class.conv.fct] as a new paragraph 7:</P>

<BLOCKQUOTE>
Conversion functions cannot be declared <TT>static</TT>.
</BLOCKQUOTE>

<BR><BR><HR><A NAME="244"></A><H4>244.
  
Destructor lookup
</H4><B>Section: </B>12.4&#160; [class.dtor]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>6 Sep 2000<BR>


<P>[Moved to DR at October 2002 meeting.]</P>



<P>12.4 [class.dtor] contains this example:</P>

<PRE>
    struct B {
        virtual ~B() { }
    };
    struct D : B {
        ~D() { }
    };

    D D_object;
    typedef B B_alias;
    B* B_ptr = &amp;D_object;

    void f() {
        D_object.B::~B();               // calls B's destructor
        B_ptr-&gt;~B();                    // calls D's destructor
        B_ptr-&gt;~B_alias();              // calls D's destructor
        B_ptr-&gt;B_alias::~B();           // calls B's destructor
        B_ptr-&gt;B_alias::~B_alias();     // error, no B_alias in class B
    }
</PRE>

<P>On the other hand, 3.4.3 [basic.lookup.qual] contains this
example:</P>

<PRE>
    struct C {
        typedef int I;
    };
    typedef int I1, I2;
    extern int* p;
    extern int* q;
    p-&gt;C::I::~I();       // I is looked up in the scope of C
    q-&gt;I1::~I2();        // I2 is looked up in the scope of
                         // the postfix-expression
    struct A {
        ~A();
    };
    typedef A AB;
    int main()
    {
        AB *p;
        p-&gt;AB::~AB();    // explicitly calls the destructor for A
    }
</PRE>

<P>Note that</P>

<PRE>
     B_ptr-&gt;B_alias::~B_alias();
</PRE>

<P>is claimed to be an error, while the equivalent</P>

<PRE>
     p-&gt;AB::~AB();
</PRE>

<P>is claimed to be well-formed.</P>

<P>I believe that clause 3 is correct and that clause 12 is in error.
We worked hard to get the destructor lookup rules in clause 3 to be
right, and I think we failed to notice that a change was also needed
in clause 12.</P>

<P><U>Mike Miller</U>:</P>

<P>Unfortunately, I don't believe 3.4.3 [basic.lookup.qual] covers
the case of <TT>p-&gt;AB::~AB()</TT>.  It's clearly intended to do so, as
evidenced by 3.4.3.1 [class.qual] paragraph 1 ("a
destructor name is looked up as specified in 3.4.3 [basic.lookup.qual]"), but I don't think the language there does so.</P>

<P>The relevant paragraph is 3.4.3 [basic.lookup.qual] paragraph
5.  (None of the other paragraphs in that section deal with this topic
at all.)  It has two parts.  The first is</P>

<BLOCKQUOTE>
If a <I>pseudo-destructor-name</I> (5.2.4 [expr.pseudo])
contains a <I>nested-name-specifier</I>, the <I>type-name</I>s are
looked up as types in the scope designated by the
<I>nested-name-specifier</I>.
</BLOCKQUOTE>

<P>This sentence doesn't apply, because <TT>~AB</TT> isn't a
<I>pseudo-destructor-name</I>.  5.2.4 [expr.pseudo] makes
clear that this syntactic production (5.2 [expr.post]
paragraph 1) only applies to cases where the <I>type-name</I> is not a
<I>class-name</I>.  <TT>p-&gt;AB::~AB</TT> is covered by the production
using <I>id-expression</I>.</P>

<P>The second part of 3.4.3 [basic.lookup.qual] paragraph 5 says</P>

<BLOCKQUOTE>
<P>In a <I>qualified-id</I> of the form:</P>

<OL>
<TT>::</TT><SUB>opt</SUB>&#160;<I>nested-name-specifier</I>&#160;<TT>~</TT>&#160;<I>class-name</I>
</OL>

<P>where the <I>nested-name-specifier</I> designates a namespace name,
and in a <I>qualified-id</I> of the form:</P>

<OL>
<TT>::</TT><SUB>opt</SUB>&#160;<I>nested-name-specifier&#160;class-name</I>&#160;<TT>::</TT>&#160;<TT>~</TT>&#160;<I>class-name</I>
</OL>

<P>the <I>class-name</I>s are looked up as types in the scope
designated by the <I>nested-name-specifier</I>.</P>
</BLOCKQUOTE>

<P>This wording doesn't apply, either.  The first one doesn't because
the <I>nested-name-specifier</I> is a <I>class-name</I>, not a
namespace name.  The second doesn't because there's only one layer of
qualification.</P>

<P>As far as I can tell, there's no normative text that specifies how
the <TT>~AB</TT> is looked up in <TT>p-&gt;AB::~AB()</TT>.
3.4.3.1 [class.qual], where all the other
class member qualified lookups are handled, defers to
3.4.3 [basic.lookup.qual], and 3.4.3 [basic.lookup.qual]
doesn't cover the case.</P>

<P>See also <A HREF="
     cwg_defects.html#305">issue 305</A>.</P>

<P><U>Jason Merrill</U>:
My thoughts on the subject were that the name we use in a destructor call
is really meaningless; as soon as we see the <TT>~</TT> we know what the
user means,
all we're doing from that point is testing their ability to name the
destructor in a conformant way.  I think that everyone will agree that
<PRE>
  anything::B::~B()
</PRE>
should be well-formed, regardless of the origins of the name "B".  I
believe that the rule about looking up the second "B" in the same context
as the first was intended to provide this behavior, but to me this seems
much more heavyweight than necessary.  We don't need a whole new type of
lookup to be able to use the same name before and after the <TT>~</TT>;
we can just
say that if the two names match, the call is well-formed.  This is
significantly simpler to express, both in the standard and in an
implementation.</P>

<P>Anyone writing two different names here is either deliberately writing
obfuscated code, trying to call the destructor of a nested class, or
fighting an ornery compiler (i.e. one that still wants to see
<TT>B_alias::~B()</TT>).  I think we can ignore the first case.
The third would be
handled by reverting to the old rule (look up the name after <TT>~</TT> in the
normal way) with the lexical matching exception described above -- or we
could decide to break such code, do no lookup at all, and only accept a
matching name.  In a good implementation, the second should probably get an
error message telling them to write <TT>Outer::Inner::~Inner</TT> instead.</P>

<P>We discussed this at the meetings, but I don't remember if we came to
any sort of consensus on a direction.  I see three options:</P>
<OL>
<LI>
Stick with the status quo, i.e. the special lookup rule such that if the
name before <TT>::~</TT> is a class name, the name after <TT>::~</TT>
is looked up in the
same scope as the previous one.  If we choose this option, we just need
better wording that actually expresses this, as suggested in the issue
list.  This option breaks old <TT>B_alias::~B</TT> code where <TT>B_alias</TT>
is declared in a different scope from <TT>B</TT>.
</LI>
<LI>
Revert to the old rules, whereby the name after <TT>::~</TT> is looked up just
like a name after <TT>::</TT>, with the exception that if it matches the name
before <TT>::~</TT> then it is considered to name the same class.  This option
supports old code and code that writes <TT>B_alias::~B_alias</TT>.  It does not
support the <TT>q-&gt;I1::~I2</TT> usage of 3.4.3 [basic.lookup.qual],
but that seems like deliberate
obfuscation.  This option is simpler to implement than #1.
</LI>
<LI>
Do no lookup for a name after <TT>::~</TT>; it must match the
name before.  This
breaks old code as #1, but supports the most important case where the
names match.  This option may be slightly simpler to implement than #2.
It is certainly easier to teach.
</LI>
</OL>

<P>My order of preference is 2, 3, 1.</P>

<P>Incidentally, it seems to me oddly inconsistent to allow
<I>Namespace</I><TT>::~</TT><I>Class</I>,
but not <I>Outer</I><TT>::~</TT><I>Inner</I>.
Prohibiting the latter makes sense from the
standpoint of avoiding ambiguity, but what was the rationale for allowing
the former?</P>

<P><U>John Spicer</U>:
I agree that allowing <I>Namespace</I><TT>::~</TT><I>Class</I> is odd.
I'm not sure where this
came from.  If we eliminated that special case, then I believe the #1
rule would just be that in <TT>A::B1::~B2</TT> you look up <TT>B1</TT>
and <TT>B2</TT> in the same place in all cases.</P>

<P>I don't like #2.  I don't think the "old" rules represent a deliberate
design choice, just an error in the way the lookup was described.  The
usage that rule permits <TT>p-&gt;X::~Y</TT>
(where <TT>Y</TT> is a typedef to <TT>X</TT> defined in <TT>X</TT>),
but I doubt people really do that.  In other words, I think that #1
a more useful special case than #2 does, not that I think either special
case is very important.</P>

<P>One problem with the name matching rule is handling cases like:
<PRE>
  A&lt;int&gt; *aip;

  aip-&gt;A&lt;int&gt;::~A&lt;int&gt;();  // should work
  aip-&gt;A&lt;int&gt;::~A&lt;char&gt;(); // should not
</PRE>
I would favor #1, while eliminating the special case of
<I>Namespace</I><TT>::~</TT><I>Class</I>.</P>

<P><B>Proposed resolution (10/01):</B></P>

<P>Replace the normative text of 3.4.3 [basic.lookup.qual] paragraph 5
after the first sentence with:</P>
<BLOCKQUOTE>
<P>Similarly, in a <I>qualified-id</I> of the form:
<PRE>    ::<SUB>opt</SUB> <I>nested-name-specifier</I><SUB>opt</SUB> <I>class-name</I> :: ~ <I>class-name</I></PRE>
the second <I>class-name</I> is looked up in the same scope as the first.</P>
</BLOCKQUOTE>
<P>In 12.4 [class.dtor] paragraph 12, change the example to</P>
<BLOCKQUOTE><PRE>
D D_object;
typedef B B_alias;
B* B_ptr = &amp;D_object;

void f() {
  D_object.B::~B();                //<I>  calls  </I>B<I>'s destructor</I>
  B_ptr-&gt;~B();                    //<I>  calls  </I>D<I>'s destructor</I>
  B_ptr-&gt;~B_alias();              //<I>  calls  </I>D<I>'s destructor</I>
  B_ptr-&gt;B_alias::~B();           //<I>  calls  </I>B<I>'s destructor</I>
  B_ptr-&gt;B_alias::~B_alias();     //<I>  calls  </I>B<I>'s destructor</I>
}
</PRE></BLOCKQUOTE>

<P><B>April 2003:</B> See <A HREF="
     cwg_active.html#399">issue 399</A>.</P>

<BR><BR><HR><A NAME="252"></A><H4>252.
  
Looking up deallocation functions in virtual destructors
</H4><B>Section: </B>12.4&#160; [class.dtor]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Clamage
 &#160;&#160;&#160;

 <B>Date: </B>19 Oct 2000<BR>


<P>[Moved to DR at 10/01 meeting.]</P>



<P>There is a mismatch between 12.4 [class.dtor]
paragraph 11 and 12.5 [class.free] paragraph 4 regarding
the lookup of deallocation functions in virtual destructors.
12.4 [class.dtor] says,</P>

<BLOCKQUOTE>

At the point of definition of a virtual destructor (including an
implicit definition (12.8 [class.copy])), non-placement
operator delete shall be looked up in the scope of the destructor's
class (3.4.1 [basic.lookup.unqual]) and if found shall be accessible
and unambiguous. [<I>Note</I>: this assures that an operator delete
corresponding to the dynamic type of an object is available for the
<I>delete-expression</I> (12.5 [class.free]). ]

</BLOCKQUOTE>

<P>The salient features to note from this description are:</P>

<OL>

<LI>The lookup is "in the scope of the destructor's class," which
implies that only members are found (cf 12.2 [class.temporary]).
(The cross-reference would indicate otherwise, however, since it
refers to the description of looking up unqualified names; this kind
of lookup "spills over" into the surrounding scope.)</LI>

<LI>Only non-placement operator delete is looked up.  Presumably
this means that a placement operator delete is ignored in the
lookup.</LI>

</OL>

<P>On the other hand, 12.5 [class.free] says,</P>

<BLOCKQUOTE>

If a <I>delete-expression</I> begins with a unary <TT>::</TT>
operator, the deallocation function's name is looked up in global
scope. Otherwise, if the <I>delete-expression</I> is used to
deallocate a class object whose static type has a virtual destructor,
the deallocation function is the one found by the lookup in the
definition of the dynamic type's virtual destructor (12.4 [class.dtor]). Otherwise, if the <I>delete-expression</I> is used to
deallocate an object of class <TT>T</TT> or array thereof, the static
and dynamic types of the object shall be identical and the
deallocation function's name is looked up in the scope of
<TT>T</TT>. If this lookup fails to find the name, the name is looked
up in the global scope. If the result of the lookup is ambiguous or
inaccessible, or if the lookup selects a placement deallocation
function, the program is ill-formed.

</BLOCKQUOTE>

<P>Points of interest in this description include:</P>

<OL>

<LI>For a class type with a virtual destructor, the lookup is
described as being "in the definition of the dynamic type's
virtual destructor," rather than "in the scope of the dynamic
type."  That is, the lookup is assumed to be an unqualified
lookup, presumably terminating in the global scope.</LI>

<LI>The assumption is made that the lookup in the virtual
destructor was successful ("...the one found...", not "...the
one found..., <B>if any"</B>).  This will not be the case if
the deallocation function was not declared as a member somewhere
in the inheritance hierarchy.</LI>

<LI>The lookup in the non-virtual-destructor case <B>does</B>
find placement deallocation functions and can fail as a result.</LI>

</OL>

<P><B>Suggested resolution:</B> Change the description of the
lookup in 12.4 [class.dtor] paragraph 11 to match the
one in 12.5 [class.free] paragraph 4.</P>

<P><B>Proposed resolution (10/00):</B></P>

<OL>

<LI><P>Replace 12.4 [class.dtor] paragraph 11 with
the following:</P>

<BLOCKQUOTE>
At the point of definition of a virtual destructor (including an
implicit definition), the non-array deallocation function is looked up
in the scope of the destructor's class (10.2 [class.member.lookup]),
and, if no declaration is found, the function is looked up in the
global scope.  If the result of this lookup is ambiguous or
inaccessible, or if the lookup selects a placement deallocation
function, the program is ill-formed.  [<I>Note:</I> this assures that
a deallocation function corresponding to the dynamic type of an object
is available for the <I>delete-expression</I> (12.5 [class.free]).]

</BLOCKQUOTE>
</LI>

<LI><P>In 12.5 [class.free] paragraph 4, change</P>

<BLOCKQUOTE>

...the deallocation function is the one found by the lookup in
the definition of the dynamic type's virtual destructor
(12.4 [class.dtor]).

</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>

...the deallocation function is the one selected at the point of
definition of the dynamic type's virtual destructor
(12.4 [class.dtor]).

</BLOCKQUOTE>
</LI>

</OL>

<BR><BR><HR><A NAME="272"></A><H4>272.
  
Explicit destructor invocation and <I>qualified-id</I>s
</H4><B>Section: </B>12.4&#160; [class.dtor]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>22 Feb 2001<BR>


<P>[Moved to DR at 10/01 meeting.]</P>

12.4 [class.dtor] paragraph 12 contains the following note:

<BLOCKQUOTE>

an explicit destructor call must always be written using a member
access operator (5.2.5 [expr.ref]); in particular, the
<I>unary-expression</I> <TT>~X()</TT> in a member function is not an
explicit destructor call (5.3.1 [expr.unary.op]).

</BLOCKQUOTE>

<P>This note is incorrect, as an explicit destructor call can be
written as a <I>qualified-id</I>, e.g., <TT>X::~X()</TT>, which
does not use a member access operator.</P>

<P><B>Proposed resolution (04/01):</B></P>

<P>Change 12.4 [class.dtor] paragraph 12 as follows:</P>

<BLOCKQUOTE>

[<I>Note:</I> an explicit destructor call must always be written
using a member access operator (5.2.5 [expr.ref])
<SPAN style="font-weight:bold;background-color:#A0FFA0">or a <I>qualified-id</I> (5.1.1 [expr.prim.general])</SPAN>;
in particular, the <I>unary-expression</I> <TT>~X()</TT> in a
member function is not an explicit destructor call
(5.3.1 [expr.unary.op]).]

</BLOCKQUOTE>

<BR><BR><HR><A NAME="677"></A><H4>677.
  
Deleted <TT>operator delete</TT> and virtual destructors
</H4><B>Section: </B>12.4&#160; [class.dtor]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>15 February, 2008<BR>


<P>[Voted into the WP at the September, 2008 meeting.]</P>



<P>Deallocation functions can't be virtual because they are static
member functions; however, according to 12.5 [class.free]
paragraph 7, they behave like virtual functions when the class's
destructor is virtual:</P>

<BLOCKQUOTE>

Since member allocation and deallocation functions are <TT>static</TT>
they cannot be virtual. [<I>Note:</I> however, when
the <I>cast-expression</I> of a <I>delete-expression</I> refers to an
object of class type, because the deallocation function actually
called is looked up in the scope of the class that is the dynamic type
of the object, if the destructor is virtual, the effect is the same.

</BLOCKQUOTE>

<P>Because the intent is to make any use of a deleted function
diagnosable at compile time, a virtual deleted function can neither
override nor be overridden by a non-deleted function, as described
in 10.3 [class.virtual] paragraph 14:</P>

<BLOCKQUOTE>

A function with a deleted definition (8.4 [dcl.fct.def]) shall
not override a function that does not have a deleted
definition. Likewise, a function that does not have a deleted
definition shall not override a function with a deleted definition.

</BLOCKQUOTE>

<P>One would assume that a similar kind of prohibition is needed for
deallocation functions in a class hierarchy with virtual destructors,
but it's not clear that the current specification says that.
8.4 [dcl.fct.def] paragraph 10 says,</P>

<BLOCKQUOTE>

A program that refers to a deleted function implicitly or explicitly,
other than to declare it, is ill-formed.

</BLOCKQUOTE>

<P>Furthermore, the deallocation function is looked up at the point
of definition of a virtual destructor (12.4 [class.dtor]
paragraph 11), and the function found by this lookup is considered
to be &#8220;used&#8221; (3.2 [basic.def.odr] paragraph 2).
However, it's not completely clear that this &#8220;use&#8221;
constitutes a &#8220;reference&#8221; in the sense of
8.4 [dcl.fct.def] paragraph 10, especially in a program in
which an object of a type that would call that deallocation function
is never deleted.</P>

<U>Suggested resolution:</U>

<P>Augment the list of lookup results from a virtual destructor that
render a program ill-formed in 12.4 [class.dtor] paragraph 10
to include a deleted function:</P>

<BLOCKQUOTE>

If the result of this lookup is ambiguous or inaccessible, or if the
lookup selects a placement deallocation function <SPAN style="font-weight:bold;background-color:#A0FFA0">or a function with
a deleted definition (8.4 [dcl.fct.def])</SPAN>, the program is
ill-formed.

</BLOCKQUOTE>

<P><B>Proposed resolution (June, 2008):</B></P>

<P>Change 12.4 [class.dtor] paragraph 10 as follows:</P>

<BLOCKQUOTE>

If the result of this lookup is ambiguous or inaccessible, or if the
lookup selects a placement deallocation function <SPAN style="font-weight:bold;background-color:#A0FFA0">or a function with
a deleted definition (8.4 [dcl.fct.def])</SPAN>, the program is
ill-formed.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="510"></A><H4>510.
  
Default initialization of POD classes?
</H4><B>Section: </B>12.6&#160; [class.init]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>18 Mar 2005<BR>


<P>[Voted into WP at April, 2006 meeting.]</P>

<P>8.5 [dcl.init] paragraph 10 makes it clear that
non-static POD class objects with no initializer are left uninitialized
and have an indeterminate initial value:</P>

<BLOCKQUOTE>

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 value; if the object or any of
its subobjects are of const-qualified type, the program is ill-formed.

</BLOCKQUOTE>

<P>12.6 [class.init] paragraph 1, however, implies that all
class objects without initializers, whether POD or not, are
default-initialized:</P>

<BLOCKQUOTE>

When no initializer is specified for an object of (possibly
cv-qualified) class type (or array thereof), or the initializer has
the form <TT>()</TT>, the object is initialized as specified in
8.5 [dcl.init]. The object is default-initialized if there
is no initializer, or value-initialized if the initializer
is <TT>()</TT>.

</BLOCKQUOTE>

<P><B>Proposed resolution (October, 2005):</B></P>

<P>Remove the indicated words from 12.6 [class.init] paragraph 1:</P>

<BLOCKQUOTE>

When no initializer is specified for an object of (possibly
cv-qualified) class type (or array thereof), or the initializer has
the form <TT>()</TT>, the object is initialized as specified in
8.5 [dcl.init]. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The object is default-initialized if
there is no initializer, or value-initialized if the initializer
is <TT>()</TT>.</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="683"></A><H4>683.
  
Requirements for trivial subobject special functions
</H4><B>Section: </B>12.8&#160; [class.copy]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jens Maurer
 &#160;&#160;&#160;

 <B>Date: </B>13 March, 2008<BR>


<P>[Voted into the WP at the September, 2008 meeting (resolution
in paper N2757).]</P>



<P>Part of the decision regarding whether a class has a trivial special
function (copy constructor, copy assignment operator, default constructor)
is whether its base and member subobjects have corresponding trivial
member functions.  However, with the advent of defaulted functions, it is
now possible for a single class to have both trivial and nontrivial
overloads for those functions.  For example,</P>

<PRE>
    struct B {
       B(B&amp;) = default;    //<SPAN style="font-family:Times;font-style:italic"> trivial</SPAN>
       B(const B&amp;);        //<SPAN style="font-family:Times;font-style:italic"> non-trivial, because user-provided</SPAN>
    };

    struct D : B { };
</PRE>

<P>Although <TT>B</TT> has <I>a</I> trivial copy constructor and thus
satisfies the requirements in 12.8 [class.copy] paragraph 6,
the copy constructor in <TT>B</TT> that would be called by the
implicitly-declared copy constructor in <TT>D</TT> is <I>not</I>
trivial.  This could be fixed either by requiring that all the
subobject's copy constructors (or copy assignment operators, or
default constructors) be trivial or that the one that would be
selected by overload resolution be trivial.</P>

<P><B>Proposed resolution (July, 2008):</B></P>

<P>Change 8.4 [dcl.fct.def] paragraph 9 as follows:</P>

<BLOCKQUOTE>

... A special member function that would be implicitly defined as
deleted shall not be explicitly defaulted. <SPAN style="font-weight:bold;background-color:#A0FFA0">If a special member
function for a class <TT>X</TT> is defaulted on its first declaration,
no other special member function of the same kind (default
constructor, copy constructor, or copy assignment operator) shall be
declared in class <TT>X</TT>.</SPAN> A special member function is
<I>user-provided</I>...

</BLOCKQUOTE>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>The resolution adopted as part of paper N2757 differs from the
July, 2008 proposed resolution by allowing defaulted and
user-provided special member functions to coexist.  Instead, a
trivial class is defined as having no non-trivial copy constructors
or copy assignment operators, and a trivial copy constructor or
assignment operator is defined as invoking only trivial copy
operations for base and member subobjects.</P>

<BR><BR><HR><A NAME="162"></A><H4>162.
  
(<TT>&amp;C::f)()</TT> with nonstatic members
</H4><B>Section: </B>13.3.1.1&#160; [over.match.call]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>26 Aug 1999<BR>



<P>[Moved to DR at October 2002 meeting.]</P>



<P>13.3.1.1 [over.match.call]
 paragraph 3
says that when a call of the form</P>

<PRE>
   (&amp;C::f)()
</PRE>

is written, the set of overloaded functions named by <TT>C::f</TT>
must not contain
any nonstatic member functions.  A footnote gives the rationale: if a member
of <TT>C::f</TT> is a nonstatic member function,
<TT>&amp;C::f</TT> is a pointer to member
constant, and therefore the call is invalid.

<P>This is clear, it's implementable, and it doesn't directly contradict
anything else in the standard.  However, I'm not sure it's consistent
with some similar cases.</P>

<P>In 13.4 [over.over]
 paragraph 5,
second example, it is made amply clear that when <TT>&amp;C::f</TT> is
used as the address of a function, e.g.,</P>

<PRE>
   int (*pf)(int) = &amp;C::f;
</PRE>

the overload set can contain both static and nonstatic member functions.
The function with the matching signature is selected, and if it is
nonstatic <TT>&amp;C::f</TT>
is a pointer to member function, and otherwise <TT>&amp;C::f</TT> is
a normal pointer to function.

<P>Similarly, 13.3.1.1.1 [over.call.func]

paragraph 3 makes it clear that</P>

<PRE>
   C::f();
</PRE>

is a valid call even if the overload set contains both static and
nonstatic member functions.  Overload resolution is done, and if a
nonstatic member function is selected, an implicit <TT>this-&gt;</TT> is added,
if that is possible.

<P>Those paragraphs seem to suggest the general rule that you do overload
resolution first and then you interpret the construct you have
according to the function selected.  The fact that there are static
and nonstatic functions in the overload set is irrelevant; it's only
necessary that the chosen function be static or nonstatic to match
the context.</P>

<P>Given that, I think it would be more consistent if the
<TT>(&amp;C::f)()</TT> case
would also do overload resolution first.  If a nonstatic member is
chosen, the program would be ill-formed.</P>

<P><B>Proposed resolution (04/01):</B></P>

<OL>

<LI><P>Change the indicated text in 13.3.1.1 [over.match.call]
paragraph 3:</P>

<BLOCKQUOTE>
The fourth case arises from a <I>postfix-expression</I> of the form
<TT>&amp;F</TT>, where
<TT>F</TT> names  a set of overloaded functions.
In the context of a function call,
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">the set of functions named by <TT>F</TT> shall contain only non-member
functions and static member functions. [Footnote:
If <TT>F</TT> names a non-static member function, <TT>&amp;F</TT>
is a pointer-to-member, which cannot be used with the function call syntax.]
And in this context using <TT>&amp;F</TT> behaves the same as using</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>&amp;F</TT> is treated the same as</SPAN>
the name <TT>F</TT> by itself.
Thus, <TT>(&amp;F)(</TT><I>expression-list</I><sub>opt</sub><TT>)</TT>
is simply
<TT>(F)(</TT><I>expression-list</I><sub>opt</sub><TT>)</TT>, which is
discussed in 13.3.1.1.1 [over.call.func].
<SPAN style="font-weight:bold;background-color:#A0FFA0">If the function selected by overload resolution according to 
13.3.1.1.1 [over.call.func] is
a nonstatic member function, the program is
ill-formed. [Footnote: When <TT>F</TT> is a nonstatic member
function, a reference of the form <TT>&amp;A::F</TT> is a
pointer-to-member,
which cannot be used with the function-call syntax, and
a reference of the form <TT>&amp;F</TT> is an invalid use of the
"<TT>&amp;</TT>" operator on a nonstatic member function.]</SPAN>
(The resolution of <TT>&amp;F</TT> in other contexts is described in
13.4 [over.over].)
</BLOCKQUOTE>
</LI>
</OL>

<BR><BR><HR><A NAME="239"></A><H4>239.
  
Footnote 116 and Koenig lookup
</H4><B>Section: </B>13.3.1.1.1&#160; [over.call.func]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Clamage
 &#160;&#160;&#160;

 <B>Date: </B>2 Aug 2000<BR>


<P>[Moved to DR at 4/01 meeting.]</P>



In describing non-member functions in an overload set, footnote
116 (13.3.1.1.1 [over.call.func]) says,

<BLOCKQUOTE>

Because of the usual name hiding rules, these will be introduced by
declarations or by <i>using-directive</i>s all found in the same block
or all found at namespace scope.

</BLOCKQUOTE>

<P>At least in terms of the current state of the Standard, this
is not correct: a block extern declaration does not prevent
Koenig lookup from occurring.  For example,</P>

<PRE>
    enum E { zero };
    void f(E);
    void g() {
        void f(int);
        f(zero);
    }
</PRE>

<P>In this example, the overload set will include declarations
from both namespace and block scope.</P>

<P>(See also <A HREF="
     cwg_closed.html#12">issue 12</A>.)</P>

<P><B>Proposed resolution (04/01):</B></P>

<OL>

<LI><P>In 3.4.2 [basic.lookup.argdep] paragraph 2, change</P>

<BLOCKQUOTE>

If the ordinary unqualified lookup of the name finds the declaration
of a class member function, the associated namespaces and classes are
not considered.

</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>

If the ordinary unqualified lookup of the name finds the declaration
of a class member function, or a block-scope function declaration
that is not a <I>using-declaration</I>, the associated namespaces
and classes are not considered.

</BLOCKQUOTE>

<P>and change the example to:</P>

<PRE>
    namespace NS {
        class T { };
        void f(T);
        void g(T, int);
    }
    NS::T parm;
    void g(NS::T, float);
    int main() {
        f(parm);            // OK: calls NS::f
        extern void g(NS::T, float);
        g(parm, 1);         // OK: calls g(NS::T, float)
    }
</PRE>

</LI>

<LI><P>In 13.3.1.1.1 [over.call.func] paragraph 3 from:</P>

<BLOCKQUOTE>

If the name resolves to a non-member function declaration, that
function and its overloaded declarations constitute the set of
candidate functions.

</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>

If the name resolves to a set of non-member function declarations,
that set of functions constitutes the set of candidate functions.

</BLOCKQUOTE>

<P>Note that this text is also edited by <A HREF="
     cwg_defects.html#364">issue 364</A>.
Also, remove the associated footnote 116.
</P>

</LI>

</OL>

<BR><BR><HR><A NAME="364"></A><H4>364.
  
Calling overloaded function with static in set, with no object
</H4><B>Section: </B>13.3.1.1.1&#160; [over.call.func]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>23 July 2002<BR>


<P>[Voted into WP at October 2003 meeting.]</P>

<P>Consider this program:</P>
<PRE>
   struct S {
     static void f (int);
     void f (char);
   };

   void g () {
     S::f ('a');
   }
</PRE>
<P>G++ 3.1 rejects it, saying:</P>
<PRE>
   test.C:7: cannot call member function `void S::f(char)' without object
</PRE>

<P><U>Mark Mitchell</U>:
It looks to me like G++ is correct, given 13.3.1.1.1 [over.call.func].
This case is the "unqualified function call" case described in paragraph
3 of that section.  ("Unqualified" here means that there is no "x-&gt;" or
"x." in front of the call, not that the name is unqualified.)</P>

<P>That paragraph says that you first do name lookup.  It then asks you
to look at what declaration is returned.  (That's a bit confusing; you
presumably get a set of declarations.  Or maybe not; the name lookup
section says that if name lookup finds a non-static member in a context
like this the program is in error.  But surely this program is not
erroneous.  Hmm.)</P>

<P>Anyhow, you have -- at least -- "S::f(char)" as the result of the
lookup.</P>

<P>The keyword "this" is not in scope, so "all overloaded declarations of
the function name in T become candidate functions and a contrived object
of type T becomes the implied object argument."  That means we get
both  versions of "f" at this point.  Then, "the call is ill-formed,
however, if overload resolution selects one of the non-static members
of T in this case."  Since, in this case, "S::f(char)" is the winner,
the program is ill-formed.</P>

<P><U>Steve Adamczyk</U>:
This result is surprising, because we've selected a function
that we cannot call, when there is another function that can be
called.  This should either be ambiguous, or it should select the static
member function.  See also 13.3.1 [over.match.funcs] paragraph 2:
"Similarly, when
appropriate, the context can construct an argument list that
contains an implied object argument..."</P>

<P><B>Notes from October 2002 meeting:</B></P>

<P>We agreed that g++ has it right, but the standard needs to be clearer.</P>

<P><B>Proposed resolution (October 2002, revised April 2003):</B></P>

<P>Change 13.3.1.1.1 [over.call.func] paragraphs 2 and 3 as
follows:</P>
<BLOCKQUOTE>
<P>In qualified function calls, the name to be resolved is an
<I>id-expression</I> and is preceded by an <TT>-&gt;</TT> or <TT>.</TT>
operator. Since the construct <TT>A-&gt;B</TT> is generally equivalent
to <TT>(*A).B</TT>, the rest of clause 13 [over]
assumes, without loss of generality, that all member function calls have been 
normalized to the form that uses an object and the <TT>.</TT> operator. 
Furthermore, clause 13 [over]
assumes that the <I>postfix-expression</I> that is the left
operand of the <TT>.</TT> operator has type ``<I>cv</I> <TT>T</TT>''
where <TT>T</TT> denotes a class.
[Footnote: Note that cv-qualifiers on the type of 
objects are significant in overload resolution for both lvalue and
class rvalue objects. --- end footnote]
Under this assumption, the <I>id-expression</I> in the 
call is looked up as a member function of <TT>T</TT> following the rules for 
looking up names in classes (10.2 [class.member.lookup]).
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">If a member function is found, that function and its overloaded 
declarations</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">The function declarations found by that lookup</SPAN>
constitute the set of candidate functions. The argument list is the
<I>expression-list</I> in the call augmented by the addition of the
left operand of the <TT>.</TT> operator in the normalized member
function call as the implied object argument (13.3.1 [over.match.funcs]).
</P>
<P>In unqualified function calls, the name is 
not qualified by an <TT>-&gt;</TT> or <TT>.</TT> operator and has the more 
general form of a <I>primary-expression</I>. The name is looked up in the 
context of the function call following the normal rules for name lookup in 
function calls (<SPAN style="text-decoration:line-through;background-color:#FFA0A0">3.4.2 [basic.lookup.argdep]</SPAN>
3.4 [basic.lookup]).
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">If the name resolves to a non-member function declaration, that
function and its overloaded declarations</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">The function declarations found by that lookup</SPAN>
constitute the set of candidate functions.
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">[Footnote: Because of the usual name hiding rules, 
these will be introduced by declarations or by <I>using-directive</I>s all 
found in the same block or all found at namespace scope. --- end footnote]</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">Because of the rules for name lookup,
the set of candidate functions consists (1) entirely of non-member functions
or (2) entirely of member functions of some class </SPAN><TT><SPAN style="font-weight:bold;background-color:#A0FFA0">T</SPAN></TT><SPAN style="font-weight:bold;background-color:#A0FFA0">. In 
case (1), t</SPAN><SPAN style="text-decoration:line-through;background-color:#FFA0A0">T</SPAN>he argument list is the same as
the <I>expression-list</I> in the call.
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">If the name resolves to a nonstatic member function, then the 
function call is actually a member function call.</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">In case (2), the argument list is the <I>expression-list</I> in the
call augmented by the addition of an implied object argument as in
a qualified function call.</SPAN> 
If the keyword <TT>this</TT> (9.3.2 [class.this]) 
is in scope and refers to <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the </SPAN>class <TT><SPAN style="font-weight:bold;background-color:#A0FFA0">T</SPAN></TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">of that member 
function</SPAN>, or a derived class <SPAN style="text-decoration:line-through;background-color:#FFA0A0">thereof</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">of <TT>T</TT></SPAN>, then 
the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">function call is transformed into a normalized qualified
function call using</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">implied object argument is</SPAN><TT>(*this)</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">as the
<I>postfix-expression</I>
to the left of the <TT>.</TT> operator</SPAN>. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The candidate 
functions and argument list are as described for qualified function calls 
above.</SPAN> If the keyword <TT>this</TT> is not in scope or refers to 
another class, then <SPAN style="text-decoration:line-through;background-color:#FFA0A0">name resolution found a static member of some
class </SPAN><TT><SPAN style="text-decoration:line-through;background-color:#FFA0A0">T</SPAN></TT><SPAN style="text-decoration:line-through;background-color:#FFA0A0">. 
In this case,</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">all overloaded declarations of the function name in
<TT>T</TT> become candidate functions and</SPAN> a contrived object of 
type <TT>T</TT> becomes the implied object argument.
[Footnote: An implied object argument must be 
contrived to correspond to the implicit object parameter attributed to member 
functions during overload resolution. It is not used in the call to the 
selected function. Since the member functions all have the same implicit
object 
parameter, the contrived object will not be the cause to select or reject a 
function. --- end footnote]
<SPAN style="font-weight:bold;background-color:#A0FFA0">If the argument list is augmented by a contrived object 
and </SPAN><SPAN style="text-decoration:line-through;background-color:#FFA0A0">The call is ill-formed, however, if</SPAN> overload 
resolution selects one of the non-static member functions of
<TT>T</TT><SPAN style="font-weight:bold;background-color:#A0FFA0">, the 
call is ill-formed</SPAN><SPAN style="text-decoration:line-through;background-color:#FFA0A0"> in this case</SPAN>.
</P>
</BLOCKQUOTE>

<P>Note that <A HREF="
     cwg_defects.html#239">issue 239</A> also edits
paragraph 3.</P>

<BR><BR><HR><A NAME="280"></A><H4>280.
  
Access and surrogate call functions
</H4><B>Section: </B>13.3.1.1.2&#160; [over.call.object]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Andrei Iltchenko
 &#160;&#160;&#160;

 <B>Date: </B>16 Apr 2001<BR>


<P>[Voted into WP at October 2003 meeting.]</P>

<P>According to 13.3.1.1.2 [over.call.object] paragraph 2, when
the <I>primary-expression</I> <TT>E</TT> in the function call syntax
evaluates to a class object of type "<I>cv</I> <TT>T</TT>", a
surrogate call function corresponding to an appropriate conversion
function declared in a direct or indirect base class <TT>B</TT> of
<TT>T</TT> is included or not included in the set of candidate
functions based on class <TT>B</TT> being accessible.</P>

<P>For instance in the following code sample, as per the paragraph in
question, the expression <TT>c(3)</TT> calls <TT>f2</TT>, instead of
the construct being ill-formed due to the conversion function
<TT>A::operator fp1</TT> being inaccessible and its corresponding
surrogate call function providing a better match than the surrogate
call function corresponding to <TT>C::operator fp2</TT>:</P>

<PRE>
    void  f1(int)  {   }
    void  f2(float)  {   }
    typedef void  (* fp1)(int);
    typedef void  (* fp2)(float);

    struct  A  {
       operator fp1()
       {   return  f1;   }
    };

    struct  B :  private A  {   };

    struct  C :  B  {
       operator  fp2()
       {   return  f2;   }
    };

    int  main()
    {
       C   c;
       c(3);  // f2 is called, instead of the construct being ill-formed.
       return  0;
    }
</PRE>

<P>The fact that the accessibility of a base class influences the
overload resolution process contradicts the fundamental language rule
(3.4 [basic.lookup] paragraph 1, and 13.3 [over.match] paragraph 2) that access checks are applied only once
name lookup and function overload resolution (if applicable) have
succeeded.</P>

<P><B>Notes from 4/02 meeting:</B></P>

<P>There was some concern about whether 10.2 [class.member.lookup] (or
anything else, for that matter) actually defines "ambiguous base class".
See <A HREF="
     cwg_defects.html#39">issue 39</A>.  See also
<A HREF="
     cwg_active.html#156">issue 156</A>.</P>

<P><B>Notes from October 2002 meeting:</B></P>

<P>It was suggested that the ambiguity check is done as part of the
call of the conversion function.</P>

<P><B>Proposed resolution (revised October 2002):</B></P>

<P>In 13.3.1.1.2 [over.call.object] paragraph 2, replace the
last sentence</P>

<BLOCKQUOTE>

Similarly, surrogate call functions are added to the set of candidate
functions for each conversion function declared in an accessible base
class provided the function is not hidden within <TT>T</TT> by another
intervening declaration.

</BLOCKQUOTE>

<P>with</P>

<BLOCKQUOTE>

Similarly, surrogate call functions are added to the set of candidate
functions for each conversion function declared in a base class of
<TT>T</TT> provided the function is not hidden within <TT>T</TT> by
another intervening declaration.
</BLOCKQUOTE>

<P>Replace 13.3.1.1.2 [over.call.object] paragraph 3
<BLOCKQUOTE>
If  such a surrogate call function is selected by overload resolution,
its body, as defined above, will be  executed  to  convert  <TT>E</TT>  to  the
appropriate  function  and then to invoke that function with the
arguments of the call.
</BLOCKQUOTE>
by
<BLOCKQUOTE>
If  such a surrogate call function is selected by overload resolution,
the corresponding conversion function will be called to convert
<TT>E</TT>  to  the appropriate  function pointer or reference,
and the function will then be invoked with the  arguments of the call.
If the conversion function cannot be called
(e.g., because of an ambiguity), the program is ill-formed.
</BLOCKQUOTE>
</P>

<BR><BR><HR><A NAME="416"></A><H4>416.
  
Class must be complete to allow operator lookup?
</H4><B>Section: </B>13.3.1.2&#160; [over.match.oper]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Greg Comeau
 &#160;&#160;&#160;

 <B>Date: </B>22 May 2003<BR>


<P>[Voted into WP at October 2004 meeting.]</P>

<P>Normally reference semantics allow incomplete types in certain contexts,
but isn't this:</P>
<PRE>
  class A;

  A&amp; operator&lt;&lt;(A&amp; a, const char* msg);
  void foo(A&amp; a)
  {
    a &lt;&lt; "Hello";
  }
</PRE>
<P>required to be diagnosed because of the op&lt;&lt;? The reason
being that the class may actually have an op&lt;&lt;(const char *) in it.</P>

<P>What is it?   un- or ill-something?   Diagnosable?   No problem at all?</P>

<P><U>Steve Adamczyk:</U>
I don't know of any requirement in the standard that the class be complete.
There is a rule that will instantiate a class template in order to be able
to see whether it has any operators.  But I wouldn't think one wants to
outlaw the above example merely because the user might have an
operator&lt;&lt;
in the class; if he doesn't, he would not be pleased that the above
is considered invalid.</P>

<P><U>Mike Miller:</U>
Hmm, interesting question.  My initial reaction is that it just
uses <TT>::operator&lt;&lt;</TT>; any <TT>A::operator&lt;&lt;</TT>
simply won't be considered in
overload resolution.  I can't find anything in the Standard that
would say any different.</P>

<P>The closest analogy to this situation, I'd guess, would be
deleting a pointer to an incomplete class;
5.3.5 [expr.delete] paragraph 5 says that that's
undefined behavior if the complete type has a non-trivial destructor
or an operator delete.  However, I tend to think that that's because
it deals with storage and resource management, not just because it
might have called a different function.  Generally, overload
resolution that goes one way when it might have gone another with
more declarations in scope is considered to be not an error, cf
7.3.3 [namespace.udecl] paragraph 9,
14.6.3 [temp.nondep] paragraph 1, etc.</P>

<P>So my bottom line take on it would be that it's okay, it's up to
the programmer to ensure that all necessary declarations are in
scope for overload resolution.  Worst case, it would be like the
operator delete in an incomplete class -- undefined behavior, and
thus not required to be diagnosed.</P>

<P>13.3.1.2 [over.match.oper] paragraph 3, bullet 1, says,
"If T1 is a class type, the set of member candidates is the result
of the qualified lookup of <TT>T1::operator@</TT>
(13.3.1.1.1 [over.call.func])."  Obviously, that lookup is
not possible if T1 is
incomplete.  Should 
13.3.1.2 [over.match.oper] paragraph 3, bullet 1, say
"complete class type"?  Or does the inability to perform
the lookup mean that the program is ill-formed?
3.2 [basic.def.odr] paragraph 4 doesn't apply,
I don't think, because you don't know whether you'll be applying a
class member access operator until you know whether the operator
involved is a member or not.</P>

<P><B>Notes from October 2003 meeting:</B></P>

<P>We noticed that the title of this issue did not match the
body.  We checked the original source and then corrected the title
(so it no longer mentions templates).</P>

<P>We decided that this is similar to other cases like
deleting a pointer to an incomplete class, and it should not be
necessary to have a complete class.  There is no undefined
behavior.</P>

<P><B>Proposed Resolution (October 2003):</B></P>

<P>Change the first bullet of 13.3.1.2 [over.match.oper] paragraph 3
to read:</P>
<BLOCKQUOTE>
If T1 is a <SPAN style="font-weight:bold;background-color:#A0FFA0">complete</SPAN> class type, the set of member candidates
is the result of the qualified lookup of <TT>T1::operator@</TT>
(13.3.1.1.1 [over.call.func]); otherwise, the set of member
candidates is empty.
</BLOCKQUOTE>

<BR><BR><HR><A NAME="60"></A><H4>60.
  
Reference binding and valid conversion sequences
</H4><B>Section: </B>13.3.3.1.4&#160; [over.ics.ref]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>13 Oct 1998<BR>



<P>[Moved to DR at October 2002 meeting.]</P>

<P>Does dropping a cv-qualifier on a reference binding prevent the binding
as far as overload resolution is concerned?
Paragraph 4 says "Other restrictions
on binding a reference to a particular argument do not affect the formation
of a conversion sequence."  This was intended to refer to things like access
checking, but some readers have taken that to mean that any aspects of
reference binding not mentioned in this section do not preclude the binding.</P>

<P><B>Proposed resolution (10/01):</B></P>

<P>In 13.3.3.1.4 [over.ics.ref] paragraph 4 add the
indicated text:</P>
<BLOCKQUOTE>
Other restrictions on binding a reference to a particular argument <SPAN style="font-weight:bold;background-color:#A0FFA0">that
are not based on the types of the reference and the argument</SPAN> do
not  affect  the formation of a standard conversion sequence, however.
</BLOCKQUOTE>

<BR><BR><HR><A NAME="115"></A><H4>115.
  
Address of template-id
</H4><B>Section: </B>13.4&#160; [over.over]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>7 May 1999<BR>



<P>[Voted into WP at October 2003 meeting.]</P>



<PRE>
    template &lt;class T&gt; void f(T);
    template &lt;class T&gt; void g(T);
    template &lt;class T&gt; void g(T,T);

    int main()
    {
        (&amp;f&lt;int&gt;);
        (&amp;g&lt;int&gt;);
    }
</PRE>

The question is whether <TT>&amp;f&lt;int&gt;</TT> identifies a unique function.
<TT>&amp;g&lt;int&gt;</TT> is clearly ambiguous.

<P>13.4 [over.over]
 paragraph 1
says that a function template name is considered to name a
set of overloaded functions.  I believe it should be expanded to say that
a function template name with an explicit template argument list is also
considered to name a set of overloaded functions.</P>

<P>In the general case, you need to have a destination type in order
to identify a unique function.  While it is possible to permit this, I
don't think it is a good idea because such code depends on there only
being one template of that name that is visible.</P>

<P>The EDG front end issues an error on this use of "<TT>f</TT>".
egcs 1.1.1 allows
it, but the most current snapshot of egcs that I have also issues an error
on it.</P>

<P>It has been pointed out that when dealing with nontemplates, the rules
for taking the address of a single function differ from the rules
for an overload set, but this asymmetry is needed for C compatibility.
This need does not exist for the template case.</P>

<P>My feeling is that a general rule is better than a general rule plus
an exception.  The general rule is that you need a destination type
to be sure that the operation will succeed.  The exception is when
there is only one template in the set and only then when you provide
values for all of the template arguments.</P>

<P>It is true that in some cases you can provide a shorthand, but only if
you encourage a fragile coding style (that will cause programs to break
when additional templates are added).</P>

<P>I think the standard needs to specify one way or the other how this
case should be handled.  My recommendation would be that it is
ill-formed.</P>

<P><U>Nico Josuttis</U>: Consider the following example:</P>

<PRE>
    template &lt;int VAL&gt;
    int add (int elem)
    {
	return elem + VAL;
    }

    std::transform(coll.begin(), coll.end(),
		   coll.begin(),
		   add&lt;10&gt;);
</PRE>

<P>If John's recommendation is adopted, this code will become
ill-formed.  I bet there will be a lot of explanation for users
necessary why this fails and that they have to change
<TT>add&lt;10&gt;</TT> to something like
<TT>(int (*)(int))add&lt;10&gt;</TT>.</P>

<P>This example code is probably common practice because this
use of the STL is typical and is accepted in many current
implementations.  I strongly urge that this issue be resolved
in favor of keeping this code valid.</P>

<P><U>Bill Gibbons</U>:  I find this rather surprising.  Shouldn't
a <I>template-id</I> which specifies all of the template arguments
be treated like a declaration-only explicit instantiation,
producing a set of ordinary function declarations?  And when that
set happens to contain only one function, shouldn't the example
code work?</P>

<P>(See also <A HREF="
     cwg_defects.html#250">issue 250</A>.)</P>

<P><B>Notes from 04/01 meeting:</B></P>

<P>The consensus of the group was that the <TT>add</TT> example
should not be an error.</P>

<P><B>Proposed resolution (October 2002):</B></P>

<P>In 13.4 add to the end of paragraph 2:</P>
<BLOCKQUOTE>
[<I>Note:</I> As described in 14.8.1 [temp.arg.explicit],
if deduction fails and the
function template name is followed by an explicit template
argument list, the <I>template-id</I> is then examined to
see whether it identifies a single function template
specialization.  If it does, the <I>template-id</I> is
considered to be an lvalue for that function template
specialization.  The target type is not used in that
determination.]
</BLOCKQUOTE>

<P>
In 14.8.1 [temp.arg.explicit] paragraph 2 insert before
the first example:</P>
<BLOCKQUOTE>
In contexts where deduction is done and fails,
or in contexts where deduction is not done,
if a template argument list is specified and it, along with any
default template arguments, identifies a single function template
specialization, then the <I>template-id</I> is an lvalue
for the function template specialization.
</BLOCKQUOTE>

<P>
Change the first example of 14.8.1 [temp.arg.explicit] paragraph 2:</P>
<PRE>
  template&lt;class X, class Y&gt; X f(Y);
  void g()
  {
    int i = f&lt;int&gt;(5.6);    // Y <I>is deduced to be</I> double
    int j = f(5.6);         // <I>ill-formed:</I> X <I>cannot be deduced</I>
  }
</PRE>
to read:
<PRE>
  template&lt;class X, class Y&gt; X f(Y);
  void g()
  {
    int i = f&lt;int&gt;(5.6);    // Y <I>is deduced to be</I> double
    int j = f(5.6);         // <I>ill-formed:</I> X <I>cannot be deduced</I>
    f&lt;void&gt;(f&lt;int, bool&gt;);  // Y <I>for outer</I> f <I>deduced to be</I>
                            //   int (*)(bool)
    f&lt;void&gt;(f&lt;int&gt;);        // <I>ill-formed:</I> f&lt;int&gt; <I>does not denote a</I>
                            //   <I>single template function specialization</I>
  }
</PRE>

<P>
<B>Note:</B> This interacts with the resolution of
<A HREF="
     cwg_defects.html#226">issue 226</A> (default
template arguments for function templates).
</P>

<BR><BR><HR><A NAME="221"></A><H4>221.
  
Must compound assignment operators be member functions?
</H4><B>Section: </B>13.5.3&#160; [over.ass]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jim Hyslop
 &#160;&#160;&#160;

 <B>Date: </B>3 Apr 2000<BR>


<P>[Moved to DR at 4/01 meeting.]</P>

<P>Is the intent of 13.5.3 [over.ass] paragraph 1 that
<I>all</I> assignment operators be non-static member functions
(including <TT>operator+=</TT>, <TT>operator*=</TT>, etc.) or only
simple assignment operators (<TT>operator=</TT>)?</P>

<P><B>Notes from 04/00 meeting:</B></P>

<P>Nearly all references to "assignment operator" in the IS mean
<TT>operator=</TT> and not the compound assignment operators.  The ARM
was specific that this restriction applied only to <TT>operator=</TT>.
If it did apply to compound assignment operators, it would be
impossible to overload these operators for <TT>bool</TT> operands.</P>

<P><B>Proposed resolution (04/01):</B></P>

<OL>
<LI><P>Change the title of 5.17 [expr.ass] from "Assignment
operators" to "Assignment and compound assignment operators."</P></LI>

<LI><P>Change the first sentence of 5.17 [expr.ass]
paragraph 1 from</P>
<BLOCKQUOTE>

There are several assignment operators, all of which group
right-to-left.  All require a modifiable lvalue as their left operand,
and the type of an assignment expression is that of its left operand.
The result of the assignment operation is the value stored in the left
operand after the assignment has taken place; the result is an lvalue.

</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>

The assignment operator (<TT>=</TT>) and the compound assignment
operators all group right-to-left.  All require a modifiable lvalue as
their left operand and return an lvalue with the type and value of
the left operand after the assignment has taken place.

</BLOCKQUOTE>
</LI>
</OL>

<P><B>Additional note (10/00):</B> Paragraphs 2-6 of
5.17 [expr.ass] should all be understood to apply to
simple assignment only and not to compound assignment operators.</P>

<BR><BR><HR><A NAME="420"></A><H4>420.
  
postfixexpression-&gt;scalar_type_dtor() inconsistent
</H4><B>Section: </B>13.5.6&#160; [over.ref]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Markus Mauhart
 &#160;&#160;&#160;

 <B>Date: </B>8 June 2003<BR>


<P>[Voted into WP at April, 2006 meeting.]</P>

<P>Lets start with the proposed solution.
In 13.5.6 [over.ref], replace line ...
<BLOCKQUOTE>
<I>postfix-expression</I> <TT>-&gt;</TT> <I>id-expression</I>
</BLOCKQUOTE>
.... with the lines ...
<BLOCKQUOTE>
<I>postfix-expression</I> <TT>-&gt;</TT> <I>template<SUB>opt</SUB> id-expression</I><BR>
<I>postfix-expression</I> <TT>-&gt;</TT> <I>pseudo-destructor-name</I>
</BLOCKQUOTE>
(This then is a copy of the two lines in 5.2 [expr.post]
covering "-&gt;dtor")</P>
<P>Alternatively remove the sentence "It implements class member
access using -&gt;" and the syntax line following.</P>

<P>Reasons:</P>

<P>Currently stdc++ is inconsistent when handling expressions of
the form "postfixexpression-&gt;scalar_type_dtor()":
If "postfixexpression" is a pointer to the scalar type, it is OK,
but if "postfixexpression" refers to any smart pointer class
(e.g. iterator or allocator::pointer) with class specific
CLASS::operator-&gt;() returning pointer to the scalar type, then
it is ill-formed; so while c++98 does allow CLASS::operator-&gt;()
returning pointer to scalar type, c++98 prohibits any '-&gt;'-expression
involving this overloaded operator function.</P>

<P>Not only is this behaviour inconsistent, but also when
comparing the corresponding chapters of c++pl2 and stdc++98
it looks like an oversight and unintended result.
Mapping between stdc++98 and c++pl2:
<BLOCKQUOTE>
  c++pl2.r.5.2 -&gt; 5.2 [expr.post]<BR>
  c++pl2.r.5.2.4 -&gt; 5.2.4 [expr.pseudo] + 5.2.5 [expr.ref]<BR>
  c++pl2.r.13.4 -&gt; 13.3.1.2 [over.match.oper]<BR>
  c++pl2.r.13.4.6 -&gt; 13.5.6 [over.ref]
</BLOCKQUOTE>
For the single line of c++pl2.r.5.2 covering "-&gt;dtor",
5.2 [expr.post] has two lines.
Analogously c++pl2.r.5.2.4 has been doubled to 5.2.4 [expr.pseudo]
and 5.2.5 [expr.ref].
From 13.5.6 [over.ref], the sentence forbiding CLASS::operator-&gt;()
returning pointer to scalar type has been removed.
Only the single line of c++pl2.r.13.4.6 (&lt;-&gt; c++pl2.r.5.2's
single line) has not gotten its 2nd line when converted
into 13.5.6 [over.ref].</P>

<P>Additionally GCC32 does is right (but against 13.5.6 [over.ref]).</P>

<P>AFAICS this would not break old code except compilers like VC7x
and Comeau4301.</P>

<P>It does not add new functionality, cause any expression
class_type-&gt;scalar_type_dtor() even today can be substituted
through (*class_type).scalar_type_dtor().</P>

<P>Without this fix, template functions like
some_allocator&lt;T&gt;::destroy(p)
must use "(*p).~T()" or "(*p).T::~T()" when calling the destructor,
otherwise the simpler versions "p-&gt;~T()" or "p-&gt;T::~T()"
could be used.</P>

<P>Sample code, compiled with GCC32, VC7[1] and Comeau4301:</P>
<PRE>
struct A {};//any class

template &lt;class T&gt;
struct PTR
    {
    T&amp; operator*  () const;
    T* operator-&gt; () const;
    };

template &lt;class T&gt;
void f ()
    {
        {
        T*  p               ;
        p = new T           ;
        (*p).T::~T()        ;//OK
        p = new T           ;
        (*p).~T()           ;//OK
        p = new T           ;
        p-&gt;T::~T()          ;//OK
        p = new T           ;
        p-&gt;~T()             ;//OK
        }

        {
        PTR&lt;T&gt; p = PTR&lt;T&gt;() ;
        (*p).T::~T()        ;//OK
        (*p).~T()           ;//OK
        p.operator-&gt;()      ;//OK !!!
        p-&gt;T::~T()          ;//GCC32: OK; VC7x,Com4301: OK for A; ERROR w/ int
        p-&gt;~T()             ;//GCC32: OK; VC7x,Com4301: OK for A; ERROR w/ int
        }
    }

void test ()
    {
    f &lt;A&gt;  ();
    f &lt;int&gt;();
    }
</PRE>

<P><B>Proposed resolution (April, 2005):</B></P>

<P>Change 13.5.6 [over.ref] paragraph 1 as indicated:</P>

<BLOCKQUOTE>

<P><TT>operator-&gt;</TT> shall be a non-static member function taking
no parameters. It implements <SPAN style="font-weight:bold;background-color:#A0FFA0">the</SPAN> class member
access <SPAN style="text-decoration:line-through;background-color:#FFA0A0">using</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">syntax that uses</SPAN> <TT>-&gt;</TT></P>

<UL>
<I>postfix-expression</I> <TT>-&gt;</TT> <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>template</TT><SUB><I><SMALL>opt</SMALL></I></SUB></SPAN> <I>id-expression</I><BR>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>postfix-expression</I> <TT>-&gt;</TT> <I>pseudo-destructor-name</I></SPAN>
</UL>

<P>An expression <TT>x-&gt;m</TT> is interpreted
as <TT>(x.operator-&gt;())-&gt;m</TT> for a class object <TT>x</TT> of
type <TT>T</TT> if <TT>T::operator-&gt;()</TT> exists and if the
operator is selected as the best match function by the overload
resolution mechanism (13.3 [over.match]).</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="425"></A><H4>425.
  
Set of candidates for overloaded built-in operator with float operand
</H4><B>Section: </B>13.6&#160; [over.built]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Frey
 &#160;&#160;&#160;

 <B>Date: </B>30 June 2003<BR>


<P>[Voted into WP at March 2004 meeting.]</P>



<P>During a discussion over at the boost mailing list (www.boost.org), we
came across the following "puzzle":</P>
<PRE>
  struct A {
    template&lt; typename T &gt; operator T() const;
  } a;

  template&lt;&gt; A::operator float() const
  {
    return 1.0f;
  }

  int main()
  {
    float f = 1.0f * a;
  }
</PRE>
<P>The code is compiled without errors or warnings from EDG-based compilers
(Comeau, Intel), but rejected from others (GCC, MSVC [7.1]). The
question: Who is correct? Where should I file the bug report?</P>

<P>To explain the problem: The EDG seems to see 1.0f*a as a call to the
unambiguous operator*(float,float) and thus casts 'a' to 'float'. The
other compilers have several operators (float*float, float*double,
float*int, ...) available and thus can't decide which cast is
appropriate. I think the latter is the correct behaviour, but I'd like
to hear some comments from the language lawyers about the standard's
point of view on this problem.</P>

<P><U>Andreas Hommel:</U>
Our compiler also rejects this code:</P>
<PRE>
Error   : function call 'operator*(float, {lval} A)' is ambiguous
'operator*(float, unsigned long long)'
'operator*(float, int)'
'operator*(float, unsigned int)'
'operator*(float, long)'
'operator*(float, unsigned long)'
'operator*(float, float)'
'operator*(float, double)'
'operator*(float, long double)'
'operator*(float, long long)'
Test.cp line 12       float f = 1.0f * a;
</PRE>
<P>Is this example really legal? It was my understanding that all candidates
from 13.6 [over.built] participate in overload resolution.</P>

<P><U>Daveed Vandevoorde:</U>
I believe the EDG-based compiler is right.  Note that the built-in operator*
requires "usual arithmetic conversions" (see
5.6 [expr.mul] paragraph 2 and
5 [expr] paragaph 9). This means that
there is no candidate taking (float, double) arguments: Only (float, float)
or
(double, double).</P>

<P>Since your first argument is of type float, the (float, float) case is
preferred
over the (double, double) case (the latter would require a floating-point
promotion).</P>

<P><U>Stave Adamczyk:</U>
Daveed's statement is wrong; as Andreas says, the prototypes in
13.6 [over.built] paragraph 12
have pairs of types, not the same type twice.  However, the list of
possibilities considered in Andreas' message is wrong also:
13.6 [over.built] paragraph 12
calls for pairs of <B>promoted</B> arithmetic types, and float is not
a promoted type (it promotes to double -- see
4.6 [conv.fpprom]).</P>

<P>Nevertheless, the example is ambiguous.  Let's look at the overload
resolution costs.  The right operand is always going to have a
user-defined-conversion cost (the template conversion function
will convert directly to the const version of the second
parameter of the prototype).  The left operand is always going to
have a promotion (float --&gt; double) or a standard conversion
(anything else).  So the cases with promotions are better 
than the others.  However, there are several of those
cases, with second parameters of type int, unsigned int, long,
unsigned long, double, and long double, and all of those are
equally good.  Therefore the example is ambiguous.</P>

<P>Here's a reduced version that should be equivalent:</P>
<PRE>
  struct A {
    template &lt;typename T&gt; operator T() const;
  } a;
  void f(double, int);
  void f(double, unsigned int);
  void f(double, long);
  void f(double, unsigned long);
  void f(double, double);
  void f(double, long double);
  int main() {
    f(1.0f, a);  // Ambiguous
  }
</PRE>
<P>Personally, I think this is evidence that
13.6 [over.built] doesn't really
do quite what it should.  But the standard is clear, if possibly
flawed.</P>

<P><U>Andreas Hommel:</U>
You are right, "float" is not a promoted arithmetic type, this is a bug in
our compiler.</P>

<P>However, the usual arithmetic conversions
(5 [expr] paragraph 9) do not promote the floating
point types, so
<PRE>
  float operator+(float, float);
</PRE>
is a legal built-in operator function, so I wonder if it shouldn't be
included in the candidate list.</P>

<P><U>Steve Adamczyk:</U> Hmm, the definition of the term in
13.6 [over.built] paragraph 2 is highly ambiguous:
<BLOCKQUOTE>
  Similarly, the  term  promoted  arithmetic type refers to promoted 
  integral types plus floating types.
</BLOCKQUOTE>
I can't tell if that's "promoted integral types plus (all) floating
types" or "promoted integral types plus (promoted) floating types".
I thought the latter was intended, but indeed the usual arithmetic
conversions could give you "float + float", so it makes sense that
float would be one of the possibilities.  We should discuss this to
make sure everyone has the same interpretation.</P>

<P><B>Proposed Resolution (October 2003):</B></P>

<P>Change the second sentence of 13.6 paragraph 2 as follows:</P>
<BLOCKQUOTE>
Similarly, the term <I>promoted arithmetic type</I> refers
to <SPAN style="text-decoration:line-through;background-color:#FFA0A0">promoted integral types plus floating types</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">floating types plus promoted integral types</SPAN>.
</BLOCKQUOTE>

<BR><BR><HR><A NAME="204"></A><H4>204.
  
Exported class templates
</H4><B>Section: </B>14&#160; [temp]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Robert Klarer
 &#160;&#160;&#160;

 <B>Date: </B>11 Feb 2000<BR>



<P>[Voted into WP at April 2003 meeting.]</P>

<P>14 [temp]
 paragraph 7 allows class
templates to be declared exported, including member classes and member
class templates (implicitly by virtue of exporting the
containing template class).  However, paragraph 8 does not exclude
exported class templates from the statement that</P>

<BLOCKQUOTE>
An exported template need only be declared (and not necessarily
defined) in a translation unit in which it is instantiated.
</BLOCKQUOTE>

This is an incorrect implication; however, it is also not dispelled in
14.7.1 [temp.inst]
 paragraph 6:

<BLOCKQUOTE>
If an implicit instantiation of a class template specialization is
required and the template is declared but not defined, the program is
ill-formed.
</BLOCKQUOTE>

This wording says nothing about the translation unit in which the
definition must be provided.  Contrast this with
14.7.2 [temp.explicit]
 paragraph 3:

<BLOCKQUOTE>
A definition of a class template or a class member template shall be
in scope at the point of the explicit instantiation of the class
template or class member template.
</BLOCKQUOTE>

<P><B>Suggested resolution:</B></P>

<BR><UL>
<LI>Change 14 [temp]
 paragraph 8 to say
that "An exported <SPAN style="font-weight:bold;background-color:#A0FFA0">non-class</SPAN> template need only be declared..."</LI>

<LI>Change 14.7.1 [temp.inst]
 paragraph 6 to
use wording similar to that of
14.7.2 [temp.explicit]
 paragraph 3 regarding
the requirement for a definition of the class template to be in scope.</LI>
</UL>

<P>(See also <A HREF="
     cwg_active.html#212">issue 212</A>.)</P>

<P><B>Notes from 04/00 meeting:</B></P>

<P>John Spicer opined that even though 14 [temp]
paragraph 7 speaks of "declaring a class template exported," that does
not mean that the class template is "an exported template" in the
sense of paragraph 8.  He suggested clarifying paragraph 7 to that
effect instead of the change to paragraph 8 suggested above, and
questioned the need for a change to 14.7.1 [temp.inst].</P>

<P><B>Notes from the 4/02 meeting:</B></P>

<P>This is resolved by the proposed changes for
<A HREF="
     cwg_defects.html#323">issue 323</A>.</P>

<BR><BR><HR><A NAME="323"></A><H4>323.
  
Where must <TT>export</TT> appear?
</H4><B>Section: </B>14&#160; [temp]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>14 Nov 2001<BR>


<P>[Voted into WP at April 2003 meeting.]</P>



<P>The standard doesn't seem to describe whether the keyword <TT>export</TT>
should appear on exported template declarations that are not used or
defined in that particular translation unit.</P>

<P>For example:</P>
<PRE>
  // File 1:
  template&lt;typename T&gt; void f();  // export omitted

  // File 2:
  export template&lt;typename T&gt; void f() {}

  int main() { f&lt;int&gt;(); }
</PRE>
<P>Another example is:</P>
<PRE>
  // File 1:
  struct S {
     template&lt;typename T&gt; void m();
  };

  // File 2:
  struct S {
     template&lt;typename T&gt; void m();
  };

  export template&lt;typename T&gt; void S::m() {}

  int main() {
     S s;
     S.m&lt;int&gt;();
  }
</PRE>

<P>I think both examples should be clarified to be invalid.  If a template is 
exported in one translation unit, it should be declared export in all 
translation units in which it appears.</P>

<P>With the current wording, it seems that even the following is valid:</P>
<PRE>
  // File 1:
  export template&lt;typename T&gt; void f();  // export effectively ignored

  // File 2:
  template&lt;typename T&gt; void f() {}  // Inclusion model
  void g() { f&lt;int&gt;(); }

  // File 3:
  void g();
  template&lt;typename T&gt; void f() {}  // Inclusion model

  int main() {
     g();
     f&lt;int&gt;();
  }
</PRE>
 
<P>In fact, I think the declaration in "File 1" could be a definition and this
would still satisfy the the requirements of the standard, which definitely
seems wrong.</P>

<P><B>Proposed Resolution (revised October 2002):</B></P>

<P>Replace 14 [temp] paragraphs 6, 7, and 8 by the
following text:</P>
<BLOCKQUOTE>
<P>
A <I>template-declaration</I> may be preceded by the <TT>export</TT> keyword.
Such a template is said to be <I>exported</I>.
Declaring exported a class template is equivalent to declaring
exported all of its non-inline member functions, static data members, 
member classes, member class templates, and non-inline member function 
templates.</P>
<P> If a template is exported in one translation unit, it
shall be exported in all translation units in which
it appears; no diagnostic is required.
A declaration of an exported template shall appear with the <TT>export</TT>
keyword before any point of instantiation (14.6.4.1 [temp.point])
of that template in that translation unit.  In addition, the first
declaration of an exported template containing the <TT>export</TT> keyword
must not follow the definition of that template.  The <TT>export</TT>
keyword shall not be used in a friend declaration.</P>
<P> Templates defined in an unnamed namespace, inline functions, and
inline function templates shall not be exported.
An exported non-class template shall be defined only once in a program;
no diagnostic is required. An exported non-class template
need only be declared (and not necessarily defined) in a translation
unit in which it is instantiated.</P>
<P>A non-exported non-class template must be defined in every translation unit
in which it is implicitly instantiated (14.7.1 [temp.inst]),
unless the corresponding
specialization is explicitly instantiated (14.7.2 [temp.explicit])
in some translation unit; no diagnostic is required.</P>
</BLOCKQUOTE>

<P> Note: This change also resolves issues <A HREF="
     cwg_defects.html#204">204</A>
and <A HREF="
     cwg_defects.html#335">335</A>.</P>

<BR><BR><HR><A NAME="335"></A><H4>335.
  
Allowing <TT>export</TT> on template members of nontemplate classes
</H4><B>Section: </B>14&#160; [temp]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>30 Jan 2002<BR>


<P>[Voted into WP at April 2003 meeting.]</P>



<P>The syntax for "export" permits it only on template declarations.
Clause 14 [temp] paragraph 6 further restricts "export"
to appear only
on namespace scope declarations.  This means that you can't export
a member template of a non-template class, as in:
<PRE>
  class A {
    template &lt;class T&gt; void f(T);
  };
</PRE>
You can, of course, put export on the definition:
<PRE>
  export template &lt;class T&gt; void A&lt;T&gt;::f(T){}
</PRE>
but in order for the template to be used from other translation units
(the whole point of export) the declaration in the other translation
unit must also be declared export.</P>

<P>There is also the issue of whether or not we should permit this usage:
<PRE>
  export struct A {
    template &lt;class T&gt; void f(T);
  };
</PRE>
My initial reaction is to retain this prohibition as all current uses
of "export" are preceding the "template" keyword.</P>

<P>If we eliminate the requirement that "export" precede "template" there
is a similar issue regarding this case, which is currently prohibited:
<PRE>
  template &lt;class T&gt; struct B {
    export void f();
  };
</PRE>
My preference is still to permit only "export template".</P>

<P><B>Notes from the 4/02 meeting:</B></P>

<P>This is resolved by the proposed changes for
<A HREF="
     cwg_defects.html#323">issue 323</A>.</P>

<BR><BR><HR><A NAME="534"></A><H4>534.
  
<I>template-name</I>s and <I>operator-function-id</I>s
</H4><B>Section: </B>14&#160; [temp]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jens Maurer
 &#160;&#160;&#160;

 <B>Date: </B>5 October 2005<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>

<P>Taken literally, 14 [temp] paragraph 2 does not
permit operator functions to be templates:</P>

<BLOCKQUOTE>

In a function template declaration, the <I>declarator-id</I> shall be a
<I>template-name</I> (i.e., not a <I>template-id</I>).

</BLOCKQUOTE>

<P>and, in <section-ref ref="14.2">14.2 [temp.names]</section-ref> paragraph 1, a <I>template-name</I>
is defined to be simply an <I>identifier</I>.</P>

<P><A HREF="
     cwg_defects.html#301">Issue 301</A> considered and rejected the
idea of changing the definition of <I>template-name</I> to include
<I>operator-function-id</I>s and <I>conversion-function-id</I>s.
Either that decision should be reconsidered or the various references
in the text to <I>template-name</I> should be examined to determine
if they should also mention the non-<I>identifier</I> possibilities
for function template names.</P>

<P><B>Proposed resolution (April, 2006):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#301">issue 301</A>.</P>

<BR><BR><HR><A NAME="184"></A><H4>184.
  
Default arguments in template <I>template-parameter</I>s
</H4><B>Section: </B>14.1&#160; [temp.param]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>11 Nov 1999<BR>



<P>[Voted into WP at April 2003 meeting.]</P>



<P><U>John Spicer</U>:
Where can default values for the template parameters of
template template parameters be specified and where so they apply?</P>

<P>For normal template parameters, defaults can be specified only in
class template declarations and definitions, and they accumulate
across multiple declarations in the same way that function default
arguments do.</P>

<P>I think that defaults for parameters of template template parameters should
be handled differently, though.  I see no reason why such a default should
extend beyond the template declaration with which it is associated.
In other words, such defaults are a property of a specific template
declaration and are not part of the interface of the template.</P>

<PRE>
    template &lt;class T = float&gt; struct B {};

    template &lt;template &lt;class _T = float&gt; class T&gt; struct A {
        inline void f();
        inline void g();
    };

    template &lt;template &lt;class _T&gt; class T&gt; void A&lt;T&gt;::f() {
        T&lt;&gt; t;  // Okay? (proposed answer - no)
    }

    template &lt;template &lt;class _T = char&gt; class T&gt; // Okay? (proposed answer - yes)
    void A&lt;T&gt;::g() {
        T&lt;&gt; t;  // T&lt;char&gt; or T&lt;float&gt;?  (proposed answer - T&lt;char&gt;)
    }

    int main() {
        A&lt;B&gt; ab;
        ab.f();
    }
</PRE>

<P>I don't think this is clear in the standard.</P>

<P><U>Gabriel Dos Reis</U>:
On the other hand I fail to see the reasons why we should introduce
yet another special rule to handle that situation differently.  I
think we should try to keep rules as uniform as possible.
For default values, it has been the case that one
should look for any declaration specifying default values.  Breaking
that rules doesn't buy us anything, at least as far as I can see.
My feeling is that [allowing different defaults in different
declarations] is very confusing.</P>

<P><U>Mike Miller</U>:
I'm with John on this one.  Although we don't have the
concept of "prototype scope" for template parameter lists,
the analogy with function parameters would suggest that the
two declarations of <TT>T</TT> (in the template class definition and
the template member function definition) are separate
declarations and completely unrelated.  While it's true that
you accumulate default arguments on top-level declarations in
the same scope, it seems to me a far leap to say that we ought
also to accumulate default arguments in nested declarations.
I would expect those to be treated as being in different
scopes and thus <B>not</B> to share default argument information.</P>

<P>When you look up the name <TT>T</TT> in the definition of
<TT>A&lt;T&gt;::f()</TT>,
the declaration you find has no default argument for the
parameter of <TT>T</TT>, so <TT>T&lt;&gt;</TT> should not be allowed.</P>

<P><B>Proposed Resolution (revised October 2002):</B></P>

<P>
In 14.1 [temp.param], add the following as a new paragraph
at the end of this section:</P>

<BLOCKQUOTE>
A <I>template-parameter</I> of a template <I>template-parameter</I>
is permitted to have a default <I>template-argument</I>.  When such
default arguments are specified, they apply to the template
<I>template-parameter</I> in the scope of the template
<I>template-parameter</I>.  [<I>Example:</I>
<PRE>
    template &lt;class T = float&gt; struct B {};

    template &lt;template &lt;class TT = float&gt; class T&gt; struct A {
        inline void f();
        inline void g();
    };

    template &lt;template &lt;class TT&gt; class T&gt; void A&lt;T&gt;::f() {
        T&lt;&gt; t;  // error - TT has no default template argument
    }

    template &lt;template &lt;class TT = char&gt; class T&gt;void A&lt;T&gt;::g() {
        T&lt;&gt; t;  // OK - T&lt;char&gt;
    }
</PRE>
<I>-- end example</I>]
</BLOCKQUOTE>

<BR><BR><HR><A NAME="215"></A><H4>215.
  
Template parameters are not allowed in <I>nested-name-specifier</I>s
</H4><B>Section: </B>14.1&#160; [temp.param]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Martin von Loewis
 &#160;&#160;&#160;

 <B>Date: </B>13 Mar 2000<BR>


<P>[Voted into WP at April, 2007 meeting.]</P>

<P>According to 14.1 [temp.param] paragraph 3, the following
fragment is ill-formed:</P>

<PRE>
    template &lt;class T&gt;
    class X{
      friend void T::foo();
    };
</PRE>

<P>In the friend declaration, the <TT>T::</TT> part is a
<I>nested-name-specifier</I> (8 [dcl.decl] paragraph 4),
and <TT>T</TT> must be a <I>class-name</I> or a <I>namespace-name</I>
(5.1.1 [expr.prim.general] paragraph 7). However, according to
14.1 [temp.param] paragraph 3, it is only a
<I>type-name</I>. The fragment should be well-formed, and
instantiations of the template allowed as long as the actual template
argument is a class which provides a function member <TT>foo</TT>. As
a result of this defect, any usage of template parameters in nested
names is ill-formed, e.g., in the example of 14.6 [temp.res] paragraph 2.</P>

<P><B>Notes from 04/00 meeting:</B></P>

<P>The discussion at the meeting revealed a self-contradiction in the
current IS in the description of <I>nested-name-specifier</I>s.
According to the grammar in 5.1.1 [expr.prim.general] paragraph 7,
the components of a <I>nested-name-specifier</I> must be either
<I>class-name</I>s or <I>namespace-name</I>s, i.e., the constraint is
syntactic rather than semantic.  On the other hand, 3.4.3 [basic.lookup.qual] paragraph 1 describes a semantic constraint: only
object, function, and enumerator names are ignored in the lookup for
the component, and the program is ill-formed if the lookup finds
anything other than a <I>class-name</I> or <I>namespace-name</I>.  It
was generally agreed that the syntactic constraint should be
eliminated, i.e., that the grammar ought to be changed not to use
<I>class-or-namespace-name</I>.</P>

<P>A related point is the explicit prohibition of use of template
parameters in <I>elaborated-type-specifier</I>s in 7.1.6.3 [dcl.type.elab] paragraph 2.  This rule was the result of an
explicit Committee decision and should not be unintentionally voided
by the resolution of this issue.</P>

<P><B>Proposed resolution (04/01):</B></P>

<P>Change 5.1.1 [expr.prim.general] paragraph 7 and
A.4 [gram.expr] from</P>

<UL>
<I>nested-name-specifier</I>:
<UL><I>class-or-namespace-name</I> <TT>::</TT> <I>nested-name-specifier<SUB>opt</SUB></I></UL>
<UL><I>class-or-namespace-name</I> <TT>:: template</TT> <I>nested-name-specifier</I></UL>
</UL>
<UL><I>class-or-namespace-name</I>:
<UL><I>class-name</I></UL>
<UL><I>namespace-name</I></UL>
</UL>

<P>to</P>

<UL>
<I>nested-name-specifier</I>:
<UL><I>type-or-namespace-name</I> <TT>::</TT> <I>nested-name-specifier<SUB>opt</SUB></I></UL>
<UL><I>type-or-namespace-name</I> <TT>:: template</TT> <I>nested-name-specifier</I></UL>
</UL>
<UL>
<I>type-or-namespace-name</I>:
<UL><I>type-name</I></UL>
<UL><I>namespace-name</I></UL>
</UL>

<P>This resolution depends on the resolutions for issues
<A HREF="
     cwg_defects.html#245">245</A> (to change the name lookup rules in
<I>elaborated-type-specifier</I>s to include all <I>type-name</I>s)
and <A HREF="
     cwg_defects.html#283">283</A> (to categorize template
<I>type-parameter</I>s as <I>type-name</I>s).</P>

<P><B>Notes from 10/01 meeting:</B></P>

<P>There was some sentiment for going with simply <I>identifier</I>
in front of the "<TT>::</TT>", and stronger sentiment for going
with something with a more descriptive name if possible.
See also <A HREF="
     cwg_defects.html#180">issue 180</A>.</P>

<P><B>Notes from April 2003 meeting:</B></P>

<P>This was partly resolved by the changes for <A HREF="
     cwg_defects.html#125">issue
125</A>.  However, we also need to add a semantic check in
3.4.3 [basic.lookup.qual] to allow <TT>T::foo</TT> and we need to
reword the first sentence of 3.4.3 [basic.lookup.qual].</P>

<P><B>Proposed resolution (October, 2004):</B></P>

<P>Change 3.4.3 [basic.lookup.qual] paragraph 1 as
follows:</P>

<BLOCKQUOTE>

The name of a class or namespace member can be referred to after
the <TT>::</TT> scope resolution operator (5.1.1 [expr.prim.general]) applied to a <I>nested-name-specifier</I> that
nominates its class or namespace. During the lookup for a name
preceding the <TT>::</TT> scope resolution operator, object,
function, and enumerator names are ignored. If the name found
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">is not a <I>class-name</I> (clause 9 [class]) or
<I>namespace-name</I> (7.3.1 [namespace.def])</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">does
not designate a class or namespace</SPAN>, the program is
ill-formed. [...]

</BLOCKQUOTE>

<P><B>Notes from the April, 2005 meeting:</B></P>

<P>The 10/2004 resolution does not take into account the fact that
template type parameters do not designate class types in the context
of the template definition.  Further drafting is required.
</P>

<P><B>Proposed resolution (April, 2006):</B></P>

<P>Change 3.4.3 [basic.lookup.qual] paragraph 1 as
follows:</P>

<BLOCKQUOTE>

The name of a class or namespace member can be referred to after
the <TT>::</TT> scope resolution operator (5.1.1 [expr.prim.general]) applied to a <I>nested-name-specifier</I> that
nominates its class or namespace. During the lookup for a name
preceding the <TT>::</TT> scope resolution operator, object,
function, and enumerator names are ignored. If the name found
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">is not a <I>class-name</I> (clause 9 [class]) or
<I>namespace-name</I> (7.3.1 [namespace.def])</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">does
not designate a namespace or a class or dependent type</SPAN>, the program is
ill-formed. [...]

</BLOCKQUOTE>

<BR><BR><HR><A NAME="226"></A><H4>226.
  
Default template arguments for function templates
</H4><B>Section: </B>14.1&#160; [temp.param]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Bjarne Stroustrup
 &#160;&#160;&#160;

 <B>Date: </B>19 Apr 2000<BR>


<P>[Voted into WP at April 2003 meeting.]</P>

<P>The prohibition of default template arguments for function
templates is a misbegotten remnant of the time where freestanding
functions were treated as second class citizens and required all 
template arguments to be deduced from the function arguments
rather than specified.
</P>

<P>The restriction seriously cramps programming style by unnecessarily making 
freestanding functions different from member functions, thus making it harder 
to write STL-style code.</P>

<P><B>Suggested resolution:</B></P>

<P>Replace</P>

<BLOCKQUOTE>

A default <I>template-argument</I> shall not be specified in a
function template declaration or a function template definition, nor
in the <I>template-parameter-list</I> of the definition of a member of
a class template.

</BLOCKQUOTE>

<P>by</P>

<BLOCKQUOTE>

A default <I>template-argument</I> shall not be specified in the
<I>template-parameter-list</I> of the definition of a member of a
class template.

</BLOCKQUOTE>

<P>The actual rules are as stated for arguments to class templates.
</P>

<P><B>Notes from 10/00 meeting:</B></P>

<P>The core language working group was amenable to this change.
Questions arose, however, over the interaction between default
template arguments and template argument deduction: should it be
allowed or forbidden to specify a default argument for a deduced
parameter?  If it is allowed, what is the meaning: should one or
the other have priority, or is it an error if the default and
deduced arguments are different?</P>

<P><B>Notes from the 10/01 meeting:</B></P>

<P>It was decided that default arguments should be allowed on friend
declarations only when the declaration is a definition.  It was
also noted that it is not necessary to insist that if there
is a default argument for a given parameter all following parameters
have default arguments, because (unlike in the class case)
arguments can be deduced if they are not specified.</P>

<P>Note that there is an interaction with
<A HREF="
     cwg_defects.html#115">issue 115</A>.</P>

<P><B>Proposed resolution (revised October 2002):</B></P>

<OL>
<LI>
<P>In 14.1 [temp.param] paragraph 9, replace</P>

<BLOCKQUOTE>
A default <I>template-argument</I> may be specified in a class
template declaration or a class template definition.  A default
<I>template-argument</I> shall not be specified in a function
template declaration or a function template definition, nor in the
<I>template-parameter-list</I> of the definition of a member of a
class template.
</BLOCKQUOTE>

<P>with</P>

<BLOCKQUOTE>
A default <I>template-argument</I> may be specified in a template
declaration.  A default
<I>template-argument</I> shall not be specified in the
<I>template-parameter-list</I>s of the definition of a member
of a class template that appears outside of the member's class.
</BLOCKQUOTE>

</LI>

<LI>
<P>In 14.1 [temp.param] paragraph 9, replace</P>

<BLOCKQUOTE>
A default <I>template-argument</I> shall not be specified in a friend template
declaration.
</BLOCKQUOTE>

<P>with</P>

<BLOCKQUOTE>
A default <I>template-argument</I> shall not be specified in a friend
class template declaration.  If a friend function template declaration
specifies a default <I>template-argument</I>, that declaration shall be
a definition and shall be the only declaration of the function template
in the translation unit.
</BLOCKQUOTE>

</LI>

<LI>
<P>In 14.1 [temp.param] paragraph 11, replace</P>

<BLOCKQUOTE>
If a <I>template-parameter</I> has a default <I>template-argument</I>,
all subsequent <I>template-parameters</I> shall have a default
<I>template-argument</I> supplied.
</BLOCKQUOTE>

<P>with</P>

<BLOCKQUOTE>
If a <I>template-parameter</I> of a class template has a default
<I>template-argument</I>, all subsequent <I>template-parameters</I>
shall have a default <I>template-argument</I> supplied.
[<I>Note:</I> This is not a requirement for function templates
because template arguments might be deduced (14.8.2 [temp.deduct]).]
</BLOCKQUOTE>
</LI>

<LI>
<P>In 14.8 [temp.fct.spec] paragraph 1, replace</P>

<BLOCKQUOTE>
Template arguments can either be explicitly specified when
naming the function template specialization or be deduced
(14.8.2 [temp.deduct]) from the context, e.g. from the
function arguments in a call to the function template
specialization.
</BLOCKQUOTE>

<P>with</P>

<BLOCKQUOTE>
Template arguments can be explicitly specified when naming the
function template specialization, deduced from the context
(14.8.2 [temp.deduct]), e.g., deduced from the function
arguments in a call to the function template specialization), or
obtained from default template arguments.
</BLOCKQUOTE>

</LI>

<LI>
<P>In 14.8.1 [temp.arg.explicit] paragraph 2, replace</P>

<BLOCKQUOTE>
Trailing template arguments that can be deduced
(14.8.2 [temp.deduct]) may be omitted from the list
of explicit <I>template-argument</I>s.
</BLOCKQUOTE>

<P>with</P>

<BLOCKQUOTE>
Trailing template arguments that can be deduced
(14.8.2 [temp.deduct]) or obtained from default
<I>template-argument</I>s may be omitted from the list of
explicit <I>template-argument</I>s.
</BLOCKQUOTE>

</LI>

<LI>
<P>In 14.8.2 [temp.deduct] paragraph 1, replace</P>

<BLOCKQUOTE>
The values can be either explicitly specified or, in some
cases, deduced from the use.
</BLOCKQUOTE>

<P>with</P>

<BLOCKQUOTE>
The values can be explicitly specified or, in some cases,
be deduced from the use or obtained from default
<I>template-argument</I>s.
</BLOCKQUOTE>

</LI>

<LI>
<P>In 14.8.2 [temp.deduct] paragraph 4, replace</P>

<BLOCKQUOTE>
The resulting substituted and adjusted function type is used as
the type of the function template for template argument
deduction.  When all template arguments have been deduced, all
uses of template parameters in nondeduced contexts are replaced
with the corresponding deduced argument values.  If the
substitution results in an invalid type, as described above,
type deduction fails.
</BLOCKQUOTE>

<P>with</P>

<BLOCKQUOTE>
<P>The resulting substituted and adjusted function type is used as
the type of the function template for template argument
deduction.  If a template argument has not been deduced, its
default template argument, if any, is used.  [<I>Example:</I>
</P>

<PRE>
    template &lt;class T, class U = double&gt;
    void f(T t = 0, U u = 0);

    void g()
    {
        f(1, 'c');         // f&lt;int,char&gt;(1,'c')
        f(1)               // f&lt;int,double&gt;(1,0)
        f();               // error: T cannot be deduced
        f&lt;int&gt;();          // f&lt;int,double&gt;(0,0)
        f&lt;int,char&gt;();     // f&lt;int,char&gt;(0,0)
    }
</PRE>

<P>---<I>end example</I>]</P>

<P>When all template arguments have been deduced or obtained from
default template arguments, all uses of template parameters in
nondeduced contexts are replaced with the corresponding deduced
or default argument values.  If the substitution results in an
invalid type, as described above, type deduction fails.</P>
</BLOCKQUOTE>
</LI>
</OL>

<BR><BR><HR><A NAME="401"></A><H4>401.
  
When is access for template parameter default arguments checked?
</H4><B>Section: </B>14.1&#160; [temp.param]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>27 Jan 2003<BR>


<P>[Voted into WP at October 2005 meeting.]</P>

<P>Is the following well-formed?</P>
<PRE>
  class policy {};
  class policy_interface {};
  template &lt;class POLICY_INTERFACE&gt;
  class aph {
  protected:
    typedef POLICY_INTERFACE PI;
  };
  template &lt;class POLICY, class BASE, class PI = typename BASE::PI&gt;
  class ConcretePolicyHolder : public BASE, protected POLICY
  {};
  ConcretePolicyHolder &lt; policy , aph &lt; policy_interface &gt; &gt; foo;
  void xx() { }
</PRE>
<P>The issue is whether the access to the default argument type BASE::PI
is checked before or after it is known that BASE is a base class of
the template. To some extent, one needs to develop the list of
template arguments (and therefore evaluate the default argument)
before one can instantiate the template, and
one does not know what base classes the template has until it has
been instantiated.</P>

<P><B>Notes from April 2003 meeting:</B></P>

<P>Shortened example:</P>
<PRE>
  class B {
  protected:
    typedef int A;
  };
  template&lt;class T, class U = typename T::A&gt;
  class X : public T
  { };
</PRE>

<P>The convincing argument here is that if we had only the declaration
of the template (including the default argument), we would expect
it to be usable in exactly the same way as the version with the
definition.  However, the special access needed is visible only
when the definition is available.  So the above should be an error,
and information from the definition cannot affect the access of
the default arguments.</P>

<P><B>Proposed Resolution (April 2003):</B></P>

<P> Add a new paragraph 16 to 14.1 [temp.param] after
paragraph 15:</P>
<BLOCKQUOTE>
Since a default <I>template-argument</I> is encountered before any
<I>base-clause</I> there is no special access to members used in a default
<I>template-argument</I>.  <I>[Example:</I>
<PRE>
  class B {};
  template &lt;class T&gt; class C {
  protected:
     typedef T TT;
  };

  template &lt;class U, class V = typename U::TT&gt;
  class D : public U {};

  D &lt;C&lt;B&gt; &gt; d;  // access error, C::TT is protected
</PRE>
<I>--- end example]</I>
</BLOCKQUOTE>

<P><B>Notes from October 2003 meeting:</B></P>

<P>We decided that template parameter default arguments should
have their access checked in the context where they appear
without special access for the entity declared (i.e., they are
different than normal function default arguments).  One reason:
we don't know the instance of the template when we need the
value.  Second reason: compilers want to parse and throw away the
form of the template parameter default argument, not save it and
check it for each instantiation.</P>

<P>Class templates should be treated the same as function templates
in this regard.  The base class information is in the same category
as friend declarations inside the class itself -- not available.
If the body were used one would need to instantiate it in order
to know whether one can name it.</P>

<P><B>Proposed resolution (October, 2004):</B></P>

<P>Add the following as a new paragraph following the last
paragraph of 11 [class.access] (but before the new
paragraph inserted by the resolution of <A HREF="
     cwg_defects.html#372">issue 372</A>, if adopted):</P>

<BLOCKQUOTE>

<P>The names in a default <I>template-argument</I> (14.1 [temp.param]) have their access checked in the context in which
they appear rather than at any points of use of the default
<I>template-argument</I>. [<I>Example:</I></P>

<PRE>
    class B {};
    template &lt;class T&gt; class C {
    protected:
       typedef T TT;
    };

    template &lt;class U, class V = typename U::TT&gt;
    class D : public U {};

    D &lt;C&lt;B&gt; &gt;* d;  // access error, C::TT is protected
</PRE>

<P>&#8212;<I>end example</I>]</P>
</BLOCKQUOTE>

<BR><BR><HR><A NAME="228"></A><H4>228.
  
Use of <TT>template</TT> keyword with non-member templates
</H4><B>Section: </B>14.2&#160; [temp.names]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>4 May 2000<BR>


<P>[Voted into WP at April 2003 meeting.]</P>



<P>Consider the following example:</P>

<PRE>
    template&lt;class T&gt;
    struct X {
       virtual void f();
    };

    template&lt;class T&gt;
    struct Y {
       void g(X&lt;T&gt; *p) {
	  p-&gt;template X&lt;T&gt;::f();
       }
    };
</PRE>

<P>This is an error because <TT>X</TT> is not a member template;
14.2 [temp.names] paragraph 5 says:</P>

<BLOCKQUOTE>
If a name prefixed by the keyword <TT>template</TT> is not the name 
of a member template, the program is ill-formed.
</BLOCKQUOTE>

<P>In a way this makes perfect sense: <TT>X</TT> is found to be a template
using ordinary lookup even though <TT>p</TT> has a dependent type.
However, I think this makes the use of the <TT>template</TT> prefix
even harder to teach.</P>

<P>Was this intentionally outlawed?</P>

<P><B>Proposed Resolution (4/02):</B></P>

<P>Elide the first use of the word "member" in
14.2 [temp.names] paragraph 5 so that its first sentence reads:</P>
<BLOCKQUOTE>
If a name prefixed by the keyword <TT>template</TT> is not the name of a
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">member</SPAN> template, the program is ill-formed.
</BLOCKQUOTE>

<BR><BR><HR><A NAME="301"></A><H4>301.
  
Syntax for <I>template-name</I>
</H4><B>Section: </B>14.2&#160; [temp.names]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mark Mitchell
 &#160;&#160;&#160;

 <B>Date: </B>24 Jul 2001<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>



<P>The grammar for a <I>template-name</I> is:</P>
<UL><I>template-name</I>:
<UL><I>identifier</I>
</UL>
</UL>

<P>That's not right; consider:</P>
<PRE>
    template &lt;class T&gt; T operator+(const T&amp;, const T&amp;);
    template &lt;&gt; S operator+&lt;S&gt;(const S&amp;, const S&amp;);
</PRE>

<P>This is ill-formed according to the standard, since <TT>operator+</TT> is
not a template-name.</P>

<P><B>Suggested resolution:</B></P>

<P>I think the right rule is</P>
<UL><I>template-name:</I>
<UL><I>identifier</I>
<BR><I>operator-function-id</I>
<BR><I>conversion-function-id</I>
</UL>
</UL>

<P>John Spicer adds that there's some question about whether
conversion functions should be included, as they cannot have template
argument lists.</P>

<P><B>Notes from 4/02 meeting:</B></P>

<P>If the change is made as a syntax change, we'll need a semantic
restriction to avoid <TT>operator+&lt;int&gt;</TT> as a class.
Clark Nelson will work on a compromise proposal -- not the minimal
change to the syntax proposed, not the maximal change either.</P>

<P><B>Clark Nelson (April 2003):</B></P>

<P> The proposed solution (adding <I>operator-function-id</I> as an
alternative for <I>template-name</I>) would have a large impact on
the language described by the grammar.  Specifically, for example,
<TT>operator+&lt;int&gt;</TT> would become a syntactically valid
<I>class-name</I>.  </P>

<P> On the other hand, a change with (I believe) exactly the desired
effect on the language accepted, would be to modify
<I>operator-function-id</I> itself: </P>

<UL>
<I>operator-function-id</I>:
<UL><TT>operator</TT> <I>operator</I>
<BR>
<B><TT>operator</TT> <I>operator</I> <TT>&lt;</TT>
<I>template-argument-list<SUB>opt</SUB></I> <TT>&gt;</TT></B></UL>
</UL>

<P><I>(Steve Adamczyk: this change was already made by
<A HREF="
     cwg_defects.html#38">issue 38</A> and is in TC1.)</I></P>

<P> Then there is the first sentence of 14.2 [temp.names]
paragraph 3: </P>

<BLOCKQUOTE> After name lookup (3.4 [basic.lookup])
finds that a name is a
<I>template-name</I>, if this name is followed by a
<TT>&lt;</TT>, the <TT>&lt;</TT> is always taken as the
beginning of a <I>template-argument-list</I> and never as a name
followed by the less-than operator.  </BLOCKQUOTE>

<P> This description seems to be adequate for names of class templates.
As far as I can tell, the only ambiguity it resolves is from something
that starts with <TT>new X &lt;</TT>, in the
scope of a class template <TT>X</TT>.  But as far as I can tell is
already inadequate for names of function templates, and is even worse
for operator function templates.  </P>

<P>Probably <TT>&lt;</TT> should always be interpreted as
introducing a <I>template-argument-list</I> if any member of the
overload set is a function template.  After all, function pointers are
very rarely compared for ordering, and it's not clear what other rule
might be workable.  </P>

<P> I'm inclined to propose the simplest rule possible for
<I>operator-function-ids</I>: if one is followed by
<TT>&lt;</TT>, then what follows is interpreted as a
<I>template-argument-list</I>, unconditionally.  Of course, if no
template for that operator has been declared, then there's an error.
</P>

<P> Also, note that if the operator in question is <TT>&lt;</TT> or <TT>&lt;&lt;</TT>, it is possible to run into a problem similar to the famous <TT>&gt;&gt;</TT> nested template argument list closing delimiter problem.
However, since in this case (at least) one of the <TT>&lt;</TT> characters has a radically different interpretation than the other, and for other reasons as well, this is unlikely to be nearly as much of a practical problem as the <TT>&gt;&gt;</TT> problem.
</P>

<P><B>Notes from April 2003 meeting:</B></P>

<P>We felt that the operator functions should not be special-cased.
They should be treated like any other name.</P>

<P><B>September 2003:</B></P>

<P>Clark Nelson has provided the changes in N1490=03-0073.</P>

<P><B>Notes from October 2003 meeting:</B></P>

<P>We reviewed Clark Nelson's N1490.  Clark will revise it and
introduce a new syntax term for an identifier or
the name of an operator function.</P>

<P><B>Notes from the April, 2005 meeting:</B></P>

<P>The CWG suggested a new approach to resolving this issue: the
existing term <I>template-id</I> will be renamed
to <I>class-template-id</I>, the term <I>template-id</I> will be
defined to include operator functions with template arguments, and any
current uses of <I>template-id</I> (such as in the definition
of <I>elaborated-type-specifier</I>) where an operator function is not
appropriate will be changed to refer to <I>class-template-id</I>.</P>

<P><B>Proposed resolution (April, 2006):</B></P>

<P>As specified in document J16/05-0156 = WG21 N1896, except that:</P>

<OL>

<LI><P>In change 9 (3.4.5 [basic.lookup.classref]), omit the change from
&#8220;entire <I>postfix-expression</I>&#8221; to
&#8220;<I>nested-name-specifier</I>.&#8221;</P></LI>

<LI><P>In change a (3.4.3.1 [class.qual] paragraph 1,
third bullet), omit the change from &#8220;entire
<I>postfix-expression</I>&#8221; to &#8220;<I>qualified-id</I>.&#8221;</P></LI>

<LI><P>In change b (3.4.3.2 [namespace.qual] paragraph 1),
omit the change from &#8220;entire <I>postfix-expression</I>&#8221; to
&#8220;<I>qualified-id</I>.&#8221;</P></LI>

</OL>

<P>(Some of these omitted changes are addressed by
<A HREF="
     cwg_active.html#562">issue 562</A>.)</P>

<P>(This resolution also resolves <A HREF="
     cwg_defects.html#534">issue 534</A>.)</P>

<BR><BR><HR><A NAME="468"></A><H4>468.
  
Allow <TT>::template</TT> outside of templates
</H4><B>Section: </B>14.2&#160; [temp.names]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>9 Apr 2004<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>

<P>For the same reasons that <A HREF="
     cwg_defects.html#382">issue 382</A>
proposes for relaxation of the requirements on <TT>typename</TT>,
it would make sense to allow the <TT>::template</TT> disambiguator
outside of templates.</P>

<P>See also issues <A HREF="
     cwg_defects.html#11">11</A>,
<A HREF="
     cwg_defects.html#30">30</A>,
<A HREF="
     cwg_defects.html#96">96</A>, and <A HREF="
     cwg_closed.html#109">109</A>.</P>

<P><B>Proposed resolution (October, 2005):</B></P>

<P>Change 14.2 [temp.names] paragraph 5 as indicated:</P>

<BLOCKQUOTE>

If a name prefixed by the keyword <TT>template</TT> is not the name of
a template, the program is ill-formed. [<I>Note:</I> the
keyword <TT>template</TT> may not be applied to non-template members
of class templates. &#8212;<I>end note</I>] <SPAN style="text-decoration:line-through;background-color:#FFA0A0">Furthermore, names of
member templates shall not be prefixed by the
keyword <TT>template</TT> if the <I>postfix-expression</I>
or <I>qualified-id</I> does not appear in the scope of a template.</SPAN>
[<I>Note:</I> just as is the case with the <TT>typename</TT> prefix,
the <TT>template</TT> prefix is allowed in cases where it is not
strictly necessary; i.e., when <SPAN style="font-weight:bold;background-color:#A0FFA0">the <I>nested-name-specifier
or</I></SPAN> the expression on the left of the <TT>-&gt;</TT>
or <TT>.</TT><SPAN style="text-decoration:line-through;background-color:#FFA0A0">, or the <I>nested-name-specifier</I></SPAN> is not
dependent on a <I>template-parameter</I><SPAN style="font-weight:bold;background-color:#A0FFA0">, or the use does not
appear in the scope of a template</SPAN>. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<BR><BR><HR><A NAME="246"></A><H4>246.
  
Jumps in <I>function-try-block</I> handlers
</H4><B>Section: </B>14.3&#160; [temp.arg]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>15 Sep 2000<BR>


<P>[Moved to DR at 4/01 meeting.]</P>



<P>Is it permitted to jump from a handler of a
<I>function-try-block</I> into the body of the function?</P>

<P>15 [except] paragraph 2 would appear to disallow
such a jump:</P>

<BLOCKQUOTE>

A <TT>goto</TT>, <TT>break</TT>, <TT>return</TT>, or <TT>continue</TT>
statement can be used to transfer control out of a try block or
handler, but not into one.

</BLOCKQUOTE>

<P>However, 15.3 [except.handle] paragraph 14 mentions
only constructors and destructors for the prohibition:</P>

<BLOCKQUOTE>

If the handlers of a <I>function-try-block</I> contain a jump into the
body of a constructor or destructor, the program is ill-formed.

</BLOCKQUOTE>

<P>Is this paragraph simply reemphasizing the more general
restriction, or does it assume that such a jump would be permitted
for functions other than constructors or destructors?  If the
former interpretation is correct, it is confusing and should be
either eliminated or turned into a note.  If the latter
interpretation is accurate, 15 [except] paragraph 2
must be revised.</P>

<P>(See also <A HREF="
     cwg_defects.html#98">issue 98</A>.)</P>

<P><B>Proposed resolution (04/01):</B></P>

<P>Delete 15.3 [except.handle] paragraph 14.</P>

<BR><BR><HR><A NAME="372"></A><H4>372.
  
Is access granted by base class specifiers available in following base class specifiers?
</H4><B>Section: </B>14.3&#160; [temp.arg]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Clark Nelson
 &#160;&#160;&#160;

 <B>Date: </B>13 August 2002<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>

<P>I'm not really sure what the standard
says about this. Personally, I'd like for it to be ill-formed, but I can't
find any words that I can interpret to say so.</P>
<PRE>
  template&lt;class T&gt;
  class X
  {
  protected:
    typedef T Type;
  };
  template&lt;class T&gt;
  class Y
  {
  };
  template&lt;class T,
           template&lt;class&gt; class T1,
           template&lt;class&gt; class T2&gt;
  class Z:
    public T2&lt;typename T1&lt;T&gt;::Type&gt;,
    public T1&lt;T&gt;
  {
  };
  Z&lt;int, X, Y&gt; z;
</PRE>
<P><U>John Spicer</U>:
I don't think the standard really addresses this case.  There
is wording about access checking of things used as template arguments,
but that doesn't address accessing members of the template argument
type (or template) from within the template.</P>

<P>This example is similar, but does not use template template arguments.</P>
<PRE>
  class X {
  private:
    struct Type {};
  };
  template &lt;class T&gt; struct A {
    typename T::Type t;
  };
  A&lt;X&gt; ax;
</PRE>

<P>This gets an error from most compilers, though the standard is probably
mute on this as well.  An error makes sense -- if there is no error,
there is a hole in the access checking.  (The special rule about
no access checks on template parameters is not a hole, because the access
is checked on the type passed in as an argument.  But when you look
up something in the scope of a template parameter type, you need to
check the access to the member found.)</P>

<P>The logic in the template template parameter case should be similar:
anytime you look up something in a template-dependent class, the
member's access must be checked, because it could be different for
different template instances.</P>

<P><B>Proposed Resolution (October 2002):</B></P>

<P>Change the last sentence of 14.3 [temp.arg]
paragraph 3 from:
<BLOCKQUOTE>
For a <I>template-argument</I> of class type, the template definition has no
special access rights to the inaccessible members of the template
argument type.
</BLOCKQUOTE>
to:
<BLOCKQUOTE>
For a <I>template-argument</I> that is a class type or a class template, the
template definition has no special access rights to the members
of the <I>template-argument</I>.  [<I>Example</I>:
<PRE>
  template &lt;template &lt;class TT&gt; class T&gt; class A {
    typename T&lt;int&gt;::S s;
  };

  template &lt;class U&gt; class B {
    private:
    struct S { /* ... */ };
  };

  A&lt;B&gt; b;   // ill-formed, A has no access to B::S
</PRE>
-- <I>end example</I>]
</BLOCKQUOTE>
</P>

<P><B>Daniel Frey posts on comp.std.c++ in July 2003:</B>
I just read DR 372 and I think that the problem presented is not really 
discussed/solved properly. Consider this example:</P>
<PRE>
  class A {
  protected:
     typedef int N;
  };

  template&lt; typename T &gt;
  class B
  {};

  template&lt; typename U &gt;
  class C : public U, public B&lt; typename U::N &gt;
  {};

  C&lt; A &gt; x;
</PRE>
<P>The question is: If C is derived from A as above, is it allowed to 
access A::N before the classes opening '{'?</P>

<P>The main problem is that you need to access U's protected parts in C's 
base-clause. This pattern is common when using policies, Andrei's Loki 
library was bitten by it as he tried to make some parts of the policies 
'protected' but some compilers rejected the code. They were right to 
reject it, I think it's
11.3 [class.friend]/2 that applies here and prevents the code 
above to be legal, although it addresses a different and reasonable 
example. To me, it seems wrong to reject the code as it is perfectly 
reasonable to write such stuff. The questions are:</P>

<UL>
<LI>Do you agree it's reasonable?</LI>
<LI>Is it a DR or is it a request for an extension?</LI>
<LI>Is DR 372 the right place to address it or shall it be a new DR?</LI>
</UL>

<P><U>Steve Adamczyk:</U>
In other words, the point of the issue is over what range access derived
from base class specifiers is granted, and whether any part of that range 
is the base specifier list itself, either the parts afterwards or the whole 
base specifier list.  (Clark Nelson confirms this is what he was
asking with the original question.)
Personally, I find it somewhat disturbing that access might
arrive incrementally; I'd prefer that the access happen all 
at once, at the opening brace of the class.</P>

<P><B>Notes from October 2003 meeting:</B></P>

<P>We decided it makes sense to delay the access checking for the
base class specifiers until the opening brace of the class is
seen.  In other words, the base specifiers will be checked using
the full access available for the class, and the order of the
base classes is not significant in that determination. The
implementors present all said they already had code to handle
accumulation of delayed access checks, because it is already
needed in other contexts.</P>

<P><B>Proposed resolution (October, 2004):</B></P>

<OL>

<LI><P>Change the last sentence of 14.3 [temp.arg]
paragraph 3 as indicated:</P>

<BLOCKQUOTE>

For a <I>template-argument</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">of</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">that is a</SPAN> class
type <SPAN style="font-weight:bold;background-color:#A0FFA0">or a class template</SPAN>, the template definition
has no special access rights to the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">inaccessible</SPAN> members of the
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">template argument type</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>template-argument</I>.
[<I>Example:</I>

<PRE>
    template &lt;template &lt;class TT&gt; class T&gt; class A {
       typename T&lt;int&gt;::S s;
    };

    template &lt;class U&gt; class B {
       private:
       struct S { /* ... */ };
    };

    A&lt;B&gt; b;   // ill-formed, A has no access to B::S
</PRE>

<P>&#8212;<I>end example</I>]</P>

</SPAN>

</BLOCKQUOTE>

</LI>

<LI><P>Insert the following as a new paragraph after the final
paragraph of 11 [class.access]:</P>

<BLOCKQUOTE>

<P>The access of names in a class <I>base-specifier-list</I> are
checked at the end of the list after all base classes are known.
[<I>Example:</I></P>

<PRE>
    class A {
      protected:
         typedef int N;
    };

    template&lt;typename T&gt; class B {};

    template&lt;typename U&gt; class C : public B&lt;typename U::N&gt;, public U {};

    C&lt;A&gt; x;  // OK: A is a base class so A::N in B&lt;A::N&gt; is accessible
</PRE>

</BLOCKQUOTE>

<P>&#8212;<I>end example</I>]</P>

</LI>

</OL>

<P><B>Notes from the April, 2005 meeting:</B></P>

<P>The 10/2004 resolution is not sufficient to implement the CWG's
intent to allow these examples: clause 11 [class.access]
paragraph 1 grants protected access only to &#8220;members and
friends&#8221; of derived classes, not to their
<I>base-specifier</I>s.  The resolution needs to be extended to say
either that access in <I>base-specifiers</I> is determined as if they
were members of the class being defined or that access is granted to
the class as an entity, including its <I>base-specifier</I>s.  See
also <A HREF="
     cwg_defects.html#500">issue 500</A>, which touches on the same
issue and should be resolved in the same way.</P>

<P><B>Proposed resolution (October, 2005):</B></P>

<OL>

<LI><P>Change the second bullet of 11 [class.access] paragraph
1 as indicated:</P>

<UL><LI><P><TT>protected</TT>; that is, its name can be used only by
members and friends of the class in which it is declared, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">and by
members and friends of classes derived from this class</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">by
classes derived from that class, and by their friends</SPAN> (see
11.4 [class.protected]).</P></LI></UL>

</LI>

<LI><P>Change 11 [class.access] paragraph 2 as indicated:</P>

<BLOCKQUOTE>

A member of a class can also access all the names <SPAN style="text-decoration:line-through;background-color:#FFA0A0">declared in the
class of which it is a member</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">to which the class has access</SPAN>.

</BLOCKQUOTE>

</LI>

<LI><P>Change 11 [class.access] paragraph 6 as indicated:</P>

<BLOCKQUOTE>

All access controls in clause 11 [class.access] affect the
ability to access a class member name from a particular scope. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The
access control for names used in the definition of a class member that
appears outside of the member's class definition is done as if the
entire member definition appeared in the scope of the member's
class.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">For purposes of access control, the <I>base-specifier</I>s
of a class and the definitions of class members that appear outside of
the class definition are considered to be within the scope of that
class.</SPAN> In particular...

</BLOCKQUOTE>

</LI>

<LI><P>Change the example and commentary in 11 [class.access]
paragraphs 6-7 as indicated:</P>

<BLOCKQUOTE>

<P>[<I>Example:</I></P>

<PRE>
    class A {
      typedef int I; //<SPAN style="font-family:Times;font-style:italic"> private member</SPAN>
      I f();
      friend I g(I);
      static I x;
    <SPAN style="font-weight:bold;background-color:#A0FFA0">protected:
      struct B { };</SPAN>
    };

    A::I A::f () { return 0; }
    A::I g(A::I p = A::x);
    A::I g(A::I p) { return 0; }
    A::I A::x = 0;

    <SPAN style="font-weight:bold;background-color:#A0FFA0">struct D: A::B, A { };</SPAN>
</PRE>

Here, all the uses of <TT>A::I</TT> are well-formed
because <TT>A::f</TT> and <TT>A::x</TT> are members of
class <TT>A</TT> and <TT>g</TT> is a friend of class <TT>A</TT>.  This
implies, for example, that access checking on the first use
of <TT>A::I</TT> must be deferred until it is determined that this use
of <TT>A::I</TT> is as the return type of a member of
class <TT>A</TT>. <SPAN style="font-weight:bold;background-color:#A0FFA0">Similarly, the use of <TT>A::B</TT> as a
<I>base-specifier</I> is well-formed because <TT>D</TT> is derived
from <TT>A</TT>, so access checking of <I>base-specifier</I>s must be
deferred until the entire <I>base-specifier-list</I> has been seen.</SPAN>
&#8212;<I>end example</I>]

</BLOCKQUOTE>

</LI>

<LI><P>In 11.3 [class.friend] paragraph 2, replace the following
text:</P>

<BLOCKQUOTE>

<P>Declaring a class to be a friend implies that the names of private
and protected members from the class granting friendship can be
accessed in declarations of members of the befriended
class. [<I>Note:</I> this means that access to private and protected
names is also granted to member functions of the friend class (as if
the functions were each friends) and to the static data member
definitions of the friend class. This also means that private and
protected type names from the class granting friendship can be used in
the <I>base-clause</I> of a nested class of the friend class. However,
the declarations of members of classes nested within the friend class
cannot access the names of private and protected members from the
class granting friendship. Also, because the <I>base-clause</I> of the
friend class is not part of its member declarations,
the <I>base-clause</I> of the friend class cannot access the names of
the private and protected members from the class granting
friendship. For example,</P>

<PRE>
    class A {
      class B { };
      friend class X;
    };
    class X: A::B {     //<SPAN style="font-family:Times;font-style:italic"> ill-formed: </SPAN>A::B<SPAN style="font-family:Times;font-style:italic"> cannot be accessed</SPAN>
                        //<SPAN style="font-family:Times;font-style:italic"> in the base-clause for </SPAN>X
      A::B mx;          //<SPAN style="font-family:Times;font-style:italic"> OK: </SPAN>A::B<SPAN style="font-family:Times;font-style:italic"> used to declare member of </SPAN>X
      class Y: A::B {   //<SPAN style="font-family:Times;font-style:italic"> OK: </SPAN>A::B<SPAN style="font-family:Times;font-style:italic"> used to declare member of </SPAN>X
        A::B my;        //<SPAN style="font-family:Times;font-style:italic"> ill-formed: </SPAN>A::B<SPAN style="font-family:Times;font-style:italic"> cannot be accessed</SPAN>
                        //<SPAN style="font-family:Times;font-style:italic"> to declare members of nested class of </SPAN>X
      };
    };
</PRE>

<P>&#8212;<I>end note</I>]</P>

</BLOCKQUOTE>

<P>with:</P>

<BLOCKQUOTE>

<P>Declaring a class to be a friend implies that the names of private and
protected members from the class granting friendship can be accessed
in the <I>base-specifier</I>s and member declarations of the befriended
class. [<I>Example:</I></P>

<PRE>
    class A {
      class B { };
      friend class X;
    };

    struct X: A::B {   //<SPAN style="font-family:Times;font-style:italic"> OK: </SPAN>A::B<SPAN style="font-family:Times;font-style:italic"> accessible to friend</SPAN>
      A::B mx;         //<SPAN style="font-family:Times;font-style:italic"> OK: </SPAN>A::B<SPAN style="font-family:Times;font-style:italic"> accessible to member of friend</SPAN>
      class Y {
        A::B my;       //<SPAN style="font-family:Times;font-style:italic"> OK: </SPAN>A::B<SPAN style="font-family:Times;font-style:italic"> accessible to nested member of friend</SPAN>
      };
    };
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

</LI>

<LI><P>Change the last sentence of 14.3 [temp.arg] paragraph 3
as indicated:</P>

<BLOCKQUOTE>

<P>For a <I>template-argument</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">of</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">that is a</SPAN> class type
<SPAN style="font-weight:bold;background-color:#A0FFA0">or a class template</SPAN>, the template definition has no special
access rights to the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">inaccessible</SPAN> members of the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">template
argument type.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>template-argument</I>.  [<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">    template &lt;template &lt;class TT&gt; class T&gt; class A {
      typename T&lt;int&gt;::S s;
    };

    template &lt;class U&gt; class B {
    private:
      struct S { /* ... */ };
    };

    A&lt;B&gt; b;    //<SPAN style="font-family:Times;font-style:italic"> ill-formed, </SPAN>A<SPAN style="font-family:Times;font-style:italic"> has no access to </SPAN>B::S
</SPAN></PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

</LI>

<LI><P>Change 9.7 [class.nest] paragraph 4 as indicated:</P>

<BLOCKQUOTE>

Like a member function, a friend function (11.3 [class.friend])
defined within a nested class is in the lexical scope of that class;
it obeys the same rules for name binding as a static member function
of that class (9.4 [class.static])<SPAN style="font-weight:bold;background-color:#A0FFA0">, but it</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">and</SPAN>
has no special access rights to members of an enclosing class.

</BLOCKQUOTE>

</LI>

</OL>

<P><I>(Note: this resolution also resolves issues <A HREF="
     cwg_defects.html#494">494</A> and <A HREF="
     cwg_defects.html#500">500</A>.)</I></P>

<BR><BR><HR><A NAME="62"></A><H4>62.
  
Unnamed members of classes used as type parameters
</H4><B>Section: </B>14.3.1&#160; [temp.arg.type]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>13 Oct 1998<BR>



<P>[Moved to DR at 4/01 meeting.]</P>

<P>Section 14.3.1 [temp.arg.type]
 paragraph 2 says</P>
<BLOCKQUOTE>A local type, a type with no linkage, an unnamed type or a
type compounded from any of these types shall not be used as a <I>template-argument
</I>for a template <I>type-parameter</I>.</BLOCKQUOTE>
<P>It probably wasn't intended that classes with unnamed members should be
included in this list, but they are arguably compounded from unnamed types.</P>

<P><B>Proposed resolution (04/01):</B></P>

<P>In 14.3.1 [temp.arg.type] paragraph 2, change</P>

<BLOCKQUOTE>

A local type, a type with no linkage, an unnamed type or a type
compounded from any of these types shall not be used as a
<I>template-argument</I> for a template <I>type-parameter</I>.

</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>

The following types shall not be used as a <I>template-argument</I>
for a template <I>type-parameter</I>:

<UL>

<LI>a type whose name has no linkage</LI>

<LI>an unnamed class or enumeration type that has no name for
linkage purposes (7.1.3 [dcl.typedef])</LI>

<LI>a cv-qualified version of one of the types in this list</LI>

<LI>a type created by application of declarator operators to one
of the types in this list</LI>

<LI>a function type that uses one of the types in this list</LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="354"></A><H4>354.
  
Null as nontype template argument
</H4><B>Section: </B>14.3.2&#160; [temp.arg.nontype]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>2 May 2002<BR>


<P>[Voted into WP at October 2005 meeting.]</P>



<P>The standard does not permit a null value to be used as a nontype template
argument for a nontype template parameter that is a pointer.</P>

<P>This code is accepted by EDG, Microsoft, Borland and Cfront, but rejected
by g++ and Sun:</P>
<PRE>
  template &lt;int *p&gt; struct A {};
  A&lt;(int*)0&gt; ai;
</PRE>
<P>I'm not sure this was ever explicitly considered by the committee.
Is there any reason to permit this kind of usage?</P>

<P><U>Jason Merrill</U>:
I suppose it might be useful for a program to be able to express a
degenerate case using a null template argument.  I think allowing it would
be harmless.</P>

<P><B>Notes from October 2004 meeting:</B></P>

<P>CWG decided that it would be desirable to allow null pointers
as nontype template arguments, even though they are not
representable in some current ABIs.  There was some discussion
over whether to allow a bare <TT>0</TT> to be used with a pointer
nontype template parameter.  The following case was decisive:</P>

<PRE>
    template&lt;int i&gt; void foo();
    template&lt;int* i&gt; void foo();
    ...
    foo&lt;0&gt;();
</PRE>

<P>The current wording of 14.3 [temp.arg] paragraph 7
disambiguates the function call in favor of the <TT>int</TT>
version.  If the null pointer conversion were allowed for pointer
nontype template parameters, this case would become ambiguous, so
it was decided to require a cast.</P>

<P><B>Proposed resolution (April, 2005):</B></P>

<OL>

<LI><P>In 14.3.2 [temp.arg.nontype] paragraph 1, insert the
following after the third bullet:</P>

<UL>

<LI><P>a constant expression that evaluates to a null pointer
value (4.10 [conv.ptr]); or</P></LI>

<LI><P>a constant expression that evaluates to a null member
pointer value (4.11 [conv.mem]); or</P></LI>

</UL>

</LI>

<LI><P>Add the indicated text to the note in the second bullet of
14.3.2 [temp.arg.nontype] paragraph 5:</P>

<BLOCKQUOTE>

[<I>Note:</I> In particular, neither the null pointer conversion
(4.10 [conv.ptr]) nor the derived-to-base conversion
(4.10 [conv.ptr]) are applied. Although <TT>0</TT> is a valid
<I>template-argument</I> for a non-type <I>template-parameter</I> of integral
type, it is not a valid <I>template-argument</I> for a non-type
<I>template-parameter</I> of pointer type. <SPAN style="font-weight:bold;background-color:#A0FFA0">However, <TT>(int*)0</TT> is a valid
<I>template-argument</I> for a non-type <I>template-parameter</I> of type
&#8220;pointer to int.&#8221;</SPAN> &#8212;<I>end note</I>]

</BLOCKQUOTE>

</LI>

<LI><P>Replace the normative wording of 14.4 [temp.type] paragraph 1 with the following:</P>

<BLOCKQUOTE>

<P>Two <I>template-id</I>s refer to the same class or function
if</P>

<UL>

<LI>their <I>template-name</I>s refer to the same template, and</LI>

<LI>their corresponding type <I>template-argument</I>s are the
same type, and</LI>

<LI>their corresponding non-type <I>template-argument</I>s of
integral or enumeration type have identical values, and</LI>

<LI>their corresponding non-type <I>template-argument</I>s of
pointer type refer to the same external object or function or are
both the null pointer value, and</LI>

<LI>their corresponding non-type <I>template-argument</I>s of
pointer-to-member type refer to the same class member or are both
the null member pointer value, and</LI>

<LI>their corresponding non-type <I>template-arguments</I>s for
template parameters of reference type refer to the same external
object or function, and</LI>

<LI>their corresponding template <I>template-argument</I>s refer
to the same template.</LI>

</UL>

</BLOCKQUOTE>

</LI>
</OL>

<BR><BR><HR><A NAME="603"></A><H4>603.
  
Type equivalence and unsigned overflow
</H4><B>Section: </B>14.4&#160; [temp.type]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>James Widman
 &#160;&#160;&#160;

 <B>Date: </B>3 November 2006<BR>


<P>[Voted into WP at April, 2007 meeting as part of paper N2258.]</P>



<P>One of the requirements for two <I>template-id</I>s to refer
to the same class or function (14.4 [temp.type]
paragraph 1) is that</P>

<UL><LI>their corresponding non-type <I>template-argument</I>s of
integral or enumeration type have identical values</LI></UL>

<P>If we have some template of the form</P>

<PRE>
  template &lt;unsigned char c&gt; struct A;
</PRE>

<P>does this imply that <TT>A&lt;'\001'&gt;</TT> and
<TT>A&lt;257&gt;</TT> (for an eight-bit <TT>char</TT>) refer to
different specializations?</P>

<P><U>Jens Maurer</U>: Looks like it should say something like,
&#8220;their corresponding converted non-type template arguments
of integral or enumeration type have identical values.&#8221;</P>

<P><B>Proposed resolution (April, 2007):</B></P>

<P>The change to 14.4 [temp.type] paragraph 1 shown in
document J16/07-0118 = WG21 N2258, in which the syntactic
non-terminal <I>template-argument</I> is changed to the English
term &#8220;template argument&#8221; is sufficient to remove the
confusion about whether the value before or after conversion is
used in matching <I>template-id</I>s.</P>

<BR><BR><HR><A NAME="679"></A><H4>679.
  
Equivalence of <I>template-id</I>s and operator function templates
</H4><B>Section: </B>14.4&#160; [temp.type]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Corden
 &#160;&#160;&#160;

 <B>Date: </B>1 March, 2008<BR>


<P>[Voted into the WP at the September, 2008 meeting.]</P>

<P>In order for two <I>template-id</I>s to refer to the same function,
14.4 [temp.type] paragraph 1, bullet 1 requires that</P>

<UL><LI><P>their <I>template-name</I>s refer to the same
template</P></LI></UL>

<P>This makes it impossible for two <I>template-id</I>s referring
to operator function templates to be equivalent, because only
<I>simple-template-id</I>s have a <I>template-name</I>, and a
<I>template-id</I> referring to an operator function template is
not a <I>simple-template-id</I> (14.2 [temp.names]
paragraph 1).</P>

<U><P>Suggested resolution:</P></U>

<P>Change 14.4 [temp.type] paragraph 1, bullet 1 to read,</P>

<UL><LI><P>their <I>template-name</I>s <SPAN style="font-weight:bold;background-color:#A0FFA0">or
<I>operator-function-id</I>s</SPAN> refer to the same template</P></LI></UL>

<P><B>Proposed resolution (June, 2008):</B></P>

<P>Change 14.4 [temp.type] paragraph 1, first bullet, as
follows:</P>

<UL><LI><P>their <I>template-name</I>s <SPAN style="font-weight:bold;background-color:#A0FFA0">or
<I>operator-function-id</I>s</SPAN> refer to the same template,
and</P></LI>

</UL>

<BR><BR><HR><A NAME="582"></A><H4>582.
  
Template conversion functions
</H4><B>Section: </B>14.5.2&#160; [temp.mem]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>PremAnand Rao
 &#160;&#160;&#160;

 <B>Date: </B>23 May 2006<BR>


<P>[Voted into WP at April, 2007 meeting.]</P>

<P>The wholesale replacement of the phrase &#8220;template
function&#8221; by the resolution of <A HREF="
     cwg_defects.html#105">issue 105</A> seems to have overlooked the similar phrase &#8220;template
conversion function.&#8221; This phrase appears a number of times in
13.3.3.1.2 [over.ics.user] paragraph 3, 14.5.2 [temp.mem] paragraphs 5-8, and 14.8.2 [temp.deduct]
paragraph 1.  It should be systematically replaced in similar
fashion to the resolution of <A HREF="
     cwg_defects.html#105">issue 105</A>.</P>

<P><B>Proposed resolution (October, 2006):</B></P>

<OL>
<LI><P>Change 13.3.3.1.2 [over.ics.user] paragraph 3 as
follows:</P></LI>

<BLOCKQUOTE>

If the user-defined conversion is specified by a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">template
conversion function</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">specialization of a conversion function
template</SPAN>, the second standard conversion sequence must have exact
match rank.

</BLOCKQUOTE>

<LI><P>Change 14.5.2 [temp.mem] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

A specialization of a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">template conversion
function</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">conversion function template</SPAN> is referenced in the
same way as a non-template conversion function that converts to the
same type.

</BLOCKQUOTE>

<LI><P>Change 14.5.2 [temp.mem] paragraph 6 as follows:</P></LI>

<BLOCKQUOTE>

A specialization of a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">template conversion
function</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">conversion function template</SPAN> is not found by name
lookup. Instead, any <SPAN style="text-decoration:line-through;background-color:#FFA0A0">template conversion
functions</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">conversion function templates</SPAN> visible in the
context of the use are considered.

</BLOCKQUOTE>

<LI><P>Change 14.5.2 [temp.mem] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

A <SPAN style="text-decoration:line-through;background-color:#FFA0A0">using-declaration</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>using-declaration</I></SPAN> in a
derived class cannot refer to a specialization of a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">template
conversion function</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">conversion function template</SPAN> in a base
class.

</BLOCKQUOTE>

<LI><P>Change 14.5.2 [temp.mem] paragraph 8 as follows:</P></LI>

<BLOCKQUOTE>

Overload resolution (13.3.3.2 [over.ics.rank]) and partial
ordering (14.5.6.2 [temp.func.order]) are used to select the
best conversion function among multiple <SPAN style="text-decoration:line-through;background-color:#FFA0A0">template conversion
functions</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">specializations of conversion function templates</SPAN>
and/or non-template conversion functions.

</BLOCKQUOTE>

<LI><P>Change 14.8.2.3 [temp.deduct.conv] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

Template argument deduction is done by comparing the return type of
the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">template conversion function</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">conversion function
template</SPAN> (call it <TT>P</TT>) with the type that is required as
the result of the conversion (call it <TT>A</TT>) as described in
14.8.2.5 [temp.deduct.type].

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="329"></A><H4>329.
  
Evaluation of friends of templates
</H4><B>Section: </B>14.5.4&#160; [temp.friend]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>19 Dec 2001<BR>


<P>[Voted into WP at October 2003 meeting.]</P>

<P>14.5.4 [temp.friend] paragraph 5 says:</P>
<BLOCKQUOTE>
When a function is defined in a friend function declaration in a class
template, the function is defined at each instantiation of  the  class
template.  The function is defined even if it is never used.  The same
restrictions on multiple declarations and definitions which  apply  to
non-template function declarations and definitions also apply to these
implicit definitions.  [Note: if the function definition is ill-formed
for  a  given specialization of the enclosing class template, the program
is ill-formed even if the function is never used.  ]
</BLOCKQUOTE>

<P>This means that the following program is invalid, even without the call
of <TT>f(ai)</TT>:</P>
<PRE>
  template &lt;class T&gt; struct A {
    friend void f(A a) {
      g(a);
    }
  };
  int main()
  {
    A&lt;int&gt; ai;
  // f(ai);  // Error if f(ai) is actually called
  }
</PRE>
<P>The EDG front end issues an error on this case even if <TT>f(ai)</TT>
is never
called.  Of the compilers I tried (g++, Sun, Microsoft, Borland) we
are the only ones to issue such an error.</P>

<P>This issue came up because there is a library that either deliberately or
accidentally makes use of friend functions that are not valid for certain
instantiations.</P>

<P>The wording in the standard is the result of a deliberate decision made
long ago, but given the fact that most implementations do otherwise it
raises the issue of whether we did the right thing.</P>

<P>Upon further investigation, the current rule was adopted as the resolution
to issue 6.47 in my series of template issue papers.  At the time the
issue was discussed (7/96) most compilers did evaluate such friends.
So it seems that a number of compilers have changed their behavior
since then.</P>

<P>Based on current practice, I think the standard should be changed to
evaluate such friends only when used.</P>

<P><B>Proposed resolution (October 2002):</B></P>

<P>Change section 14.5.4 [temp.friend]
paragraph 5 from:
<BLOCKQUOTE>
When a function is defined
in a friend function declaration in a class template,
the function is defined at each instantiation of the class template.
The function is defined even if it is never used.
The same restrictions on multiple declarations and definitions
which apply to non-template function declarations and definitions
also apply to these implicit definitions.
[<I>Note:</I>
if the function definition is ill-formed for a given specialization of the
enclosing class template, the program is ill-formed even if the function
is never used.
]
</BLOCKQUOTE>
to:
<BLOCKQUOTE>
When a function is defined 
in a friend function declaration in a class template,
the function is instantiated when the function is used.
The same restrictions on multiple declarations and definitions
that apply to non-template function declarations and definitions
also apply to these implicit definitions.
</BLOCKQUOTE>
Note the change from "which" to "that" in the last sentence.
</P>

<BR><BR><HR><A NAME="410"></A><H4>410.
  
Paragraph missed in changes for issue 166
</H4><B>Section: </B>14.5.4&#160; [temp.friend]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>18 Apr 2003<BR>


<P>[Voted into WP at October 2004 meeting.]</P>

<P>14.5.4 [temp.friend] paragraph 2 was overlooked when the
changes for <A HREF="
     cwg_defects.html#166">issue 166</A> were made.</P>

<P>The friend declaration of f&lt;&gt;(int) is now valid.</P>

<BLOCKQUOTE>
A  friend  function declaration that is not a template declaration and
in which the name of the friend is an  unqualified <I>template-id</I>  shall
refer  to  a  specialization  of  a  function template declared in the
nearest enclosing namespace scope.  [<I>Example:</I>
<PRE>
  namespace N {
          template &lt;class T&gt; void f(T);
          void g(int);
          namespace M {
                  template &lt;class T&gt; void h(T);
                  template &lt;class T&gt; void i(T);
                  struct A {
                          friend void f&lt;&gt;(int);   // ill-formed - N::f
                          friend void h&lt;&gt;(int);   // OK - M::h
                          friend void g(int);     // OK - new decl of M::g
                          template &lt;class T&gt; void i(T);
                          friend void i&lt;&gt;(int);   // ill-formed - A::i
                  };
          }
  }
</PRE>
<I>--end example</I>]
</BLOCKQUOTE>

<P><B>Proposed Resolution (October 2003):</B></P>

<P> Remove 14.5.4 [temp.friend] paragraph 2:</P>

<BLOCKQUOTE>
A  friend  function declaration that is not a template declaration and
in which the name of the friend is an  unqualified <I>template-id</I>  shall
refer  to  a  specialization  of  a  function template declared in the
nearest enclosing namespace scope.  [<I>Example:</I>
<PRE>
  namespace N {
          template &lt;class T&gt; void f(T);
          void g(int);
          namespace M {
                  template &lt;class T&gt; void h(T);
                  template &lt;class T&gt; void i(T);
                  struct A {
                          friend void f&lt;&gt;(int);   // ill-formed - N::f
                          friend void h&lt;&gt;(int);   // OK - M::h
                          friend void g(int);     // OK - new decl of M::g
                          template &lt;class T&gt; void i(T);
                          friend void i&lt;&gt;(int);   // ill-formed - A::i
                  };
          }
  }
</PRE>
<I>--end example</I>]
</BLOCKQUOTE>

<BR><BR><HR><A NAME="286"></A><H4>286.
  
Incorrect example in partial specialization
</H4><B>Section: </B>14.5.5&#160; [temp.class.spec]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Martin Sebor
 &#160;&#160;&#160;

 <B>Date: </B>09 May 2001<BR>


<P>[Moved to DR at 4/02 meeting.]</P>



<P>The example in 14.5.5 [temp.class.spec] paragraph 6 is
incorrect.  It reads,</P>

<PRE>
    template&lt;class T&gt; struct A {
        class C {
            template&lt;class T2&gt; struct B { };
        };
    };

    // partial specialization of A&lt;T&gt;::C::B&lt;T2&gt;
    template&lt;class T&gt; template&lt;class T2&gt;
        struct A&lt;T&gt;::C::B&lt;T2*&gt; { };

    A&lt;short&gt;::C::B&lt;int*&gt; absip; // uses partial specialization
</PRE>

<P>Because <TT>C</TT> is a <TT>class</TT> rather than a <TT>struct</TT>,
the use of the name <TT>B</TT> is inaccessible.</P>

<P><B>Proposed Resolution (10/01):</B></P>

<P>Change <TT>class C</TT> to <TT>struct C</TT> in the example in
14.5.5 [temp.class.spec] paragraph 6.  The example becomes</P>
<PRE>
    template&lt;class T&gt; struct A {
        struct C {
            template&lt;class T2&gt; struct B { };
        };
    };

    // partial specialization of A&lt;T&gt;::C::B&lt;T2&gt;
    template&lt;class T&gt; template&lt;class T2&gt;
        struct A&lt;T&gt;::C::B&lt;T2*&gt; { };

    A&lt;short&gt;::C::B&lt;int*&gt; absip; // uses partial specialization
</PRE>

<BR><BR><HR><A NAME="517"></A><H4>517.
  
Partial specialization following explicit instantiation
</H4><B>Section: </B>14.5.5&#160; [temp.class.spec]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>03 May 2005<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>

<P>According to 14.5.5 [temp.class.spec] paragraph 1,</P>

<BLOCKQUOTE>

If a template is partially specialized then that partial
specialization shall be declared before the first use of that partial
specialization that would cause an implicit instantiation to take
place, in every translation unit in which such a use occurs; no
diagnostic is required.

</BLOCKQUOTE>

<P>This leaves the impression that an explicit instantiation of the
primary template may precede the declaration of an applicable partial
specialization.  Is the following example well-formed?</P>

<PRE>
    template&lt;typename T&gt; class X{
        public:
        void foo(){};
    };

    template class X&lt;void *&gt;;

    template&lt;typename T&gt; class X&lt;T*&gt;{
        public:
        void baz();
    };

    void bar() {
        X&lt;void *&gt; x;
        x.foo();
    }
</PRE>

<P><B>Proposed resolution (October, 2005):</B></P>

<P>Replace the last sentence of 14.5.5 [temp.class.spec]
paragraph 1:</P>

<BLOCKQUOTE>

If a template is partially specialized then that partial
specialization shall be declared before the first use of that partial
specialization that would cause an implicit instantiation to take
place, in every translation unit in which such a use occurs; no
diagnostic is required.

</BLOCKQUOTE>

<P>with:</P>

<BLOCKQUOTE>

A partial specialization shall be declared before the first use of a
class template specialization that would make use of the partial
specialization as the result of an implicit or explicit instantiation
in every translation unit in which such a use occurs; no diagnostic is
required.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="214"></A><H4>214.
  
Partial ordering of function templates is underspecified
</H4><B>Section: </B>14.5.6.2&#160; [temp.func.order]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Martin von Loewis/Martin Sebor
 &#160;&#160;&#160;

 <B>Date: </B>13 Mar 2000<BR>


<P>[Voted into WP at October 2003 meeting.]</P>

<P>In 14.5.6.2 [temp.func.order], partial ordering is explained in
terms of template argument deduction. However, the exact procedure for
doing so is not specified. A number of details are missing, they are
explained as sub-issues below.</P>

<OL>

<LI>14.5.6.2 [temp.func.order] paragraph 2 refers to
14.8.2 [temp.deduct] for argument deduction. This is the
wrong reference; it explains how explicit arguments are processed
(paragraph 2) and how function parameter types are adjusted (paragraph
3). Neither of these steps is meaningful in the context of partial
ordering. Next in deduction follows one of the steps in 14.8.2.1 [temp.deduct.call], 14.8.2.2 [temp.deduct.funcaddr], 14.8.2.3 [temp.deduct.conv], or 14.8.2.5 [temp.deduct.type]. The standard
does not specify which of these contexts apply to partial
ordering. </LI>

<LI>Because 14.8.2.1 [temp.deduct.call] and 14.8.2.3 [temp.deduct.conv] both start with actual function parameters, it is
meaningful to assume that partial ordering uses 14.8.2.5 [temp.deduct.type], which only requires types. With that assumption,
the example in 14.5.6.2 [temp.func.order] paragraph 5 becomes
incorrect, considering the two templates

<PRE>
    template&lt;class T&gt; void g(T);  // #1
    template&lt;class T&gt; void g(T&amp;); // #2
</PRE>

Here, #2 is at least as specialized as #1: With a synthetic type
<TT>U</TT>, #2 becomes <TT>g(U&amp;)</TT>; argument deduction against
#1 succeeds with <TT>T=U&amp;</TT>. However, #1 is not at least as
specialized as #2: Deducing <TT>g(U)</TT> against <TT>g(T&amp;)</TT>
fails. Therefore, the second template is more specialized than the
first, and the call <TT>g(x)</TT> is not ambiguous.</LI>

<LI>According to John Spicer, the intent of the partial ordering was
that it uses deduction as in a function call (14.8.2.1 [temp.deduct.call]), which is indicated by the mentioning of "exact
match" in 14.5.6.2 [temp.func.order] paragraph 4. If that is
indeed the intent, it should be specified how values are obtained for
the step in 14.8.2.1 [temp.deduct.call] paragraph 1, where the
types of the arguments are determined. Also, since 14.8.2.1 [temp.deduct.call] paragraph 2 drops references from the parameter
type, symmetrically, references should be dropped from the argument
type (which is done in 5 [expr] paragraph 2, for a true
function call).</LI>

<LI>14.5.6.2 [temp.func.order] paragraph 4 requires an "exact
match" for the "deduced parameter types". It is not clear whether this
refers to the template parameters, or the parameters of the template
function. Considering the example

<PRE>
    template&lt;class S&gt; void g(S);  // #1
    template&lt;class T&gt; void g(T const &amp;); // #3
</PRE>

Here, #3 is clearly at least as specialized as #1. To determine
whether #1 is at least as specialized as #3, a unique type <TT>U</TT>
is synthesized, and deduction of <TT>g&lt;U&gt;(U)</TT> is performed
against #3. Following the rules in 14.8.2.1 [temp.deduct.call],
deduction succeeds with <TT>T=U</TT>.  Since the template argument is
<TT>U</TT>, and the deduced template parameter is also <TT>U</TT>, we
have an exact match between the template parameters. Even though the
conversion from <TT>U</TT> to <TT>U const &amp;</TT> is an exact
match, it is not clear whether the added qualification should be taken
into account, as it is in other places.</LI>

</OL>

<P><A HREF="
     cwg_closed.html#200">Issue 200</A> covers a related issue,
illustrated by the following example:</P>

<PRE>
    template &lt;class T&gt; T f(int);
    template &lt;class T, class U&gt; T f(U);
    void g() {
        f&lt;int&gt;(1);
    }
</PRE>

<P>Even though one template is "obviously" more specialized than the
other, deduction fails in both directions because neither function
parameter list allows template parameter <TT>T</TT> to be deduced.</P>

<P>(See also <A HREF="
     cwg_defects.html#250">issue 250</A>.)</P>



<P><U>Nathan Sidwell</U>:</P>

<P>14.5.6.2 [temp.func.order] describes the partial ordering of function
templates. Paragraph 5 states,
<BLOCKQUOTE>
A template is more specialized than another if, and
only if, it is at least as specialized as the other
template and that template is not at least as
specialized as the first.
</BLOCKQUOTE>
To paraphrase, given two templates A &amp; B, if A's template
parameters can be deduced by B, but B's cannot be deduced by
A, then A is more specialized than B. Deduction is done as
if for a function call. In particular, except for conversion
operators, the return type is not involved in deduction.
This leads to the following templates and use being
unordered. (This example is culled from G++ bug report 4672
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&amp;pr=4672)
<PRE>
  template &lt;typename T, class U&gt; T checked_cast(U from); //#1
  template &lt;typename T, class U&gt; T checked_cast(U * from); //#2
  class C {};

  void foo (int *arg)
  {
    checked_cast &lt;C const *&gt; (arg);
  }
</PRE>
In the call,</P>
<P>#1 can be deduced with T = 'C const *' and U = 'int *'</P>
<P>#2 can be deduced with T = 'C const *' and U = 'int'</P>

<P>It looks like #2 is more specialized that #1, but
14.5.6.2 [temp.func.order] does not make it so, as neither template can
deduce 'T' from the other template's function parameters.</P>

<P>Possible Resolutions:</P>
<P>There are several possible solutions, however through
experimentation I have discounted two of them.</P>

<P>Option 1:</P>
<P>When deducing function ordering, if the return type of one of
the templates uses a template parameter, then return types
should be used for deduction.  This, unfortunately, makes
existing well formed programs ill formed. For example
<PRE>
  template &lt;class T&gt; class X {};

  template &lt;class T&gt; X&lt;T&gt; Foo (T *);	// #1
  template &lt;class T&gt; int Foo (T const *); // #2

  void Baz (int *p1, int const *p2)
  {
    int j = Foo (p2); //#3
  }
</PRE>
Here, neither #1 nor #2 can deduce the other, as the return
types fail to match. Considering only the function parameters
gives #2 more specialized than #1, and hence makes the call
#3 well formed.</P>

<P>Option 2:</P>
<P>As option 1, but only consider the return type when deducing
the template whose return type involves template parameters.
This has the same flaw as option 1, and that example is
similarly ill formed, as #1's return type 'X&lt;T,0&gt;' fails to
match 'int' so #1 cannot deduce #2. In the converse direction,
return types are not considered, but the function parameters
fail to deduce.</P>

<P>Option 3:</P>
<P>It is observed that the original example is only callable
with a template-id-expr to supply a value for the first,
undeducible, parameter.  If that parameter were deducible it
would also appear within at least one of the function
parameters.  We can alter paragraph 4 of [temp.func.order]
to indicate that it is not necessary to deduce the parameters
which are provided explicitly, when the call has the form
of a template-id-expr.  This is a safe extension as it only
serves to make ill formed programs well formed. It is also
in line with the concept that deduction for function
specialization order should proceed in a similar manner to
function calling, in that explicitly provided parameter
values are taken into consideration.</P>

<P><B>Suggested resolution</B>:</P>
<P>Insert after the first sentence of paragraph 4 in
14.5.6.2 [temp.func.order]</P>
<BLOCKQUOTE>
Should any template parameters remain undeduced, and
the function call be of the form of a <I>template-id-expr</I>,
those template parameters provided in the
<I>template-id-expr</I> may be arbitrarily synthesized prior
to determining whether the deduced arguments generate
a valid function type.
</BLOCKQUOTE>

<P>See also <A HREF="
     cwg_closed.html#200">issue 200</A>.</P>

<P><B>(April 2002)</B> John Spicer and John Wiegley have written a
paper on this.  See 02-0051/N1393.</P>

<P><B>Proposed resolution (October 2002):</B></P>

<P>
Change 14.5.6.2 [temp.func.order] paragraph 2 to read:</P>
<BLOCKQUOTE>
Partial ordering selects which of two function templates is more
specialized than the other by transforming each template in turn
(see next paragraph) and performing template argument deduction
using the function parameter types, or in the case of a conversion
function the return type.  The deduction process determines whether
one of the templates is more specialized than the other.  If so, the
more specialized template is the one chosen by the partial ordering
process.
</BLOCKQUOTE>
<P>
Change 14.5.6.2 [temp.func.order] paragraph 3 to read:</P>
<BLOCKQUOTE>
To produce the transformed template, for each type, non-type, or template
template parameter synthesize a unique type, value, or class template
respectively and substitute it for each occurrence of that parameter
in the function type of the template.
</BLOCKQUOTE>

<P>
Change 14.5.6.2 [temp.func.order] paragraph 4 to read
(note: the section reference should refer to the section added to
14.8.2 [temp.deduct] below):</P>
<BLOCKQUOTE>
Using the transformed function template's function parameter list, or
in the case of a conversion function its transformed return type,
perform type deduction against the function parameter list (or return
type) of the other function.  The mechanism for performing these
deductions is given in 14.8.2.x.
</BLOCKQUOTE>
<P>
Remove the text of 14.5.6.2 [temp.func.order] paragraph 5 but
retain the example.  The removed text is:</P>
<BLOCKQUOTE>
A template is more specialized than another if, and only if, it is
at least as specialized as the other template and that template is not
at least as specialized as the first.
</BLOCKQUOTE>
<P>
Insert the following section before 14.8.2.5
(Note that this would either be a new 14.8.2.4, or would be given
a number like 14.8.2.3a.  If neither of these is possible from
a troff point of view, this could be made 14.8.2.5.

)</P>
<BLOCKQUOTE>
<P><B>Deducing template arguments when determining the partial ordering
of function templates (temp.deduct.partial)</B></P>

<P>
Template argument deduction is done by comparing certain types associated with
the two function templates being compared.</P>
<P>
Two sets of types are used to determine the partial ordering.  For each of
the templates involved there is the original function type and the
transformed function type. [<I>Note:</I>
The creation of the transformed type is
described in 14.5.6.2 [temp.func.order].]
The deduction process uses the
transformed type as the argument template and the original type of the
other template as the parameter template.  This process is done twice
for each type involved in the partial ordering comparison: once using
the transformed template-1 as the argument template and template-2 as
the parameter template and again using the transformed template-2 as
the argument template and template-1 as the parameter template.</P>
<P>
The types used to determine the ordering depend on the context in which
the partial ordering is 
<UL>
<LI>
In the context of a function call, the function parameter types
are used.</LI>
<LI>
In the context of a call to a conversion operator, the return types of
the conversion function templates are used.</LI>
<LI>
In other contexts (14.5.6.2 [temp.func.order]),
the function template's function type is used.</LI>
</UL>
</P>

<P>
Each type from the parameter template and the corresponding type from the
argument template are used as the types of <TT>P</TT> and <TT>A</TT>.</P>
<P>
Before the partial ordering is done, certain transformations are performed
on the types used for partial ordering:
<UL>
<LI>
If <TT>P</TT> is a reference type, <TT>P</TT> is replaced by the type
referred to.</LI>
<LI>
If <TT>A</TT> is a reference type, <TT>A</TT> is replaced by the type
referred to.</LI>
</UL>
</P>

<P>
If both <TT>P</TT> and <TT>A</TT> were reference types (before being replaced
with the type referred to above), determine which
of the two types (if any) is more cv-qualified than the other; otherwise
the types are considered to be equally cv-qualified for partial ordering
purposes.  The result of this determination will be used below.</P>

<P>
Remove any top-level cv-qualifiers:
<UL>
<LI>
If <TT>P</TT> is a cv-qualified type, <TT>P</TT> is replaced by the
cv-unqualified version of <TT>P</TT>.</LI>
<LI>
If <TT>A</TT> is a cv-qualified type, <TT>A</TT> is replaced by the
cv-unqualified version of <TT>A</TT>.</LI>
</UL>
</P>

<P>
Using the resulting types <TT>P</TT> and <TT>A</TT> the deduction is then
done as described in (14.8.2.5 [temp.deduct.type]).
If deduction succeeds for a given type,
the type from the argument template is considered to be at least as specialized
as the type from the parameter template.</P>

<P>
If, for a given type, deduction succeeds in both directions (i.e., the
types are identical after the transformations above) if the type from
the argument template is more cv-qualified than the type from the
parameter template (as described above) that type is considered to be
more specialized than the other.  If neither type is more cv-qualified
than the other then neither type is more specialized than the other.</P>

<P>
If for each type being considered a given template is at least as specialized
for all types and more specialized for some set of types and the
other template is not more specialized for any types or is not
at least as specialized for any types, then
the given template is more specialized than the other template.
 Otherwise, neither template
is more specialized than the other.</P>

<P>
In most cases, all template parameters must have values in order for
deduction to succeed, but for partial ordering purposes a template
parameter may remain without a value provided it is not used in the
types being used for partial ordering.  [<I>Note:</I>
A template parameter used
in a non-deduced context is considered used.]</P>

<P>
[<I>Example:</I>
<PRE>
template &lt;class T&gt; T f(int);        // #1
template &lt;class T, class U&gt; T f(U); // #2
void g() {
    f&lt;int&gt;(1);  // Calls #1
}
</PRE>
--<I>end example</I>]
</P>

</BLOCKQUOTE>


<BR><BR><HR><A NAME="180"></A><H4>180.
  
<TT>typename</TT> and elaborated types
</H4><B>Section: </B>14.6&#160; [temp.res]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>21 Dec 1999<BR>



<P>[Moved to DR at 4/02 meeting.]</P>



<P><U>Mike Miller</U>:
A question about <TT>typename</TT> came up in the discussion of
<A HREF="
     cwg_defects.html#68">issue 68</A> that is somewhat relevant
to the idea of omitting
typename in contexts where it is clear that a type is
required: consider something like</P>

<PRE>
        template &lt;class T&gt;
        class X {
            friend class T::nested;
        };
</PRE>

Is <TT>typename</TT> required here?  If so, where would it go?  (The
grammar doesn't seem to allow it anywhere in an
<I>elaborated-type-specifier</I> that has a <I>class-key</I>.)

<P><U>Bill Gibbons</U>:
The <TT>class</TT> applies to the last identifier in the qualified name,
since all the previous names must be classes or namespaces.  Since the
name is specified to be a class it does not need <TT>typename</TT>.
[However,] it looks like
14.6 [temp.res]
 paragraph 3 requires
<TT>typename</TT> and the following paragraphs
do not exempt this case.  This is not what we agreed on.</P>

<P><B>Proposed resolution (04/01):</B></P>

<P>In 14.6 [temp.res] paragraph 5, change</P>

<BLOCKQUOTE>

The keyword <TT>typename</TT> is not permitted in a
<I>base-specifier</I> or in a <I>mem-initializer</I>; in these
contexts a <I>qualified-name</I> that depends on a
<I>template-parameter</I> (14.6.2 [temp.dep]) is
implicitly assumed to be a type name.

</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>

A qualified name used as the name in a <I>mem-initializer-id</I>,
a <I>base-specifier</I>, or an <I>elaborated-type-specifier</I>
(in the <I>class-key</I> and <TT>enum</TT> forms) is implicitly
assumed to name a type, without the use of the <TT>typename</TT>
keyword.  [<I>Note:</I> the <TT>typename</TT> keyword is not
permitted by the syntax of these constructs.]

</BLOCKQUOTE>

<P>(The expected resolution for <A HREF="
     cwg_defects.html#254">issue 254</A> will remove the <TT>typename</TT> forms from the
grammar for <I>elaborated-type-specifier</I>.  If that
resolution is adopted, the parenthetical phrase "(in the
<I>class-key</I> and <TT>enum</TT> forms)" in the preceding
wording should be removed because those will be the only forms
of <I>elaborated-type-specifier</I>.)</P>

<P>This has been consolidated with the edits for some other
issues.  See N1376=02-0034.</P>

<BR><BR><HR><A NAME="345"></A><H4>345.
  
Misleading comment on example in templates chapter
</H4><B>Section: </B>14.6&#160; [temp.res]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Shirk
 &#160;&#160;&#160;

 <B>Date: </B>18 March 2002<BR>


<P>[Voted into WP at April 2003 meeting.]</P>



<P>The following example from 14.6 [temp.res] paragraph 4:</P>
<PRE>
struct A {
	struct X { };
	int X;
};
template&lt;class T&gt; void f(T t) {
	typename T::X x;        //  ill-formed: finds the data member  X
					//  not the member type  X
}
</PRE>

<P>
is not ill-formed.  The intent of the example is obvious, but some
mention should be made that it is only ill-formed when T=A.  For other
T's, it could be well formed.</P>

<P><B>Proposed resolution (October 2002):</B></P>

<P>
In 14.6 [temp.res] paragraph 4, replace the example with:</P>
<BLOCKQUOTE>
<PRE>
struct A {
  struct X { };
  int X; 
} ; 
struct B {
  struct X { };
} ;
template&lt;class T&gt; void f(T t) {
  typename T::X x; 
}
void foo() {
  A a; 
  B b;
  f(b);  // OK -- T::X refers to B::X.
  f(a);  // error: T::X refers to the data member A::X not 
         // the struct A::X.
}
</PRE>
</BLOCKQUOTE>

<BR><BR><HR><A NAME="382"></A><H4>382.
  
Allow <TT>typename</TT> outside of templates
</H4><B>Section: </B>14.6&#160; [temp.res]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>8 Nov 2002<BR>


<P>[Voted into WP at October 2005 meeting.]</P>

<P>P. J. Plauger, among others, has noted that <TT>typename</TT> is hard
to use, because in a given context it's either required or forbidden,
and it's often hard to tell which.
It would make life easier for programmers if <TT>typename</TT>
could be allowed in places where it is not required, e.g., outside
of templates.</P>

<P><B>Notes from the April 2003 meeting:</B></P>

<P>There was unanimity on relaxing this requirement on typename.
The question was how much to relax it.  Everyone agreed on allowing
it on all qualified names, which is an easy fix (no syntax change
required).  But should it be allowed other places?  P.J. Plauger
said he'd like to see it allowed anywhere a type name is allowed,
and that it could actually be a decades-late assist for the infamous
"the ice is thin here" typedef problem noted in K&amp;R I.</P>

<P><B>Proposed resolution (April 2003):</B></P>

<P>Replace the text at the start of 14.6 [temp.res] paragraph 3:</P>

<BLOCKQUOTE>
A <I>qualified-id</I> that refers to a type and in which 
the <I>nested-name-specifier</I>
depends on a <I>template-parameter</I> (14.6.2 [temp.dep])
shall be prefixed by the keyword
<TT>typename</TT> to indicate that
the <I>qualified-id</I> denotes a type, forming an
<I>elaborated-type-specifier</I> (7.1.6.3 [dcl.type.elab]). 
</BLOCKQUOTE>

<P>With:</P>

<BLOCKQUOTE>
The keyword <TT>typename</TT> can only be applied to a <I>qualified-id</I>. A
<I>qualified-id</I> that refers to a type and in which
the <I>nested-name-specifier</I>
depends on a <I>template-parameter</I> (14.6.2 [temp.dep])
shall be prefixed by the keyword
<TT>typename</TT> to indicate that the <I>qualified-id</I>
denotes a type, forming
an <I>elaborated-type-specifier</I> (7.1.6.3 [dcl.type.elab]).
If a <I>qualified-id</I> which
has been prefixed by the keyword <TT>typename</TT> does not
denote a type the program is ill-formed.
[ <I>Note:</I> The keyword is only required on a <I>qualified-id</I> within a
template declaration or definition in which the
<I>nested-name-specifier</I> depends on a <I>template-parameter</I>. ]
</BLOCKQUOTE>

<P>Remove 14.6 [temp.res] paragraph 5:</P>

<BLOCKQUOTE>
The keyword <TT>typename</TT> shall only be used in template
declarations and definitions, including in the return type of a function template or
member function template, in the return type for the definition of a member function
of a class template or of a class nested within a class template, and in the
<I>type-specifier</I> for the definition of a static member of a class template or
of a class nested within a class template. The keyword <TT>typename</TT> shall be
applied only to qualified names, but those names need not be dependent. The keyword
<TT>typename</TT> shall be used only in contexts in which dependent names
can be used. This includes template declarations and definitions but excludes explicit
specialization declarations and explicit instantiation declarations. The keyword
<TT>typename</TT>
is not permitted in a <I>base-specifier</I> or in a <I>mem-initializer</I>; in these
contexts a <I>qualified-id</I> that depends on a <I>template-parameter</I> (temp.dep) is
implicitly assumed to be a type name.
</BLOCKQUOTE>

<P><B>Note:</B> the claim here that a qualified name preceded by
<TT>typename</TT> forms an elaborated type specifier conflicts with
the changes made in <A HREF="
     cwg_defects.html#254">issue 254</A> (see
N1376=02-0034), which introduces <I>typename-specifier</I>.</P>

<P><B>Notes from October 2003 meeting:</B></P>

<P>We considered whether <TT>typename</TT> should be allowed in more
places, and decided we only wanted to allow it in qualified
names (for now at least).</P>

<P><A HREF="
     cwg_defects.html#254">Core issue 254</A> changed
<I>elaborated-type-specifier</I> to <I>typename-specifier</I>.
It also changed 14.6 [temp.res] paragraph 5, which
this proposed resolution deletes.  </P>

<P>See also <A HREF="
     cwg_defects.html#468">issue 468</A>.</P>

<P><B>Proposed resolution (October, 2004):</B></P>

<OL>

<LI><P>Change 14.6 [temp.res] paragraph 3 as
follows:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">When a</SPAN> <I>qualified-id</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">that refers to a
type and</SPAN> in which the <I>nested-name-specifier</I> depends on a
<I>template-parameter</I> (14.6.2 [temp.dep]) <SPAN style="font-weight:bold;background-color:#A0FFA0">is
intended to refer to a type, it</SPAN> shall be prefixed by the
keyword <TT>typename</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">to indicate that the qualified-id
denotes a type</SPAN>, forming a <I>typename-specifier</I>. <SPAN style="font-weight:bold;background-color:#A0FFA0">If
the <I>qualified-id</I> in a <I>typename-specifier</I> does not
denote a type, the program is ill-formed.</SPAN>

</BLOCKQUOTE>

</LI>

<LI><P>Change 14.6 [temp.res] paragraph 5 as
follows:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The keyword <TT>typename</TT> shall only be used in template
declarations and definitions, including in the return type of a
function template or member function template, in the return type
for the definition of a member function of a class template or of
a class nested within a class template, and in the
<I>type-specifier</I> for the definition of a static member of a
class template or of a class nested within a class template. The
keyword <TT>typename</TT> shall be applied only to qualified
names, but those names need not be dependent. The keyword
<TT>typename</TT> shall be used only in contexts in which
dependent names can be used. This includes template declarations
and definitions but excludes explicit specialization declarations
and explicit instantiation declarations.</SPAN> A qualified name
used as the name in a <I>mem-initializer-id</I>, a
<I>base-specifier</I>, or an <I>elaborated-type-specifier</I> is
implicitly assumed to name a type, without the use of the
<TT>typename</TT> keyword. [<I>Note:</I> the <TT>typename</TT>
keyword is not permitted by the syntax of these
constructs. &#8212;<I>end note</I>]

</BLOCKQUOTE>

</LI>

</OL>

<BR><BR><HR><A NAME="409"></A><H4>409.
  
Obsolete paragraph missed by changes for issue 224
</H4><B>Section: </B>14.6&#160; [temp.res]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>18 Apr 2003<BR>


<P>[Voted into WP at October 2004 meeting.]</P>

<P>Paragraph 6 of 14.6 [temp.res] is obsolete as result of
<A HREF="
     cwg_defects.html#224">issue 224</A>, and needs to be revised.</P>
<BLOCKQUOTE>
Within  the definition of a class template or within the definition of
a member of a class template, the keyword  typename  is  not  required
when referring to the unqualified name of a previously declared member
of the class template that declares  a  type.   The  keyword  typename
shall always be specified when the member is referred to using a qual-
ified name, even if the qualifier is simply the class  template  name.
[<I>Example:</I>
<PRE>
  template&lt;class T&gt; struct A {
      typedef int B;
      A::B b;                     // ill-formed: typename required before A::B
      void f(A&lt;T&gt;::B);            // ill-formed: typename required before A&lt;T&gt;::B
      typename A::B g();          // OK
  };
</PRE>
]
</BLOCKQUOTE>

<P><B>Proposed Resolution:</B></P>
<P>
Change 14.6 [temp.res] paragraph 6 as follows</P>
<BLOCKQUOTE>
Within the definition of a class template or within the definition of
a member of a class template, the keyword <TT>typename</TT> is not
required when referring to the unqualified name of a previously
declared member of the class template that declares a type.
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The keyword <TT>typename</TT> shall always be specified when the
member is referred to using a qualified name, even if the qualifier is
simply the class template name.</SPAN> [Example:

<PRE>
template&lt;class T&gt; struct A {
    typedef int B;
    B b;                      // ok, no typename required
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">    A::B b;                   //  ill-formed: typename required before  A::B
    void f(A&lt;T&gt;::B);          //  ill-formed: typename required before  A&lt;T&gt;::B
    typename A::B g();        //  OK</SPAN>
};
</PRE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The keyword typename is required whether the qualified name is A or
A&lt;T&gt; because A or A&lt;T&gt; are synonyms within a class template with
the parameter list &lt;T&gt;. </SPAN>]
</BLOCKQUOTE>

<BR><BR><HR><A NAME="559"></A><H4>559.
  
Editing error in issue 382 resolution
</H4><B>Section: </B>14.6&#160; [temp.res]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>11 February 2006<BR>


<P>[Voted into WP at April, 2006 meeting.]</P>

<P>Part of the resolution for <A HREF="
     cwg_defects.html#224">issue 224</A> was
the addition of the phrase &#8220;but does not refer to a member of
the current instantiation&#8221; to 14.6 [temp.res]
paragraph 3.  When the resolution of <A HREF="
     cwg_defects.html#382">issue 382</A>
was added to the current working draft, however, that phrase was
inadvertently removed.  Equivalent phrasing should be restored.</P>

<P><B>Proposed resolution (April, 2006):</B></P>

<P>Replace the first sentence of 14.6 [temp.res] paragraph 3
with the following text:</P>

<BLOCKQUOTE>

When a <I>qualified-id</I> is intended to refer to a type that is not
a member of the current instantiation (14.6.2.1 [temp.dep.type]) and its <I>nested-name-specifier</I> depends on a
<I>template-parameter</I> (14.6.2 [temp.dep]), it shall be
prefixed by the keyword <TT>typename</TT>, forming
a <I>typename-specifier</I>.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="666"></A><H4>666.
  
Dependent <I>qualified-id</I>s without the <TT>typename</TT> keyword
</H4><B>Section: </B>14.6&#160; [temp.res]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>6 December 2007<BR>


<P>[Voted into the WP at the June, 2008 meeting.]</P>

<P>14.6 [temp.res] paragraphs 2 and 4 read,</P>

<BLOCKQUOTE>

<P>A name used in a template declaration or definition and that is
dependent on a <I>template-parameter</I> is assumed not to name a type unless
the applicable name lookup finds a type name or the name is qualified
by the keyword <I>typename</I>.</P>

<P>If a specialization of a template is instantiated for a set of
<I>template-argument</I>s such that the <I>qualified-id</I> prefixed
by <TT>typename</TT> does not denote a type, the specialization is
ill-formed.</P>

</BLOCKQUOTE>

<P>It is not clear whether this is intended to, or is sufficient to,
render a specialization ill-formed if a dependent <I>qualified-id</I>
that is <I>not</I> prefixed by <TT>typename</TT> actually <I>does</I>
denote a type.  For example,</P>

<PRE>
    int i;

    template &lt;class T&gt; void f() {
        T::x * i; //<SPAN style="font-family:Times;font-style:italic"> declaration or multiplication!?</SPAN>
    }

    struct Foo {
        typedef int x;
    };

    struct Bar {
        static int const x = 5;
    };

    int main() {
        f&lt;Bar&gt;(); //<SPAN style="font-family:Times;font-style:italic"> multiplication</SPAN>
        f&lt;Foo&gt;(); //<SPAN style="font-family:Times;font-style:italic"> declaration!</SPAN>
    }
</PRE>

<P>I think that the specialization for <TT>Foo</TT> should be
ill-formed.</P>

<P><B>Proposed resolution (February, 2008):</B></P>

<P>Add the following after 14.6 [temp.res] paragraph 5:</P>

<BLOCKQUOTE>

<P>If, for a given set of template arguments, a specialization of a template
is instantiated that refers to a <I>qualified-id</I> that denotes a type,
and the <I>nested-name-specifier</I> of the <I>qualified-id</I> depends
on a template parameter, the <I>qualified-id</I> shall either be prefixed
by <TT>typename</TT> or shall be used in a context in which it implicitly
names a type as described above.  [<I>Example:</I></P>

<PRE>
    template &lt;class T&gt; void f(int i) {
      T::x * i;     //<SPAN style="font-family:Times;font-style:italic"> </SPAN>T::x<SPAN style="font-family:Times;font-style:italic"> must not be a type</SPAN>
    }

    struct Foo {
      typedef int x;
    };

    struct Bar {
      static int const x = 5;
    };

    int main() {
      f&lt;Bar&gt;(1);     //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
      f&lt;Foo&gt;(1);     //<SPAN style="font-family:Times;font-style:italic"> error: </SPAN>Foo::x<SPAN style="font-family:Times;font-style:italic"> is a type</SPAN>
    }
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="515"></A><H4>515.
  
Non-dependent references to base class members
</H4><B>Section: </B>14.6.2&#160; [temp.dep]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>18 Apr 2005<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>

<P>Implementations vary in their treatment of the following code:</P>

<PRE>
    struct A {
      int foo_;
    };
    template &lt;typename T&gt; struct B: public A { };
    template &lt;typename T&gt; struct C: B&lt;T&gt; {
      int foo() {
        return A::foo_;  //<SPAN style="font-family:Times;font-style:italic"> #1</SPAN>
      }
    };
    int f(C&lt;int&gt;* p) {
      return p-&gt;foo();
    }
</PRE>

<P>According to <A HREF="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21008">one
analysis</A>, because the expression <TT>A::foo_</TT> on line #1
is non-dependent, it must be analyzed in the definition
context.  It that context, it violates the restrictions of
9.2 [class.mem] paragraph 10 on how the name of a
nonstatic data member of a class can be used and thus should be
treated as an error.</P>

<P>On the other hand, the description of the transformation of
an <I>id-expression</I> into a class member access expression
(9.3.1 [class.mfct.non-static] paragraph 3) does not have any special
treatment of templates; when <TT>C&lt;int&gt;::foo()</TT> is
instantiated, the reference to <TT>A::foo_</TT> turns out to be to a
base class member and is thus transformed into
<TT>(*this).A::foo_</TT> and is thus not an error.</P>

<P><B>Proposed resolution (October, 2005):</B></P>

<P>Change 9.3.1 [class.mfct.non-static] paragraph 3 as indicated:</P>

<BLOCKQUOTE>

When an <I>id-expression</I> (5.1.1 [expr.prim.general]) that is not
part of a class member access syntax (5.2.5 [expr.ref])
and not used to form a pointer to member (5.3.1 [expr.unary.op]) is used in the body of a non-static member function
of class <TT>X</TT> or used in the <I>mem-initializer</I> for a
constructor of class <TT>X</TT>, if name lookup (3.4.1 [basic.lookup.unqual]) resolves the name in the <I>id-expression</I> to a
non-static non-type member of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">class <TT>X</TT> or of a base class
of <TT>X</TT></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">some class <TT>C</TT></SPAN>,
the <I>id-expression</I> is transformed into a class member access
expression (5.2.5 [expr.ref]) using <TT>(*this)</TT>
(9.3.2 [class.this]) as the
<I>postfix-expression</I> to the left of the <TT>.</TT>
operator.  <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> If <TT>C</TT> is not <TT>X</TT> or a base
class of <TT>X</TT>, the class member access expression is ill-formed.
&#8212;<I>end note</I>]</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The member name then refers to the
member of the object for which the function is called.</SPAN> Similarly
during name lookup...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="524"></A><H4>524.
  
Can function-notation calls to operator functions be dependent?
</H4><B>Section: </B>14.6.2&#160; [temp.dep]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>19 July 2005<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>

<P>The description of dependent function calls in
14.6.2 [temp.dep] paragraph 1 applies only to
<I>identifier</I>s in postfix-notation function calls and to operator
notation calls for operator functions:</P>

<BLOCKQUOTE>

<P>In an expression of the form:</P>

<UL><I>postfix-expression</I> <TT>(</TT> <I>expression-list<SUB>opt</SUB></I> <TT>)</TT></UL>

<P>where the <I>postfix-expression</I> is an <I>identifier</I>,
the <I>identifier</I> denotes a <I>dependent name</I> if and only if
any of the expressions in the <I>expression-list</I> is a
type-dependent expression (14.6.2.2 [temp.dep.expr]). If an
operand of an operator is a type-dependent expression, the operator
also denotes a dependent name.</P>

</BLOCKQUOTE>

<P>It would appear from the related passage in
14.6.4.2 [temp.dep.candidate] paragraph 1 that the description of
postfix-notation function calls should apply to all
<I>unqualified-id</I>s that are not <I>template-id</I>s,
including <I>operator-function-id</I>s, not just to
<I>identifier</I>s:</P>

<BLOCKQUOTE>

For a function call that depends on a template parameter, if the
function name is an <I>unqualified-id</I> but not
a <I>template-id</I>, the candidate functions are found...

</BLOCKQUOTE>

<P><B>Proposed resolution (October, 2005):</B></P>

<OL><LI><P>Change 14.6.2 [temp.dep] paragraph 1 as
indicated:</P></LI>

<BLOCKQUOTE>

<P>...In an expression of the form:</P>

<UL><I>postfix-expression </I><TT>(</TT><I> expression-list<SUB>opt</SUB> </I><TT>)</TT></UL>

<P>where the <I>postfix-expression</I> is an <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>identifier</I></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>unqualified-id</I> but not a <I>template-id</I></SPAN>,
the <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>identifier</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>unqualified-id</I></SPAN> denotes
a <I>dependent name</I> if and only if any of the expressions in
the <I>expression-list</I> is a type-dependent expression
(14.6.2.2 [temp.dep.expr])...</P>

</BLOCKQUOTE>

<LI><P>Change 14.6.4.2 [temp.dep.candidate] paragraph 1 as
indicated:</P></LI>

<BLOCKQUOTE>

For a function call that depends on a template parameter, if the
function name is an <I>unqualified-id</I> but not
a <I>template-id</I>, <SPAN style="font-weight:bold;background-color:#A0FFA0">or if the function is called using operator
notation,</SPAN> the candidate functions are found using the
usual lookup rules (3.4.1 [basic.lookup.unqual], 3.4.2 [basic.lookup.argdep]) except that...

</BLOCKQUOTE>

</OL>

<P>(See also <A HREF="
     cwg_defects.html#561">issue 561</A>.)</P>

<BR><BR><HR><A NAME="224"></A><H4>224.
  
Definition of dependent names
</H4><B>Section: </B>14.6.2.1&#160; [temp.dep.type]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Derek Inglis
 &#160;&#160;&#160;

 <B>Date: </B>30 Nov 1999<BR>


<P>[Moved to DR at 10/01 meeting.]</P>



<P>The definition of when a type is dependent, given in
14.6.2.1 [temp.dep.type], is essentially syntactic: if the
reference is a <I>qualified-id</I> and one of the <I>class-name</I>s
in the <I>nested-name-specifier</I> is dependent, the type is
dependent.  This approach leads to surprising results:</P>

<PRE>
    template &lt;class T&gt; class X {
        typedef int I;
	I a;                 // non-dependent
        typename X&lt;T&gt;::I b;  // dependent
        typename X::I c;     // dependent (X is equivalent to X&lt;T&gt;)
    };
</PRE>

<P><B>Suggested resolution:</B></P>

<P>The decision on whether a name is dependent or non-dependent should
be based on lookup, not on the form of the name: if the name can be
looked up in the definition context and cannot be anything else as the
result of specialization, the name should be non-dependent.</P>

<P>See papers J16/00-0028 = WG21 N1251 and
J16/00-0056 = WG21 N1279.</P>

<P><B>Proposed resolution (10/00):</B></P>

<OL>

<LI><P>Replace section 14.6.2.1 [temp.dep.type] with the
following:

<BLOCKQUOTE>

<P>In the definition of a class template, a nested class of a class
template, a member of a class template, or a member of a nested class
of a class template, a name refers to the <I>current
instantiation</I> if it is</P>

<UL>

<LI>the injected-class-name (clause 9 [class]) of the
class template or nested class,</LI>

<LI>in the definition of a primary class template, the name of the
class template followed by the template argument list of the
primary template (as described below) enclosed in &lt;&gt;,</LI>

<LI>in the definition of a nested class of a class template,
the name of the nested class referenced as a member of the
current instantiation, or</LI>

<LI>in the definition of a partial specialization, the name of
the class template followed by the template argument list of
the partial specialization enclosed in &lt;&gt;.</LI>

</UL>

<P>The template argument list of a primary template is a
template argument list in which the n<SUP>th</SUP> template
argument has the value of the n<SUP>th</SUP> template
parameter of the class template.</P>

<P>A template argument that is equivalent to a template
parameter (i.e., has the same constant value or the same type
as the template parameter) can be used in place of that
template parameter in a reference to the current
instantiation.  In the case of a nontype template argument,
the argument must have been given the value of the
template parameter and not an expression involving the
template parameter.</P>

<P>[<I>Example:</I></P>

<PRE>
template &lt;class T&gt; class A {
    A* p1;      // A is the current instantiation
    A&lt;T&gt;* p2;   // A&lt;T&gt; is the current instantiation
    A&lt;T*&gt; p3;   // A&lt;T*&gt; is not the current instantiation
    ::A&lt;T&gt;* p4; // ::A&lt;T&gt; is the current instantiation
    class B {
	B* p1;        // B is the current instantiation
	A&lt;T&gt;::B* p2;  // A&lt;T&gt;::B is the current instantiation
	typename A&lt;T*&gt;::B* p3; // A&lt;T*&gt;::B is not the
			     // current instantiation
    };
};

template &lt;class T&gt; class A&lt;T*&gt; {
    A&lt;T*&gt;* p1;  // A&lt;T*&gt; is the current instantiation
    A&lt;T&gt;* p2;   // A&lt;T&gt; is not the current instantiation
};

template &lt;class T1, class T2, int I&gt; struct B {
    B&lt;T1, T2, I&gt;*	b1;        // refers to the current instantiation
    B&lt;T2, T1, I&gt;*	b2;        // not the current instantiation
    typedef T1 my_T1;
    static const int my_I = I;
    static const int my_I2 = I+0;
    static const int my_I3 = my_I;
    B&lt;my_T1, T2, my_I&gt;* b3;  // refers to the current instantiation
    B&lt;my_T1, T2, my_I2&gt;* b4; // not the current instantiation
    B&lt;my_T1, T2, my_I3&gt;* b5; // refers to the current instantiation
};
</PRE>

<P>&#8212;<I>end example</I>]</P>

<P>A name is a <I>member of the current instantiation</I> if it is</P>

<UL>

<LI>An unqualified name that, when looked up, refers to a member
of a class template.  [<I>Note:</I> This can only occur when
looking up a name in a scope enclosed by the definition of a
class template.]</LI>

<LI>A <I>qualified-id</I> in which the <I>nested-name-specifier</I>
refers to the current instantiation.</LI>

</UL>

<P>[<I>Example:</I></P>

<PRE>
template &lt;class T&gt; class A {
    static const int i = 5;
    int n1[i];        // i refers to a member of the current instantiation 
    int n2[A::i];     // A::i refers to a member of the current instantiation 
    int n3[A&lt;T&gt;::i];  // A&lt;T&gt;::i refers to a member of the current instantiation 
    int f();
};

template &lt;class T&gt; int A&lt;T&gt;::f()
{
    return i;  // i refers to a member of the current instantiation
}
</PRE>

<P>&#8212;<I>end example</I>]</P>

<P>A name is a <I>member of an unknown specialization</I> if the
name is a <I>qualified-id</I> in which the
<I>nested-name-specifier</I> names a dependent type that is not
the current instantiation.</P>

<P>A type is dependent if it is</P>

<UL>

<LI>a template parameter,</LI>

<LI>a member of an unknown specialization,</LI>

<LI>a nested class that is a member of the current
instantiation,</LI>

<LI>a cv-qualified type where the cv-unqualified type is dependent,</LI>

<LI>a compound type constructed from any dependent type,</LI>

<LI>an array type constructed from any dependent type or whose
size is specified by a constant expression that is value-dependent, or</LI>

<LI>a <I>template-id</I> in which either the template name is a
template parameter or any of the template arguments is a dependent
type or an expression that is type-dependent or value-dependent.</LI>

</UL>

<P>[<I>Note:</I> Because typedefs to not introduce new types, but
instead simply refer to other types, a name that refers to a
typedef that is a member of the current instantiation is dependent
only if the type referred to is dependent.]</P>

</BLOCKQUOTE>

</P></LI>

<LI><P>In 14.6.2.2 [temp.dep.expr] paragraph 3, replace</P>

<BLOCKQUOTE>

<UL><LI>a <I>nested-name-specifier</I> that contains a
<I>class-name</I> that names a dependent type.</LI></UL>

</BLOCKQUOTE>

<P>with</P>

<BLOCKQUOTE>

<UL><LI>a <I>nested-name-specifier</I> or <I>qualified-id</I> that
names a member of an unknown specialization.</LI></UL>

</BLOCKQUOTE>

</LI>

<LI><P>In 14.6.2.2 [temp.dep.expr], add the following
paragraph:</P>

<BLOCKQUOTE>

A class member access expression (5.2.5 [expr.ref]) is
type-dependent if the type of the referenced member is dependent.
[<I>Note:</I> In an expression of the form <TT>x.y</TT> or
<TT>xp-&gt;y</TT> the type of the expression is usually the type
of the member <TT>y</TT> of the class of <TT>x</TT> (or the class
pointed to by <TT>xp</TT>).  However, if <TT>x</TT> or <TT>xp</TT>
refers to a dependent type that is not the current instantiation,
the type of <TT>y</TT> is always dependent.  If <TT>x</TT> or
<TT>xp</TT> refers to a non-dependent type or refers to the
current instantiation, the type of <TT>y</TT> is the type of the
class member access expression.]

</BLOCKQUOTE>

</LI>

<LI><P>In 14.6 [temp.res] paragraph 3, replace</P>

<BLOCKQUOTE>

A <I>qualified-name</I> that refers to a type and that depends
on a <I>template-parameter</I> (14.6.2 [temp.dep]) shall
be prefixed by the keyword <TT>typename</TT>.

</BLOCKQUOTE>

<P>with</P>

<BLOCKQUOTE>

A <I>qualified-id</I> that refers to a type and that depends on
a <I>template-parameter</I> (14.6.2 [temp.dep]) but
does not refer to a member of the current instantiation shall be
prefixed by the keyword <TT>typename</TT>.

</BLOCKQUOTE>

<P>Note: the wording for this paragraph was changed in TC1.  The
words shown here are the pre-TC1 words.</P>

</LI>

<LI><P>In 14.2 [temp.names] paragraph 4, replace</P>

<BLOCKQUOTE>

When the name of a member template specialization appears after
<TT>.</TT> or <TT>-&gt;</TT> in a <I>postfix-expression</I>, or
after a <I>nested-name-specifier</I> in a <I>qualified-id</I>,
and the <I>postfix-expression</I> or <I>qualified-id</I> explicitly
depends on a <I>template-parameter</I> (14.6.2 [temp.dep]),
the member template name must be prefixed by the keyword
<TT>template</TT>.  Otherwise the name is assumed to name a
non-template.

</BLOCKQUOTE>

<P>with</P>

<BLOCKQUOTE>

When the name of a member template specialization appears after
<TT>.</TT> or <TT>-&gt;</TT> in a <I>postfix-expression</I>, or
after a <I>nested-name-specifier</I> in a <I>qualified-id</I>,
and the <I>postfix-expression</I> or <I>qualified-id</I> explicitly
depends on a <I>template-parameter</I> (14.6.2 [temp.dep])
but does not refer to a member of the current instantiation
(14.6.2.1 [temp.dep.type]), the member template name must
be prefixed by the keyword <TT>template</TT>.  Otherwise the name
is assumed to name a non-template.

</BLOCKQUOTE>

</LI>

<LI><P>In 14.6.1 [temp.local] paragraph 2, remove the
following text, which was added for <A HREF="
     cwg_defects.html#108">issue 108</A>.
The updated definition of dependent name now addresses this case.</P>

<BLOCKQUOTE>

<P>Within the scope of a class template, when the unqualified name of
a nested class of the class template is referred to, it is
equivalent to the name of the nested class qualified by the name
of the enclosing class template.  [<I>Example:</I></P>

<PRE>
template &lt;class T&gt; struct A {
	class B {};
	// B is equivalent to A::B, which is equivalent to A&lt;T&gt;::B,
	// which is dependent.
	class C : B { };
};
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

</LI>

</OL>

<BR><BR><HR><A NAME="447"></A><H4>447.
  
Is offsetof type-dependent?
</H4><B>Section: </B>14.6.2.3&#160; [temp.dep.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mark Mitchell
 &#160;&#160;&#160;

 <B>Date: </B>7 Jan 2004<BR>


<P>[Voted into WP at October 2005 meeting.]</P>

<P>As far as I can tell, the standard doesn't say whether "offsetof(...)"
is type-dependent.  In the abstract, it shouldn't be -- an "offsetof"
expression is always of type "size_t". But the standard doesn't say to
what the definition of the macro is, so I don't think one can deduce
that it will always be considered non-dependent by a conforming
compiler.</P>

<P><U>John Spicer:</U>
(1) I agree that you can't know if offsetof is dependent because you
don't know what it expands to.
(2) In principle, offsetof should be like sizeof -- it is value-dependent
if its argument is type-dependent.</P>

<P><U>Mark Mitchell:</U>
I think we should say that:
(a) offsetof is not type-dependent, and
(b) offsetof is value dependent iff the first argument is type-dependent</P>

<P>Everyone is using slightly different builtins to implement this
functionality, and I don't think that there's any guarantee that they're all
behaving the same here.</P>

<P><B>Notes from the March 2004 meeting:</B></P>

<P>Note that any such requirement would be in the library section,
not core.</P>

<P><B>Proposed resolution (October, 2004):</B></P>

<OL>

<LI><P>At the end of 14.6.2.2 [temp.dep.expr] paragraph
4, add after the list that ends with <TT>throw</TT>
<I>assignment-expression</I>:</P>

<BLOCKQUOTE>

[<I>Note:</I> For the standard library macro <TT>offsetof</TT>,
see 18.2 [support.types]. &#8212;<I>end note</I>]

</BLOCKQUOTE>

</LI>

<LI><P>At the end of 14.6.2.3 [temp.dep.constexpr] paragraph
2, add after the list that ends with
<TT>sizeof(</TT><I>type-id</I><TT>)</TT>:</P>

<BLOCKQUOTE>

[<I>Note:</I> For the standard library macro <TT>offsetof</TT>,
see 18.2 [support.types]. &#8212;<I>end note</I>]

</BLOCKQUOTE>

</LI>

<LI><P>In 18.2 [support.types] paragraph 4, replace</P>

<BLOCKQUOTE>

The macro <TT>offsetof</TT> accepts a restricted set of
<I>type</I> arguments in this International Standard. If
<I>type</I> is not a POD structure or a POD union the results are
undefined. The result of applying the <TT>offsetof</TT> macro to
a field that is a static data member or a function member is
undefined.

</BLOCKQUOTE>

<P>with</P>

<BLOCKQUOTE>

The macro <TT>offsetof(</TT><I>type</I><TT>,</TT>
<I>member-designator</I><TT>)</TT> accepts a restricted set of
<I>type</I> arguments in this International Standard. If
<I>type</I> is not a POD structure or a POD union (clause
9 [class]), the results are undefined. The
expression <TT>offsetof(</TT><I>type</I><TT>,</TT>
<I>member-designator</I><TT>)</TT> is never type-dependent
(14.6.2.2 [temp.dep.expr]) and it is value-dependent
(14.6.2.3 [temp.dep.constexpr]) if and only if <I>type</I> is
dependent. The result of applying the <TT>offsetof</TT> macro to
a field that is a static data member or a function member is
undefined.

</BLOCKQUOTE>

<P><I>[Note: the original wording shown here reflects the
resolutions of library issues 306 and 449.]</I></P>

</LI>

</OL>

<BR><BR><HR><A NAME="197"></A><H4>197.
  
Issues with two-stage lookup of dependent names
</H4><B>Section: </B>14.6.4.2&#160; [temp.dep.candidate]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Derek Inglis
 &#160;&#160;&#160;

 <B>Date: </B>26 Jan 2000<BR>



<P>[Voted into WP at October 2005 meeting.]</P>



<P>The example in
14.6 [temp.res]
 paragraph 9 is incorrect,
according to 14.6.4.2 [temp.dep.candidate]
.  The
example reads,</P>

<PRE>
    void f(char);

    template &lt;class T&gt; void g(T t)
    {
        f(1);        // f(char);
        f(T(1));     // <I>dependent</I>
        f(t);        // <I>dependent</I>
        dd++;        // <I>not dependent</I>
                     // <I>error: declaration for dd not found</I>
    }

    void f(int);

    double dd;
    void h()
    {
        g(2);        // <I>will cause one call of </I>f(char)<I> followed</I>
                     // <I>by two calls of </I>f(int)
        g('a');      // <I>will cause three calls of </I>f(char)
    }
</PRE>

Since 14.6.4.2 [temp.dep.candidate]
 says that
only Koenig lookup is done from the instantiation context, and since
3.4.2 [basic.lookup.argdep]
 says that
fundamental types have no associated namespaces, either the example is
incorrect (and <TT>f(int)</TT> will never be called) or the
specification in 14.6.4.2 [temp.dep.candidate]

is incorrect.

<P><B>Notes from 04/00 meeting:</B></P>

<P>The core working group agreed that the example as written is
incorrect and should be reformulated to use a class type instead of a
fundamental type.  It was also decided to open a new issue dealing
more generally with Koenig lookup and fundamental types.</P>

<P>(See also issues <A HREF="
     cwg_defects.html#213">213</A> and
<A HREF="
     cwg_closed.html#225">225</A>.)</P>

<P><B>Proposed resolution (April, 2005):</B></P>

<P>Change the example in 14.6 [temp.res] paragraph 9 as
follows:</P>

<PRE>
    void f(char);

    template &lt;class T&gt; void g(T t)
    {
        f(1);        // f(char);
        f(T(1));     // <I>dependent</I>
        f(t);        // <I>dependent</I>
        dd++;        // <I>not dependent</I>
                     // <I>error: declaration for </I>dd<I> not found</I>
    }

    <SPAN style="font-weight:bold;background-color:#A0FFA0">enum E { e };</SPAN>
    void f(<SPAN style="text-decoration:line-through;background-color:#FFA0A0">int</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">E</SPAN>);

    double dd;
    void h()
    {
        g(<SPAN style="text-decoration:line-through;background-color:#FFA0A0">2</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">e</SPAN>);       // <I>will cause one call of </I>f(char)<I> followed</I>
                     // <I>by two calls of </I>f(<SPAN style="text-decoration:line-through;background-color:#FFA0A0">int</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">E</SPAN>)
        g('a');      // <I>will cause three calls of</I> f(char)
    }
</PRE>

<BR><BR><HR><A NAME="387"></A><H4>387.
  
Errors in example in 14.6.5
</H4><B>Section: </B>14.6.5&#160; [temp.inject]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Aleksey Gurtovoy
 &#160;&#160;&#160;

 <B>Date: </B>27 Oct 2002<BR>


<P>[Voted into WP at March 2004 meeting.]</P>

<P>The example in 14.6.5 [temp.inject]
paragraph 2 is incorrect:</P>
<PRE>
  template&lt;typename T&gt; class number {
      number(int);
      //...
      friend number gcd(number&amp; x, number&amp; y) { /* ... */ }
      //...
  };

  void g()
  {
      number&lt;double&gt; a(3), b(4);
      //...
      a = gcd(a,b);   // finds gcd because number&lt;double&gt; is an
                      // associated class, making gcd visible
                      // in its namespace (global scope)
      b = gcd(3,4);   // ill-formed; gcd is not visible
  }
</PRE>
<P>Regardless of the last statement ("b = gcd(3,4);"), the above code is
ill-formed:</P>

<P>  a) number's constructor is private;</P>
<P>  b) the definition of (non-void) friend 'gcd' function does not
contain a return statement.</P>

<P><B>Proposed resolution (April 2003):</B></P>

<P>
Replace the example in 14.6.5 [temp.inject]
paragraph 2</P>

<BLOCKQUOTE>
<PRE>
  template&lt;typename T&gt; class number {
          number(int);
          //...
          friend number gcd(number&amp; x, number&amp; y) { /* ... */ }
          //...
  };

  void g()
  {
          number&lt;double&gt; a(3), b(4);
          //...
          a = gcd(a,b);           //  finds  gcd  because  number&lt;double&gt;  is an
                                  //  associated class, making  gcd  visible
                                  //  in its namespace (global scope)
          b = gcd(3,4);           //  ill-formed;  gcd  is not visible
  }
</PRE>
</BLOCKQUOTE>

by

<BLOCKQUOTE>
<PRE>
  template&lt;typename T&gt; class number {
     public:
          number(int);
          //...
          friend number gcd(number x, number y) { return 0; }
     private:
          //...
  };

  void g()
  {
          number&lt;double&gt; a(3), b(4);
          //...
          a = gcd(a,b);           //  finds  gcd  because  number&lt;double&gt;  is an
                                  //  associated class, making  gcd  visible
                                  //  in its namespace (global scope)
          b = gcd(3,4);           //  ill-formed;  gcd  is not visible
  }
</PRE>
</BLOCKQUOTE>

<P><I>Drafting note: Added "return" to the friend function, removed
references in gcd arguments, added access specifiers.</I></P>

<BR><BR><HR><A NAME="259"></A><H4>259.
  
Restrictions on explicit specialization and instantiation
</H4><B>Section: </B>14.7&#160; [temp.spec]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Matt Austern
 &#160;&#160;&#160;

 <B>Date: </B>2 Nov 2000<BR>


<P>[Moved to DR at 4/02 meeting.]</P>



<P>According to 14.7 [temp.spec] paragraph 5,</P>

<BLOCKQUOTE>

No program shall explicitly instantiate any template more than once,
both explicitly instantiate and explicitly specialize a template, or
specialize a template more than once for a given set of
<I>template-argument</I>s.

</BLOCKQUOTE>

<P>This rule has an impact on library issue 120.  Library authors
would like to have the freedom to specialize (or not) various
library functions without having to document their choices, while
users need the flexibility to explicitly instantiate library
functions in certain translation units.</P>

<P>If this rule could be slightly weakened, it would reduce the need
for constraining either the library author or the programmer.  For
instance, the rule might be recast to say that if a specialization is
followed by an explicit instantiation in the same translation unit,
the explicit instantiation is ignored.  A specialization and an
explicit instantiation of the same template in two different
translation units would still be an error, no diagnostic required.</P>

<P><B>Proposed resolution (04/01):</B></P>

<OL>
<LI><P>Replace the first sentence of 14.7 [temp.spec]
paragraph 5,</P>

<BLOCKQUOTE>

No program shall explicitly instantiate any template more
than once, both explicitly instantiate and explicitly
specialize a template, or specialize a template more than
once for a given set of <I>template-argument</I>s.

</BLOCKQUOTE>

<P>by</P>

<BLOCKQUOTE>

For a given template and a given set of <I>template-argument</I>s,

<UL>
<LI>an explicit instantiation shall appear at most once in a
program,</LI>

<LI>an explicit specialization shall be defined at most once
according to 3.2 [basic.def.odr] in a program, and</LI>

<LI>both an explicit instantiation and a declaration of an
explicit specialization shall not appear in a program unless
the explicit instantiation follows a declaration of the explicit
specialization.</LI>

</UL>

</BLOCKQUOTE>
</LI>

<LI>
<P>Replace 14.7.2 [temp.explicit] paragraph 4,</P>

<BLOCKQUOTE>

The definition of a non-exported function template, a non-exported
member function template, or a non-exported member function or
static data member of a class template shall be present in every
translation unit in which it is explicitly instantiated.

</BLOCKQUOTE>

<P>by</P>

<BLOCKQUOTE>

For a given set of template parameters, if an explicit
instantiation of a template appears after a declaration of
an explicit specialization for that template, the explicit
instantiation has no effect.  Otherwise, the definition of a
non-exported function template, a non-exported member
function template, or a non-exported member function or static
data member of a class template shall be present in every
translation unit in which it is explicitly instantiated.

</BLOCKQUOTE>
</LI>

</OL>

<BR><BR><HR><A NAME="63"></A><H4>63.
  
Class instantiation from pointer conversion to void*, null and self
</H4><B>Section: </B>14.7.1&#160; [temp.inst]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>13 Oct 1998<BR>



<P>[Moved to DR at October 2002 meeting.]</P>

<P>A template is implicitly instantiated because of a "pointer conversion"
on an argument. This was intended to include related-class conversions,
but it also inadvertently includes conversions to <TT>void*, </TT>null
pointer conversions, cv-qualification conversions and the identity conversion.</P>

<P>It is not clear whether a <TT>reinterpret_cast</TT> of a pointer should
cause implicit instantiation.</P>

<P><B>Proposed resolution (10/01):</B> Replace
14.7.1 [temp.inst]
 paragraph 4, up to the
example, with the following:</P>
<BLOCKQUOTE>
A class template specialization is implicitly instantiated if the
class type is used in a context that requires a completely-defined
object type or if the completeness of the class type might affect the
semantics of the program.  [<I>Note:</I> in particular, if the
semantics of an expression depend on the member or base class lists
of a class template specialization, the class template specialization
is implicitly generated.  For instance, deleting a pointer to class
type depends on whether or not the class declares a destructor, and
conversion between pointer to class types depends on the inheritance
relationship between the two classes involved. ]
</BLOCKQUOTE>

<P>This version differs from the previous version is its use of the
word "might" in the first sentence.</P>

<P>(See also <A HREF="
     cwg_active.html#212">issue 212</A>.)</P>

<BR><BR><HR><A NAME="525"></A><H4>525.
  
Missing <TT>*</TT> in example
</H4><B>Section: </B>14.7.1&#160; [temp.inst]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>25 July 2005<BR>


<P>[Voted into WP at April, 2006 meeting.]</P>

<P>The example in 14.7.1 [temp.inst] paragraph 4 has a
typographical error: the third parameter of function <TT>g</TT>
should be <TT>D&lt;double&gt;* ppp</TT>, but it is missing the
<TT>*</TT>:</P>

<PRE>
  template &lt;class T&gt; class B { /* ... */ };
  template &lt;class T&gt; class D : public B&lt;T&gt; { /* ... */ };
  void f(void*);
  void f(B&lt;int &gt;*);

  void g(D&lt;int&gt;* p, D&lt;char&gt;* pp, D&lt;double&gt; ppp)
  {
    f(p);             //<SPAN style="font-family:Times;font-style:italic"> instantiation of </SPAN>D&lt;int&gt;<SPAN style="font-family:Times;font-style:italic"> required: call </SPAN>f(B&lt;int&gt;*)

    B&lt;char&gt;* q = pp;  //<SPAN style="font-family:Times;font-style:italic"> instantiation of </SPAN>D&lt;char&gt;<SPAN style="font-family:Times;font-style:italic"> required:</SPAN>
                      //<SPAN style="font-family:Times;font-style:italic"> convert </SPAN>D&lt;char&gt;*<SPAN style="font-family:Times;font-style:italic"> to </SPAN>B&lt;char&gt;*
    delete ppp;       //<SPAN style="font-family:Times;font-style:italic"> instantiation of </SPAN>D&lt;double&gt;<SPAN style="font-family:Times;font-style:italic"> required</SPAN>
  }
</PRE>

<P><B>Proposed resolution (October, 2005):</B></P>

<P>As suggested.</P>

<BR><BR><HR><A NAME="237"></A><H4>237.
  
Explicit instantiation and base class members
</H4><B>Section: </B>14.7.2&#160; [temp.explicit]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Christophe de Dinechin
 &#160;&#160;&#160;

 <B>Date: </B>28 Jul 2000<BR>


<P>[Voted into WP at October 2005 meeting.]</P>



<P>In 14.7.2 [temp.explicit] paragraph 7 we read:</P>

<BLOCKQUOTE>
 The explicit instantiation of a class template specialization 
implies the instantiation of all of its members not previously 
explicitly specialized in the translation unit containing the 
explicit instantiation.
</BLOCKQUOTE>

<P>Is "member" intended to mean "non-inherited member?"
If yes, maybe it should be clarified since
10 [class.derived] paragraph 1 says,</P>

<BLOCKQUOTE>
Unless redefined in the derived class, members of a 
base class are also considered to be members of the derived 
class. 

</BLOCKQUOTE>

<P><B>Proposed resolution (October, 2004):</B></P>

<P>Fixed by the resolution of <A HREF="
     cwg_defects.html#470">issue 470</A>.</P>

<BR><BR><HR><A NAME="470"></A><H4>470.
  
Instantiation of members of an explicitly-instantiated class template
</H4><B>Section: </B>14.7.2&#160; [temp.explicit]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Matt Austern
 &#160;&#160;&#160;

 <B>Date: </B>11 May 2004<BR>


<P>[Voted into WP at October 2005 meeting.]</P>


<P>14.7.2 [temp.explicit] paragraph 7 says,</P>

<BLOCKQUOTE>
The explicit instantiation of a class template specialization
implies the instantiation of all of its members not previously
explicitly specialized in the translation unit containing the
explicit instantiation.
</BLOCKQUOTE>

<P>It's not clear whether this &#8220;implied&#8221;
instantiation is implicit or explicit instantiation.  It makes a
difference in cases like the following:</P>

<PRE>
    template &lt;typename T&gt; struct foo {
        struct bar { };
    };

    template struct foo&lt;int&gt;;         // #1

    template struct foo&lt;int&gt;::bar;    // #2
</PRE>

<P>If the instantiation of <TT>foo&lt;int&gt;::bar</TT> implied
by <TT>#1</TT> is implicit, the explicit instantiation in
<TT>#2</TT> is well-formed.  Otherwise, <TT>#2</TT> violates the
requirement in 14.7 [temp.spec] that</P>

<BLOCKQUOTE>
No program shall explicitly instantiate any template more than
once ... for a given set of <I>template-argument</I>s.
</BLOCKQUOTE>

<P>It's also unclear whether the implied instantiation applies
only to direct members of the class template or to inherited
members, as well.</P>

<P><U>John Spicer:</U> I have always interpreted this as meaning
only the members declared in the class, not those inherited from
other classes.  This is what EDG does, and appears to be what
g++, Microsoft and Sun do, too.  I also think this is the correct
thing for the Standard to require.  If I were to derive a class
from a class in the standard library, an explicit instantiation
of my class should not cause the explicit instantiation of things
in the standard library (because the library might provide such
explicit instantiations, thus causing my program to run afoul of
the "can't instantiate more than once" rule).</P>

<P><B>Proposed resolution (October, 2004):</B></P>

<P>Change 14.7.2 [temp.explicit] paragraph 7 as follows:</P>

<BLOCKQUOTE>

The explicit instantiation of a class template specialization
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">implies the instantiation of all</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">also explicitly
instantiates each</SPAN> of its members <SPAN style="text-decoration:line-through;background-color:#FFA0A0">not</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">(not including
members inherited from base classes) whose definition is visible at
the point of instantiation and that has not been</SPAN> previously
explicitly specialized in the translation unit containing the explicit
instantiation.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="551"></A><H4>551.
  
When is <TT>inline</TT> permitted in an explicit instantiation?
</H4><B>Section: </B>14.7.2&#160; [temp.explicit]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Clamage
 &#160;&#160;&#160;

 <B>Date: </B>07 December 2005<BR>


<P>[Voted into the WP at the April, 2007 meeting as part of paper
J16/07-0095 = WG21 N2235.]</P>

<P>The Standard does not definitively say when the <TT>inline</TT>
specifier may be used in an explicit instantiation.  For example,
the following would seem to be innocuous, as the function being
instantiated is already inline:</P>

<PRE>
    template &lt;typename T&gt; struct S {
        void f() { }
    };
    template inline void S&lt;int&gt;::f();
</PRE>

<P>However, presumably one would want to prohibit something like:</P>

<PRE>
    template &lt;typename T&gt; void f(T) { }
    template inline void f(int);
</PRE>

<P>7.1.2 [dcl.fct.spec] paragraph 4 (after application of the
resolution of <A HREF="
     cwg_defects.html#317">issue 317</A>) comes close to
covering the obvious problematic cases:</P>

<BLOCKQUOTE>

If the definition of a function appears in a translation unit before
its first declaration as inline, the program is ill-formed.  If a
function with external linkage is declared inline in one translation
unit, it shall be declared inline in all translation units in which it
appears; no diagnostic is required.

</BLOCKQUOTE>

<P>This would seem to prohibit the latter case, but apparently would
not handle an exported template that was instantiated as inline
(because the definition might not appear in the same translation unit
as the inline instantiation).  It would be better to make a clear
statement regarding the use of <TT>inline</TT> in explicit
instantiations.</P>

<P><B>Notes from the April, 2006 meeting:</B></P>

<P>The CWG favored completely disallowing the <TT>inline</TT> keyword in
explicit instantiation directives.</P>

<BR><BR><HR><A NAME="44"></A><H4>44.
  
Member specializations
</H4><B>Section: </B>14.7.3&#160; [temp.expl.spec]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Nathan Myers
 &#160;&#160;&#160;

 <B>Date: </B>19 Sep 1998<BR>



<P>[Moved to DR at 4/01 meeting.]</P>



<P>Some compilers reject the following:</P>
<PRE>
    struct A {
        template &lt;int I&gt; void f();
        template &lt;&gt; void f&lt;0&gt;();
    };
</PRE>
on the basis of 14.7.3 [temp.expl.spec]

paragraph 2:
<BLOCKQUOTE>An explicit specialization shall be declared in the namespace
of which the template is a member, or, for member templates, in the namespace
of which the enclosing class or enclosing class template is a member. An
explicit specialization of a member function, member class or static data
member of a class template shall be declared in the namespace of which
the class template is a member. ...</BLOCKQUOTE>
claiming that the specialization above is not "in the namespace of which
the enclosing class ... is a member". Elsewhere, declarations are sometimes
required to be "at" or "in" "namespace scope", which is not what it says
here. Paragraph 17 says:
<BLOCKQUOTE>A member or a member template may be nested within many enclosing
class templates. If the declaration of an explicit specialization for such
a member appears in namespace scope, the member declaration shall be preceded
by a <TT>template&lt;&gt;</TT> for each
enclosing class template that is explicitly
specialized.</BLOCKQUOTE>
The qualification "if the declaration ... appears in namespace scope",
implies that it might appear elsewhere. The only other place I can think
of for a member specialization is in class scope.

<P>Was it the intent of the committee to forbid the construction above?
(Note that A itself is not a template.) If so, why?</P>

<P><B>Proposed resolution (04/01):</B> In-class specializations
of member templates are not allowed. In
14.7.3 [temp.expl.spec]
 paragraph 17, replace</P>

<BLOCKQUOTE>
If the declaration of an explicit specialization for such a member
appears in namespace scope...
</BLOCKQUOTE>

with

<BLOCKQUOTE>
In an explicit specialization for such a member...
</BLOCKQUOTE>

<P><B>Notes from 04/00 meeting:</B></P>

<P>This issue was kept in "review" status for two major reasons:</P>

<OL>

<LI>It's not clear that a change is actually needed.  All uses of the
phrase "in the namespace" in the IS mean "directly in the namespace,"
not in a scope nested within the namespace.</LI>

<LI>There was substantial sentiment for actually adding support for
in-class specializations at a future time, and it might be perceived
as a reversal of direction to pass a change aimed at reinforcing the
absence of the feature, only to turn around afterward and add it.</LI>

</OL>

<P><B>Notes from 10/00 meeting:</B></P>

<P>The core working group felt that the value of additional
clarity here outweighs the potential disadvantages that were noted
at the preceding meeting.</P>

<BR><BR><HR><A NAME="275"></A><H4>275.
  
Explicit instantiation/specialization and <I>using-directive</I>s
</H4><B>Section: </B>14.7.3&#160; [temp.expl.spec]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>15 Feb 2001<BR>


<P>[Moved to DR at 4/02 meeting.]</P>



<P>Consider this example:</P>

<PRE>
    namespace N {
	template &lt;class T&gt; void f(T){}
	template &lt;class T&gt; void g(T){}
	template &lt;&gt; void f(int);
	template &lt;&gt; void f(char);
	template &lt;&gt; void g(char);
    }

    using namespace N;

    namespace M {
	template &lt;&gt; void N::f(char){}  // prohibited by standard
	template &lt;class T&gt; void g(T){}
	template &lt;&gt; void g(char){}     // specialization of M::g or ambiguous?
	template void f(long);         // instantiation of N::f?
    }

    template &lt;class T&gt; void g(T){}

    template &lt;&gt; void N::f(char){}  // okay
    template &lt;&gt; void f(int){}      // is this a valid specialization of N::f?

    template void g(int);          // instantiation of ::g(int) or ambiguous?
</PRE>

<P>The question here is whether unqualified names made visible by a
<I>using-directive</I> can be used as the declarator in an explicit
instantiation or explicit specialization.</P>

<P>Note that this question is already answered for qualified names in
8.3 [dcl.meaning] paragraph 1.  In a qualified name such as
<TT>N::f</TT>, <TT>f</TT> must be a member of class or namespace
<TT>N</TT>, not a name made visible in <TT>N</TT> by a
<I>using-directive</I> (or a <I>using-declaration</I>, for that
matter).</P>

<P>The standard does not, as far as I can tell, specify the behavior of
these cases one way or another.</P>

<P>My opinion is that names from <I>using-directive</I>s should not be
considered when looking up the name in an unqualified declarator in an
explicit specialization or explicit instantiation.  In such cases, it
is reasonable to insist that the programmer know exactly which
template is being specialized or instantiated, and that a qualified
name must be used if the template is a member of a namespace.</P>

<P>As the example illustrates, allowing names from
<I>using-directive</I>s to be used would also have the affect of
making ambiguous otherwise valid instantiation and specialization
directives.</P>

<P>Furthermore, permitting names from <I>using-directive</I>s would
require an additional rule to prohibit the explicit instantiation of
an entity in one namespace from being done in another (non-enclosing)
namespace (as in the instantiation of <TT>f</TT> in namespace
<TT>M</TT> in the example).</P>

<P><U>Mike Miller</U>: I believe the explicit specialization case
is already covered by 7.3.1.2 [namespace.memdef] paragraph 2,
which requires using a qualified name to define a namespace member
outside its namespace.</P>

<P><U>John Spicer</U>: 7.3.1.2 [namespace.memdef] deals with
namespace members.  An explicit specialization directive deals with
something that is a specialization of a namespace member.  I don't
think the rules in 7.3.1.2 [namespace.memdef] could be taken to
apply to specializations unless the standard said so explicitly.</P>

<P><B>Proposed resolution (suggested 04/01, proposed 10/01)</B>:</P>

<P>(The first change below will need to be revised in accordance
with the resolution of <A HREF="
     cwg_defects.html#284">issue 284</A> to
add a cross-reference to the text dealing with class names.)</P>

<OL>

<LI><P>Add in 14.7.2 [temp.explicit] paragraph 2 before the
example:</P>

<BLOCKQUOTE>

An explicit instantiation shall appear in an enclosing namespace
of its template.  If the name declared in the explicit
instantiation is an unqualified name, the explicit instantiation
shall appear in the namespace where its template is declared.
[<I>Note:</I> Regarding qualified names in declarators, see
8.3 [dcl.meaning].]

</BLOCKQUOTE>

</LI>

<LI><P>Change the first sentence of 7.3.1.2 [namespace.memdef]
paragraph 1 from</P>

<BLOCKQUOTE>

Members of a namespace can be defined within that namespace.

</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>

Members (including explicit specializations of templates
(14.7.3 [temp.expl.spec])) of a namespace can be defined
within that namespace.

</BLOCKQUOTE>

</LI>

<LI><P>Change the first sentence of 7.3.1.2 [namespace.memdef]
paragraph 2 from</P>

<BLOCKQUOTE>

Members of a named namespace can also be defined...

</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>

Members (including explicit specializations of templates (14.7.3 [temp.expl.spec])) of a named namespace can also be defined...

</BLOCKQUOTE>

</LI>

<LI><P>Change the last sentence of 14.7.3 [temp.expl.spec]
paragraph 2 from</P>

<BLOCKQUOTE>

If the declaration is not a definition, the specialization may be
defined later in the namespace in which the explicit specialization
was declared, or in a namespace that encloses the one in which the
explicit specialization was declared.

</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>

If the declaration is not a definition, the specialization may be
defined later (7.3.1.2 [namespace.memdef]).

</BLOCKQUOTE>

</LI>

</OL>

<BR><BR><HR><A NAME="336"></A><H4>336.
  
Explicit specialization examples are still incorrect
</H4><B>Section: </B>14.7.3&#160; [temp.expl.spec]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Shirk
 &#160;&#160;&#160;

 <B>Date: </B>29 Jan 2002<BR>


<P>[Voted into WP at April 2003 meeting.]</P>



<P>The examples corrected by <A HREF="
     cwg_defects.html#24">issue 24</A> are still
wrong in one case.</P>

<P>In item #4 (a correction to the example in paragraph 18), the proposed
resolution is:</P>
<PRE>
  template&lt;class T1&gt; class A { 
    template&lt;class T2&gt; class B { 
      template&lt;class T3&gt; void mf1(T3); 
        void mf2(); 
      }; 
  }; 
  template&lt;&gt; template&lt;class X&gt; 
    class A&lt;int&gt;::B { }; 
  template&lt;&gt; template&lt;&gt; template&lt;class T&gt; 
    void A&lt;int&gt;::B&lt;double&gt;::mf1(T t) { }
  template&lt;class Y&gt; template&lt;&gt; 
    void A&lt;Y&gt;::B&lt;double&gt;::mf2() { } // ill-formed; B&lt;double&gt; is specialized but 
                                    // its enclosing class template A is not 
</PRE>

<P>The explicit specialization of member <TT>A&lt;int&gt;::B&lt;double&gt;::mf1</TT>
is ill-formed.  The class template <TT>A&lt;int&gt;::B</TT>
is explicitly specialized and
contains no members, so any implicit specialization (such as
<TT>A&lt;int&gt;::B&lt;double&gt;</TT>) would also contain no members.</P>

<P><B>Proposed Resolution (4/02):</B></P>

<P>
Fix the example in 14.7.3 [temp.expl.spec] paragraph 18 to read:</P>
<PRE>
  template&lt;class T1&gt; class A { 
    template&lt;class T2&gt; class B { 
      template&lt;class T3&gt; void mf1(T3);
      void mf2(); 
    }; 
  }; 
  template&lt;&gt; template&lt;class X&gt; 
    class A&lt;int&gt;::B {
      template&lt;class T&gt; void mf1(T);
    }; 
  template&lt;&gt; template&lt;&gt; template&lt;class T&gt; 
    void A&lt;int&gt;::B&lt;double&gt;::mf1(T t) { }
  template&lt;class Y&gt; template&lt;&gt; 
    void A&lt;Y&gt;::B&lt;double&gt;::mf2() { } // ill-formed; B&lt;double&gt; is specialized but 
                                    // its enclosing class template A is not 
</PRE>

<BR><BR><HR><A NAME="337"></A><H4>337.
  
Attempt to create array of abtract type should cause deduction to fail
</H4><B>Section: </B>14.8.2&#160; [temp.deduct]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>30 Jan 2002<BR>


<P>[Voted into WP at April 2003 meeting.]</P>

<P>In 14.8.2 [temp.deduct], attempting to create an array
of abstract class type should
be included in the list of things that cause type deduction to fail.</P>

<P><B>Proposed Resolution (4/02):</B></P>

<P> In 14.8.2 [temp.deduct] paragraph 2 amend the bullet item:</P>
<BLOCKQUOTE>
Attempting to create an array with an element type that is <TT>void</TT>,
a function type, or a reference type, or attempting to create an array
with a size that is zero or negative.
</BLOCKQUOTE>

<P> To the following:</P>
<BLOCKQUOTE>
Attempting to create an array with an element type that is <TT>void</TT>,
a function type, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN> a reference type, <SPAN style="font-weight:bold;background-color:#A0FFA0">or an abstract class
type,</SPAN> or
attempting to create an array with a size that is zero or negative.
</BLOCKQUOTE>

<BR><BR><HR><A NAME="368"></A><H4>368.
  
Uses of non-type parameters that should cause deduction to fail
</H4><B>Section: </B>14.8.2&#160; [temp.deduct]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Shirk
 &#160;&#160;&#160;

 <B>Date: </B>29 July 2002<BR>


<P>[Voted into WP at October 2003 meeting.]</P>

<P>I understand the rules in 14.8.2 [temp.deduct] paragraph 2
are meant to be an exhaustive list of what can cause type deduction to
fail.</P>

<P>Consider:</P>
<PRE>
  template&lt;typename U,U u&gt; struct wrap_t;

  template&lt;typename U&gt; static yes check( wrap_t&lt;U,U(0)&gt;* );

  struct X { X(int); };
  int main() {
    check&lt;X&gt;(0);
  }
</PRE>
<P>I can see 2 reasons this might cause type deduction to fail:</P>
<UL>
<LI>
Conversion is not a compile time constant.
</LI>
<LI>
Non-type parameter is a class type.
</LI>
</UL>
<P>Neither case is mentioned in 14.8.2 [temp.deduct] paragraph 2,
nor do I see a DR mentioning these.</P>

<P><B>Proposed resolution (October 2002):</B></P>

<P>Add after the fourth-to-last bullet of
14.8.2 [temp.deduct] paragraph 2:</P>
<BLOCKQUOTE>
<UL>
<LI>
Attempting to give an invalid type to a nontype template parameter.
[<I>Example:</I>
<PRE>
  template &lt;class T, T&gt; struct S {};
  template &lt;class T&gt; int f(S&lt;T, T()&gt;*);
  struct X {};
  int i0 = f&lt;X&gt;(0);
</PRE>
]
</LI>
</UL>
</BLOCKQUOTE>

<BR><BR><HR><A NAME="398"></A><H4>398.
  
Ambiguous wording on naming a type in deduction
</H4><B>Section: </B>14.8.2&#160; [temp.deduct]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>16 Jan 2003<BR>


<P>[Voted into WP at March 2004 meeting.]</P>



<P>The following example (simplified from a posting to
comp.lang.c++.moderated) is accepted by some
compilers (e.g., EDG), but not by other (e.g., g++).</P>
<PRE>
  struct S {
    static int const I = 42;
  };

  template&lt;int N&gt; struct X {};

  template&lt;typename T&gt; void f(X&lt;T::I&gt;*) {}

  template&lt;typename T&gt; void f(X&lt;T::J&gt;*) {}

  int main() {
    f&lt;S&gt;(0);
  }
</PRE>

<P>The wording in the standard that normally would
cover this (third sub-bullet in 14.8.2 [temp.deduct]
paragraph 2) says:
<BLOCKQUOTE>
    Attempting to use a type in the qualifier portion of a
    qualified name <B>that names a type</B> when that type does
    not contain the specified member, or if the specified
    member is not a type where a type is required.
</BLOCKQUOTE>
(emphasis mine).  If the phrase "that names a
type" applies to "a qualified name," then the example
is invalid.  If it applies to "the qualifier portion,"
then it is valid (because the second candidate is simply
discarded).</P>

<P>I suspect we want this example to work.  Either way,
I believe the sub-bullet deserves clarification.</P>

<P><B>Notes from April 2003 meeting:</B></P>

<P>We agreed that the example should be valid.  The phrase "that
names a type" applies to "the qualifier portion."</P>

<P><B>Proposed resolution (October 2003):</B></P>

<P>
In 14.8.2 [temp.deduct], paragraph 2, bullet 3,
sub-bullet 3, replace</P>

<BLOCKQUOTE>
Attempting to use a type in the qualifier portion of a qualified name
that names a type when that type does not contain the
specified member, or if the specified member is not a type
where a type is required.
</BLOCKQUOTE>

<P>
With</P>

<BLOCKQUOTE>
Attempting to use a type
in a <I>nested-name-specifier</I> of a <I>qualified-id</I>
when that type does not contain the specified member, or
<UL>
<LI>
the specified member is not a type where a type is required, or
</LI>
<LI>
the specified member is not a template where a template is required,
or
</LI>
<LI>
the specified member is not a nontype where a nontype is required.
</LI>
</UL>
<P>
[<I>Example:</I></P>
</BLOCKQUOTE>

<P>
Replace the example that follows the above text with</P>

<BLOCKQUOTE>
<PRE>
template &lt;int I&gt; struct X { };
template &lt;template &lt;class T&gt; class&gt; struct Z {};
template &lt;class T&gt; void f(typename T::Y*){}
template &lt;class T&gt; void g(X&lt;T::N&gt;*){}
template &lt;class T&gt; void h(Z&lt;T::template TT&gt;*){}
struct A {};
struct B { int Y; };
struct C {
	typedef int N;
};
struct D {
	typedef int TT;
};

int main()
{
	// Deduction fails in each of these cases:
	f&lt;A&gt;(0); // A does not contain a member Y
	f&lt;B&gt;(0); // The Y member of B is not a type
	g&lt;C&gt;(0); // The N member of C is not a nontype
	h&lt;D&gt;(0); // The TT member of D is not a template
}
</PRE>
]
</BLOCKQUOTE>

<BR><BR><HR><A NAME="486"></A><H4>486.
  
Invalid return types and template argument deduction
</H4><B>Section: </B>14.8.2&#160; [temp.deduct]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>16 Nov 2004<BR>


<P>[Voted into WP at April, 2006 meeting.]</P>

<P>According to 14.8.2 [temp.deduct] paragraph 2,</P>

<BLOCKQUOTE>

If a substitution in a template parameter or in the function type
of the function template results in an invalid type, type
deduction fails.

</BLOCKQUOTE>

<P>That would seem to apply to cases like the following:</P>

<PRE>
    template &lt;class T&gt; T f(T&amp;){}
    void f(const int*){}
    int main() {
      int a[5];
      f(a);
    }
</PRE>

<P>Here, the return type of <TT>f</TT> is deduced as
<TT>int[5]</TT>, which is invalid according to 8.3.5 [dcl.fct] paragraph 6.  The outcome of this example, then,
should presumably be that type deduction fails and overload
resolution selects the non-template function.  However, the list
of reasons in 14.8.2 [temp.deduct] for which type
deduction can fail does not include function and array types as a
function return type.  Those cases should be added to the
list.</P>

<P><B>Proposed resolution (October, 2005):</B></P>

<P>Change the last sub-bullet of 14.8.2 [temp.deduct]
paragraph 2 as indicated:</P>

<UL><LI><P>Attempting to create a function type in which a parameter
has a type of <TT>void</TT><SPAN style="font-weight:bold;background-color:#A0FFA0">, or in which the return type is a
function type or array type</SPAN>.</P></LI></UL>

<BR><BR><HR><A NAME="488"></A><H4>488.
  
Local types, overload resolution, and template argument deduction
</H4><B>Section: </B>14.8.2&#160; [temp.deduct]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mark Mitchell
 &#160;&#160;&#160;

 <B>Date: </B>24 Nov 2004<BR>


<P>[Voted into the WP at the June, 2008 meeting as paper N2657.]</P>

<P>It is not clear how to handle the following example:</P>

<PRE>
    struct S {
        template &lt;typename T&gt; S(const T&amp;);
    };
    void f(const S&amp;);
    void f(int);
    void g() {
        enum E { e };
        f(e);    //<SPAN style="font-family:Times;font-style:italic"> ill-formed?</SPAN>
    }
</PRE>

<P>Three possibilities suggest themselves:</P>

<OL>

<LI><P><B>Fail during overload resolution.</B> In order to
perform overload resolution for the call to <TT>f</TT>, the
declaration of the required specialization of the <TT>S</TT>
constructor must be instantiated.  This instantiation uses a
local type and is thus ill-formed (14.3.1 [temp.arg.type]
paragraph 2), rendering the example as a whole ill-formed, as
well.</P></LI>

<LI><P><B>Treat this as a type-deduction failure.</B> Although it
is not listed currently among the causes of type-deduction
failure in 14.8.2 [temp.deduct] paragraph 2, it could
plausibly be argued that instantiating a function declaration
with a local type as a template type-parameter falls under the
rubric of &#8220;If a substitution in a template parameter or in
the function type of the function template results in an invalid
type&#8221; and thus should be a type-deduction failure.  The
result would be that the example is well-formed because
<TT>f(const S&amp;)</TT> would be removed from the list of viable
functions.</P></LI>

<LI><P><B>Fail only if the function selected by overload
resolution requires instantiation with a local type.</B> This
approach would require that the diagnostic resulting from the
instantiation of the function type during overload resolution be
suppressed and either regenerated or regurgitated once overload
resolution is complete.  (The example would be well-formed under
this approach because <TT>f(int)</TT> would be selected as the
best match.)</P></LI>

</OL>

<P>(See also <A HREF="
     cwg_closed.html#489">issue 489</A>.)</P>

<P><B>Notes from the April, 2005 meeting:</B></P>

<P>The question in the original example was whether there should be
an error, even though the uninstantiable template was not needed for
calling the best-matching function.  The broader issue is whether a
user would prefer to get an error or to call a &#8220;worse&#8221;
non-template function in such cases.  For example:</P>

<PRE>
    template&lt;typename T&gt; void f(T);
    void f(int);
    void g() {
        enum E { e };
        f(e);    //<SPAN style="font-family:Times;font-style:italic"> call </SPAN>f(int)<SPAN style="font-family:Times;font-style:italic"> or get an error?</SPAN>
    }
</PRE>

<P>It was observed that the type deduction rules are intended to model,
albeit selectively, the other rules of the language.  This would argue
in favor of the second approach, a type-deduction failure, and the
consensus of the group was that the incremental benefit of other
approaches was not enough to outweigh the additional complexity of
specification and implementation.</P>

<P><B>Proposed resolution (October, 2005):</B></P>

<P>Add a new sub-bullet following bullet 3, sub-bullet 7 ("Attempting
to give an invalid type to a non-type template parameter") of
14.8.2 [temp.deduct] paragraph 2:</P>

<UL><LI><P>Attempting to use a local or unnamed type as the value of
a template type parameter.</P></LI></UL>

<P><B>Additional note (December, 2005):</B></P>

<P>The Evolution Working Group is currently considering an extension
that would effectively give linkage to some (but perhaps not all)
types that currently have no linkage.  If the proposed resolution above
is adopted and then later a change along the lines that the EWG is
considering were also adopted, the result would be a silent change
in the result of overload resolution, because the newly-acceptable
specializations would become part of the overload set.  It is not
clear whether that possibility is sufficient reason to delay adoption
of this resolution or not.  </P>

<P><B>Notes from the April, 2007 meeting:</B></P>

<P>The Evolution Working Group is now actively pursuing an
extension that would allow local and/or nameless types to be
used as template arguments, so this resolution will be held in
abeyance until the outcome of that proposal is known.</P>

<P><B>Notes from the June, 2008 meeting:</B></P>

<P>Paper N2657, adopted at the Sophia Antipolis (June, 2008) meeting,
removed the restriction against local and unnamed types as template
parameters.  The example is now well-formed.</P>

<BR><BR><HR><A NAME="352"></A><H4>352.
  
Nondeduced contexts
</H4><B>Section: </B>14.8.2.1&#160; [temp.deduct.call]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Andrei Iltchenko
 &#160;&#160;&#160;

 <B>Date: </B>24 April 2002<BR>


<P>[Voted into WP at March 2004 meeting.]</P>

<P>The current definition of the C++ language speaks about nondeduced
contexts only in terms of deducing template arguments from a type
14.8.2.5 [temp.deduct.type] paragraph 4. Those cases, however, don't
seem to be the only ones when template argument deduction is not
possible. The example below illustrates that:</P>
<PRE>
namespace  A  {
   enum  ae  {   };
   template&lt;class R, class A&gt;
   int  foo(ae, R(*)(A))
   {   return  1;   }
}

template&lt;typename T&gt;
void  tfoo(T)
{   }

template&lt;typename T&gt;
int  tfoo(T)
{   return  1;   }

/*int  tfoo(int)
{   return  1;   }*/


int  main()
{
   A::ae   a;
   foo(a, &amp;tfoo);
}
</PRE>
<P>Here argument-dependent name lookup finds the function template
'A::foo' as a candidate function. None of the function template's
function parameter types constitutes a nondeduced context as per
14.8.2.5 [temp.deduct.type] paragraph 4. And yet, quite clearly,
argument deduction is not possible in this context. Furthermore it is
not clear what a conforming implementation shall do when the
definition of the non-template function '::tfoo' is uncommented.</P>

<P><B>Suggested resolution:</B></P>

<P>Add the following as a new paragraph immediately before paragraph 3 of
14.8.2.1 [temp.deduct.call]:</P>
<BLOCKQUOTE>
<P>After the above transformations, in the event of P being a function
type, a pointer to function type, or a pointer to member function type
and the corresponding A designating a set of overloaded (member)
functions with at least one of the (member) functions introduced by
the use of a (member) function template name (13.4 [over.over])
or by the use of a
conversion function template (14.8.2.3 [temp.deduct.conv]),
the whole function call
expression is considered to be a nondeduced context. [Example:</P>
<PRE>
namespace  A  {
   enum  ae  {   };
   template&lt;class R, class A&gt;
   int  foo(ae, R(*)(A))
   {   return  1;   }
}

template&lt;typename T&gt;
void  tfoo(T)
{   }

template&lt;typename T&gt;
int  tfoo(T)
{   return  1;   }

int  tfoo(int)
{   return  1;   }

int  main()
{
   A::ae   a;
   foo(a, &amp;tfoo);   //  ill-formed, the call is a nondeduced context
   using  A::foo;
   foo&lt;void,int&gt;(a, &amp;tfoo);  // well-formed, the address of the spe-
                             // cialization 'void tfoo&lt;int&gt;(int)' is
                             // the second argument of the call
}
</PRE>
</BLOCKQUOTE>



<P><B>Notes from October 2002 meeting:</B></P>

<P>There was agreement that deduction should fail but it's still possible
to get a result -- it's just not a "nondeduced context" in the
sense of the standard.</P>

<P>The presence of a template in the overload set should not automatically
disqualify the overload set.</P>

<P><B>Proposed Resolution (April 2003, revised October 2003):</B></P>

<P>
In 14.8.2.5 [temp.deduct.type] paragraph 4 replace:
<BLOCKQUOTE>
The nondeduced contexts are:
<UL><LI>
The <I>nested-name-specifier</I> of a type that was specified using a
<I>qualified-id</I>.
</LI>
<LI>
A type that is a <I>template-id</I> in which one or more of the
<I>template-argument</I>s is an expression that references a
<I>template-parameter</I>.
</LI>
</UL>
</BLOCKQUOTE>

with:

<BLOCKQUOTE>
The nondeduced contexts are:
<UL><LI>
The <I>nested-name-specifier</I> of a type that was specified using a
<I>qualified-id</I>.
</LI>
<LI>
A non-type template argument or an array bound that is an expression
that references a template-parameter.
</LI>
<LI>
A template parameter used in the parameter type of a function parameter
that has a default argument that is being used in the call
for which argument deduction is being done.
</LI>
<LI>
A function parameter for which argument deduction cannot be done
because the associated function argument is a function, or a set of
overloaded functions (13.4 [over.over]), and one or
more of the following apply:
<UL>
<LI>
more than one function matches the function parameter type
(resulting in an ambiguous deduction), or
</LI>
<LI>
no function matches the function parameter type, or
</LI>
<LI>
the set of functions supplied as an argument contains one or more
function templates.
</LI>
</UL>
</LI>
</UL>
</BLOCKQUOTE>
</P>

<P>
In 14.8.2.1 [temp.deduct.call], add after paragraph 3:</P>

<BLOCKQUOTE>
<P>When P is a function type, pointer to function type, or pointer to
member function type:</P>

<UL>
<LI>
If the argument is an overload set containing one or more function templates,
the parameter is treated as a nondeduced context.
</LI>
<LI>
If the argument is an overload set (not containing function templates),
trial argument deduction is attempted using each of the members of the set.
If deduction succeeds for only one of the overload set members, that member
is used as the argument value for deduction.  If deduction succeeds for more
than one member of the overload set the parameter is treated as a nondeduced
context.
</LI>
</UL>

<P>
[Example:
<PRE>
// Only one function of an overload set matches the call so the function
// parameter is a deduced context.
template &lt;class T&gt; int f(T (*p)(T));
int g(int);
int g(char);
int i = f(g);  // calls f(int (*)(int))
</PRE>
--end example]</P>

<P>
[Example:
<PRE>
// Ambiguous deduction causes the second function parameter to be a
// nondeduced context.
template &lt;class T&gt; int f(T, T (*p)(T));
int g(int);
char g(char);
int i = f(1, g);  // calls f(int, int (*)(int))
</PRE>
--end example]</P>

<P>
[Example:
<PRE>
// The overload set contains a template, causing the second function
// parameter to be a nondeduced context.
template &lt;class T&gt; int f(T, T (*p)(T));
char g(char);
template &lt;class T&gt; T g(T);
int i = f(1, g);  // calls f(int, int (*)(int))
</PRE>
--end example]</P>


</BLOCKQUOTE>

<P>
In 14.8.2.5 [temp.deduct.type] paragraph 14, replace:

<BLOCKQUOTE>
If, in the declaration of a function template with a non-type
<I>template-parameter</I>, the non-type <I>template-parameter</I> is
used in an expression in the function parameter-list, the
corresponding <I>template-argument</I> must always be explicitly
specified or deduced elsewhere because type deduction would otherwise
always fail for such a <I>template-argument</I>.
</BLOCKQUOTE>

With:

<BLOCKQUOTE>
If, in the declaration of a function template with a non-type
template parameter, the non-type template parameter is
used in an expression in the function parameter list, the
expression is a nondeduced context.
</BLOCKQUOTE>
</P>

<P>
Replace the example with:</P>

<BLOCKQUOTE>
[Example:
<PRE>
template&lt;int i&gt; class A { /* ... */ };
template&lt;int i&gt; void g(A&lt;i+1&gt;);
template&lt;int i&gt; void f(A&lt;i&gt;, A&lt;i+1&gt;);
void k() {
  A&lt;1&gt; a1;
  A&lt;2&gt; a2;
  g(a1);  //error: deduction fails for expression i+1
  g&lt;0&gt;(a1); //OK
  f(a1, a2);  // OK
}
</PRE>
--end example]
</BLOCKQUOTE>


<P>
In 14.8.2.5 [temp.deduct.type] paragraph 16, replace:</P>

<BLOCKQUOTE>
A <I>template-argument</I> can be deduced from a pointer to function
or pointer to member function argument if the set of overloaded
functions does not contain function templates and at most
one of a set of overloaded functions provides a unique match.
</BLOCKQUOTE>

<P>
With:</P>

<BLOCKQUOTE>
A <I>template-argument</I> can be deduced from a function,
pointer to function, or pointer to member function type.
</BLOCKQUOTE>

<BR><BR><HR><A NAME="522"></A><H4>522.
  
Array-to-pointer decay in template argument deduction
</H4><B>Section: </B>14.8.2.1&#160; [temp.deduct.call]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>3 June 2005<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>

<P>Consider the following example:</P>

<PRE>
    char* cmdline3_[1] = {};

    template&lt;class charT&gt;
    void func(const charT* const argv[]) {}

    int main()
    {
        func(cmdline3_);
    }
</PRE>

<P>In terms of the process described in 14.8.2.1 [temp.deduct.call],
<TT>P</TT> is <TT>const charT* const *</TT> and <TT>A</TT> is
<TT>char*[1]</TT>.  According to the first bullet in paragraph 2,
the type used in deduction is not <TT>A</TT> but &#8220;the pointer
type produced by the array-to-pointer standard conversion.&#8221;</P>

<P>According to paragraph 4,</P>

<BLOCKQUOTE>

In general, the deduction process attempts to find template argument
values that will make the deduced <TT>A</TT> identical to <TT>A</TT>
(after the type <TT>A</TT> is transformed as described
above). However, there are three cases that allow a difference:

</BLOCKQUOTE>

<P>In this example, the deduced <TT>A</TT> is <I>not</I>
identical to the transformed <TT>A</TT>, because the deduced
<TT>A</TT> has additional cv-qualification, so the three exceptions
must be examined to see if they apply.  The only one that might
apply is the second bullet of paragraph 4:</P>

<BLOCKQUOTE>

<UL><LI><TT>A</TT> can be another pointer or pointer to member type
that can be converted to the deduced <TT>A</TT> via a qualification
conversion (4.4 [conv.qual]).</LI></UL>

</BLOCKQUOTE>

<P>However, <TT>A</TT> is not a pointer type but an array type;
this provision does not apply and deduction fails.</P>

<P>It has been argued that the phrase &#8220;after the type <TT>A</TT>
is transformed as described above&#8221; should be understood to
apply to the <TT>A</TT> in the three bullets of paragraph 4.  If
that is the intent, the wording should be changed to make that
explicit.</P>

<P><B>Proposed resolution (October, 2005):</B></P>

<P>Add the indicated words to 14.8.2.1 [temp.deduct.call]
paragraph 4:</P>

<BLOCKQUOTE>

<P>In general, the deduction process attempts to find template
argument values that will make the deduced <TT>A</TT> identical
to <TT>A</TT> (after the type <TT>A</TT> is transformed as described
above). However, there are three cases that allow a difference:</P>

<UL>

<LI><P>If the original <TT>P</TT> is a reference type, the
deduced <TT>A</TT> (i.e., the type referred to by the reference) can
be more cv-qualified than <SPAN style="font-weight:bold;background-color:#A0FFA0">the transformed</SPAN> <TT>A</TT>.</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">The transformed</SPAN> <TT>A</TT> can be another pointer or
pointer to member type that can be converted to the deduced <TT>A</TT>
via a qualification conversion (4.4 [conv.qual]).</P></LI>

<LI><P>If <TT>P</TT> is a class, and <TT>P</TT> has the
form <I>template-id</I>, then <SPAN style="font-weight:bold;background-color:#A0FFA0">the transformed</SPAN> <TT>A</TT> can be
a derived class of the deduced <TT>A</TT>. Likewise, if <TT>P</TT> is
a pointer to a class of the form <I>template-id</I>, <SPAN style="font-weight:bold;background-color:#A0FFA0">the
transformed</SPAN> <TT>A</TT> can be a pointer to a derived class pointed
to by the deduced <TT>A</TT>.</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="606"></A><H4>606.
  
Template argument deduction for rvalue references
</H4><B>Section: </B>14.8.2.1&#160; [temp.deduct.call]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Peter Dimov
 &#160;&#160;&#160;

 <B>Date: </B>1 December 2006<BR>


<P>[Voted into the WP at the September, 2008 meeting as part of
paper N2757.]</P>



<P>There are a couple of minor problems with the rvalue reference
wording in the WP.  The non-normative note in
14.8.2.1 [temp.deduct.call] paragraph 3 says,</P>

<BLOCKQUOTE>

[<I>Note:</I> The effect of this rule for lvalue arguments and
rvalue reference parameters is that deduction in such cases will
fail unless the function parameter is of the form <I>cv</I>
<TT>T&amp;&amp;</TT> (14.8.2.5 [temp.deduct.type]).
&#8212;<I>end note</I>]

</BLOCKQUOTE>

<P>It turns out that this isn't correct.  For example:</P>

<PRE>
    template &lt;class T&gt; void g(basic_string&lt;T&gt; &amp;&amp; );
    ...
    basic_string&lt;char&gt; s;
    g(s);    //<SPAN style="font-family:Times;font-style:italic"> Note says that it should fail, we want it to call</SPAN>
             //<SPAN style="font-family:Times;font-style:italic"> </SPAN>g&lt;char&gt;(basic_string&lt;char&gt;&amp;&amp;)
</PRE>

<P>Additionally, consider this case:</P>

<PRE>
    template &lt;class T&gt; void f(const T&amp;&amp;);
    ...
    int i;
    f(i);
</PRE>

<P>If we deduce <TT>T</TT> as <TT>int&amp;</TT> in this case then
<TT>f(i)</TT> calls <TT>f&lt;int&amp;&gt;(int&amp;)</TT>, which
seems counterintuitive.  We prefer that
<TT>f&lt;int&gt;(const int&amp;&amp;)</TT> be called.  Therefore,
we would like the wording clarified that the <TT>A&amp;</TT>
deduction rule in 14.8.2.1 [temp.deduct.call] paragraph 3
applies only to the form <TT>T&amp;&amp;</TT> and not to
<I>cv</I> <TT>T&amp;&amp;</TT> as the note currently implies.</P>

<P>These are minor tweaks to the rvalue reference wording and a
fallout from <A HREF="
     cwg_defects.html#540">issue 540</A>.  In particular,
the major applications of move semantics and perfect forwarding
are not impacted with respect to the original intentions of the
rvalue reference work by these suggestions.</P>

<P><U>Suggested resolution:</U></P>

<P>Change 14.8.2.1 [temp.deduct.call] paragraph 3 as
follows:</P>

<BLOCKQUOTE>

<P>If <TT>P</TT> is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">an rvalue reference type</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">of the form
<TT>T&amp;&amp;</TT>, where <TT>T</TT> is a template
parameter,</SPAN> and the argument is an lvalue, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the
type <TT>A&amp;</TT> is used in place of <TT>A</TT> for type
deduction</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>T</TT> is deduced
as <TT>A&amp;</TT></SPAN>. [<I>Example:</I></P>

<PRE>
    template &lt;typename T&gt; int f(T&amp;&amp;);
    int i;
    int j = f(i); //<SPAN style="font-family:Times;font-style:italic"> calls </SPAN>f&lt;int&amp;&gt;(i)
    <SPAN style="font-weight:bold;background-color:#A0FFA0">template &lt;typename T&gt; int g(const T&amp;&amp;);
    int k;
    int n = g(k); //<SPAN style="font-family:Times;font-style:italic"> calls </SPAN>g&lt;int&gt;(k)</SPAN>
</PRE>

<P>&#8212;<I>end example</I>]<SPAN style="text-decoration:line-through;background-color:#FFA0A0">[<I>Note:</I> The effect of this
rule for lvalue arguments and rvalue reference parameters is that
deduction in such cases will fail unless the function parameter
is of the form <I>cv</I> <TT>T&amp;&amp;</TT> (14.8.2.5 [temp.deduct.type]). &#8212;<I>end note</I>]</SPAN></P>

</BLOCKQUOTE>

<P><B>Proposed resolution (August, 2008):</B></P>

<P>Change 14.8.2.1 [temp.deduct.call] paragraph 3 as
follows:</P>

<BLOCKQUOTE>

<P>If <TT>P</TT> is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">an rvalue reference type</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">of the form
<TT>T&amp;&amp;</TT>, where <TT>T</TT> is a template
parameter,</SPAN> and the argument is an lvalue, the
type <TT>A&amp;</TT> is used in place of <TT>A</TT> for type
deduction. [<I>Example:</I></P>

<PRE>
    template &lt;typename T&gt; int f(T&amp;&amp;);
    int i;
    int j = f(i); //<SPAN style="font-family:Times;font-style:italic"> calls </SPAN>f&lt;int&amp;&gt;(i)
    <SPAN style="font-weight:bold;background-color:#A0FFA0">template &lt;typename T&gt; int g(const T&amp;&amp;);
    int k;
    int n = g(k); //<SPAN style="font-family:Times;font-style:italic"> calls </SPAN>g&lt;int&gt;(k)</SPAN>
</PRE>

<P>&#8212;<I>end example</I>]<SPAN style="text-decoration:line-through;background-color:#FFA0A0">[<I>Note:</I> The effect of this
rule for lvalue arguments and rvalue reference parameters is that
deduction in such cases will fail unless the function parameter
is of the form <I>cv</I> <TT>T&amp;&amp;</TT> (14.8.2.5 [temp.deduct.type]). &#8212;<I>end note</I>]</SPAN></P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="322"></A><H4>322.
  
Deduction of reference conversions
</H4><B>Section: </B>14.8.2.3&#160; [temp.deduct.conv]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>14 Nov 2001<BR>


<P>[Voted into WP at April 2003 meeting.]</P>



<P>Consider:
<PRE>
  struct S {
    template &lt;class T&gt; operator T&amp; ();
  };

  int main ()
  {
    S s;
    int i = static_cast&lt;int&amp;&gt; (s);
  }
</PRE>
14.8.2.3 [temp.deduct.conv] says that we strip the
reference from <TT>int&amp;</TT>, but doesn't say
anything about <TT>T&amp;</TT>.  As a result, <TT>P</TT> (<TT>T&amp;</TT>)
and <TT>A</TT> (<TT>int</TT>) have incompatible forms
and deduction fails.</P>

<P><B>Proposed Resolution (4/02):</B></P>

<P>Change the last chunk of 14.8.2.3 [temp.deduct.conv] paragraph 2 from
<BLOCKQUOTE>
     If <TT>A</TT> is a cv-qualified type, the top level cv-qualifiers
     of <TT>A</TT>'s type are ignored for type deduction.  If
     <TT>A</TT> is a reference type, the type referred to by
     <TT>A</TT> is used for type deduction.
</BLOCKQUOTE>
to
<BLOCKQUOTE>
     If <TT>A</TT> is a cv-qualified type, the top level cv-qualifiers
     of <TT>A</TT>'s type are ignored for type deduction.  If <TT>A</TT> is a
     reference type, the type referred to by <TT>A</TT> is used for
     type deduction.  If <TT>P</TT> is a reference type, the type
     referred to by <TT>P</TT> is used for type deduction.
</BLOCKQUOTE>
</P>

<BR><BR><HR><A NAME="349"></A><H4>349.
  
Template argument deduction for conversion functions and qualification conversions
</H4><B>Section: </B>14.8.2.3&#160; [temp.deduct.conv]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>16 April 2002<BR>


<P>[Voted into WP at October 2003 meeting.]</P>



<P>We ran into an issue concerning qualification conversions when doing
template argument deduction for conversion functions.</P>

<P>The question is: What is the type of T in the conversion functions
called by this example?  Is T "int" or "const int"?</P>

<P>If T is "int", the conversion function in class A works and the one in
class B fails (because the return expression cannot be converted to
the return type of the function).  If T is "const int", A fails and B
works.</P>

<P>Because the qualification conversion is performed on the result of the
conversion function, I see no benefit in deducing T as const int.</P>

<P>In addition, I think the code in class A is more likely to occur than
the code in class B.  If the author of the class was planning on returning
a pointer to a const entity, I would expect the function to have been
written with a const in the return type.</P>

<P>Consequently, I believe the correct result should be that T is int.</P>
<PRE>
struct A {
	template &lt;class T&gt; operator T***() {
		int*** p = 0;
		return p;
	}
};

struct B {
	template &lt;class T&gt; operator T***() {
		const int*** p = 0;
		return p;
	}
};

int main()
{
	A a;
	const int * const * const * p1 = a;
	B b;
	const int * const * const * p2 = b;
}
</PRE>
<P>We have just implemented this feature, and pending clarification by
the committee, we deduce T as int.  It appears that g++ and the Sun
compiler deduce T as const int.</P>

<P>One way or the other, I think the standard should be clarified to
specify how cases like this should be handled.</P>

<P><B>Notes from October 2002 meeting:</B></P>

<P>There was consensus on having the deduced type be "int" in the
above.</P>

<P><B>Proposed resolution (April 2003):</B></P>

<P>
Add to the end of 14.8.2.3 [temp.deduct.conv] (as a new paragraph
following paragraph 3):</P>
<BLOCKQUOTE>
<P>When the deduction process requires a qualification conversion for a
pointer or pointer to member type as described above, the following
process is used to determine the deduced template argument values:</P>

<P> If <TT>A</TT> is a type <I>cv</I><SUB>1,0</SUB> pointer to ... <I>cv</I>
<SUB>1,<I>n</I>-1</SUB>
pointer to <I>cv</I><SUB>1,<I>n</I></SUB> <I>T1</I></P>
<P> and <TT>P</TT> is a type <I>cv</I><SUB>2,0</SUB>
pointer to ... <I>cv</I><SUB>2,<I>n</I>-1</SUB>
pointer to <I>cv</I><SUB>2,<I>n</I></SUB> <I>T2</I></P>
<P> The cv-unqualified T1 and T2 are used as the types of
<TT>A</TT> and <TT>P</TT> respectively for type deduction.</P>

<P>
[<I>Example:</I>
<PRE>
struct A {
	template &lt;class T&gt; operator T***();
};

A a;
const int * const * const * p1 = a;  // T is deduced as int, not const int
</PRE>
-- <I>end example</I>]
</P>
</BLOCKQUOTE>

<BR><BR><HR><A NAME="70"></A><H4>70.
  
Is an array bound a nondeduced context?
</H4><B>Section: </B>14.8.2.5&#160; [temp.deduct.type]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jack Rouse
 &#160;&#160;&#160;

 <B>Date: </B>29 Sep 1998<BR>



<P>[Moved to DR at 4/01 meeting.]</P>

<P>Paragraph 4 lists contexts in which template formals are not deduced.
Were template formals in an expression in the array bound of an array type
specification intentionally left out of this list? Or was the intent
that such formals always be explicitly specified? Otherwise I believe the
following should be valid:</P>
<PRE>
    template &lt;int I&gt; class IntArr {};

    template &lt;int I, int J&gt;
    void concat( int (&amp;d)[I+J], const IntArr&lt;I&gt;&amp; a, const IntArr&lt;J&gt;&amp; b ) {}

    int testing()
    {
        IntArr&lt;2&gt; a;
        IntArr&lt;3&gt; b;
        int d[5];

        concat( d, a, b );
    }
</PRE>
Can anybody shed some light on this?

<P><U>From John Spicer:</U></P>

<P>Expressions involving nontype template parameters are nondeduced
contexts, even though they are omitted from the list in
14.8.2.5 [temp.deduct.type]
 paragraph 4. See
14.8.2.5 [temp.deduct.type]
 paragraphs
12-14:</P>

<OL START="12">
<LI>
A template type argument cannot be deduced from the type of a non-type
<I>template-argument</I>.
<P>&#160;...</P></LI></OL>
<OL START="14">
<LI>
If, in the declaration of a function template with
a non-type <I>template-parameter</I>, the non-type <I>template-parameter</I>
is used in an expression in the function parameter-list, the corresponding
<I>template-argument</I> must always be explicitly specified or deduced
elsewhere because type deduction would otherwise always
fail for such a <I>template-argument</I>.</LI>
</OL>

<P><B>Proposed resolution (04/01):</B> In
14.8.2.5 [temp.deduct.type]
 paragraph 4, add a
third bullet:</P>

<UL>
<LI>
An array bound that is an expression that references a
<I>template-parameter</I></LI>
</UL>
<BR><BR><HR><A NAME="300"></A><H4>300.
  
References to functions in template argument deduction
</H4><B>Section: </B>14.8.2.5&#160; [temp.deduct.type]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Andrei Iltchenko
 &#160;&#160;&#160;

 <B>Date: </B>11 Jul 2001<BR>


<P>[Moved to DR at October 2002 meeting.]</P>

<P>Paragraph 9 of 14.8.2.5 [temp.deduct.type] enumerates the
forms that the types P and A need to have in order for template
argument deduction to succeed.</P>

<P>For P denoting a pointer to function the paragraph lists the following
forms as allowing for template argument deduction:</P>
<PRE>
type(*)(T)
T(*)()
T(*)(T)
</PRE>

<P>On the other hand, no provision has been made to accommodate similar
cases for references to functions, which in light of the wording of
14.8.2.5 [temp.deduct.type] paragraph 11 means that the program below
is ill-formed (some of the C++ compilers do not reject it however):</P>

<PRE>
    template&lt;typename Arg, typename Result, typename T&gt;
    Result  foo_r(Result(&amp; rf)(Arg), T x)
    {   return  rf(Arg(x));   }

    template&lt;typename Arg, typename Result, typename T&gt;
    Result  foo_p(Result(* pf)(Arg), T x)
    {   return  pf(Arg(x));   }

    #include &lt;iostream&gt;
    int  show_arg(char c)
    {
       std::cout &lt;&lt; c &lt;&lt; ' ';
       if(std::cout)  return  0;
       return  -1;
    }

    int  main()
    {
                                                   // The deduction 
       int  (&amp; rf1)(int(&amp;)(char), double) = foo_r; // shall fail here
                                                   // While here
       int  (&amp; rf2)(int(*)(char), double) = foo_p; // it shall succeed
       return  rf2(show_arg, 2);
    }
</PRE>

<P><B>Proposed resolution (10/01, same as suggested resolution):</B></P>

<P>In the list of allowable forms for the types <TT>P</TT> and
<TT>A</TT> in paragraph 9 of
14.8.2.5 [temp.deduct.type] replace</P>
<PRE>
type(*)(T)
T(*)()
T(*)(T)
</PRE>
<P>by</P>
<PRE>
type(T)
T()
T(T)
</PRE>

<BR><BR><HR><A NAME="526"></A><H4>526.
  
Confusing aspects in the specification of non-deduced contexts
</H4><B>Section: </B>14.8.2.5&#160; [temp.deduct.type]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>25 July 2005<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>

<P>14.8.2.5 [temp.deduct.type] paragraph 5 reads:</P>

<BLOCKQUOTE>

<P>The non-deduced contexts are:</P>

<UL>

<LI><P>The <I>nested-name-specifier</I> of a type that was specified
using a <I>qualified-id</I>.</P></LI>

<LI><P>A non-type template argument or an array bound that is an
expression that references a template parameter.</P></LI>

<LI><P>A template parameter used in the parameter type of a function
parameter that has a default argument that is being used in the call
for which argument deduction is being done.</P></LI>

<LI><P>A function parameter for which argument deduction cannot be
done because the associated function argument is a function, or a set
of overloaded functions (13.4 [over.over]), and one or more
of the following apply:</P></LI>

<UL>

<LI><P>more than one function matches the function parameter type
(resulting in an ambiguous deduction), or</P></LI>

<LI><P>no function matches the function parameter type, or</P></LI>

<LI><P>the set of functions supplied as an argument contains one or
more function templates.</P></LI>

</UL>

<LI><P>An array bound that is an expression that references
a <I>template-parameter</I>.</P></LI>

</UL>

</BLOCKQUOTE>

<P>There are two problems with this list:</P>

<OL>

<LI><P>The last bullet is redundant with the second bullet.  This
appears to have been the result of applying the resolutions of issues
<A HREF="
     cwg_defects.html#70">70</A> and <A HREF="
     cwg_defects.html#352">352</A>
independently instead of in coordination.</P></LI>

<LI><P>The second bullet
appears to be contradicted by the statement in paragraph 8 saying that
an argument can be deduced if <TT>P</TT> and <TT>A</TT> have the
forms <I>type</I><TT>[i]</TT> and
<I>template-name</I><TT>&lt;i&gt;</TT>.</P>

<P>The intent of the wording in bullet 2 appears to have been that
deduction cannot be done if the template parameter is a sub-expression
of the template argument or array bound expression and that it can be
done if it is the complete expression, but the current wording does
not say that very clearly.  (Similar wording also appears in
14.6.2.1 [temp.dep.type] paragraph 3 and 14.8.2.5 [temp.deduct.type] paragraph 14.)</P>
</LI>

</OL>

<P><B>Proposed resolution (October, 2005):</B></P>

<OL><LI><P>Change 14.8.2.5 [temp.deduct.type] paragraph 5 as
indicated:</P></LI>

<BLOCKQUOTE>

<P>The non-deduced contexts are:</P>

<UL>
<LI><P>The <I>nested-name-specifier</I> of a type that was specified
using a <I>qualified-id</I>.</P></LI>

<LI><P>A non-type template argument or an array bound <SPAN style="text-decoration:line-through;background-color:#FFA0A0">that is an
expression that</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">in either of which a subexpression</SPAN>
references a template parameter.</P></LI>

<LI><P>A template parameter used in the parameter type of a function
parameter that has a default argument that is being used in the call
for which argument deduction is being done.</P></LI>

<LI><P>A function parameter for which argument deduction cannot be done
because the associated function argument is a function, or a set of
overloaded functions (13.4 [over.over]), and one or more of
the following apply:</P></LI>

<UL>
<LI><P>more than one function matches the function parameter type
(resulting in an ambiguous deduction), or</P></LI>

<LI><P>no function matches the function parameter type, or</P></LI>

<LI><P>the set of functions supplied as an argument contains one or more function templates.</P></LI>
</UL>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><LI><P>An array bound that is an expression that references a
<I>template-parameter</I>.</P></LI></SPAN>
</UL>

</BLOCKQUOTE>

<LI><P>Change 14.8.2.5 [temp.deduct.type] paragraph 14 as
indicated:</P></LI>

<BLOCKQUOTE>

If, in the declaration of a function template with a non-type template
parameter, the non-type template parameter is used in <SPAN style="text-decoration:line-through;background-color:#FFA0A0">an
expression</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">a subexpression</SPAN> in the function parameter list,
the expression is a non-deduced context <SPAN style="font-weight:bold;background-color:#A0FFA0">as specified above</SPAN>...

</BLOCKQUOTE>

<LI><P>Change 14.6.2.1 [temp.dep.type] paragraph 3 as
indicated:</P></LI>

<BLOCKQUOTE>

A template argument that is equivalent to a template parameter (i.e.,
has the same constant value or the same type as the template
parameter) can be used in place of that template parameter in a
reference to the current instantiation. In the case of a non-type
template argument, the argument must have been given the value of the
template parameter and not an expression <SPAN style="text-decoration:line-through;background-color:#FFA0A0">involving</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">that
contains</SPAN> the template parameter <SPAN style="font-weight:bold;background-color:#A0FFA0">as a subexpression</SPAN>...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="415"></A><H4>415.
  
Template deduction does not cause instantiation
</H4><B>Section: </B>14.8.3&#160; [temp.over]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>4 May 2003<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>



<P><U>Mike Miller:</U>
In fact, now that I've looked more closely, that appears not to be the
case.  (At least, it's not the error I get when I compile his example.)
Here's a minimal extract (without the inflammatory using-directive :-)
that illustrates what I think is going on:</P>
<PRE>
  template &lt;typename _Iterator&gt;
  struct iterator_traits {
    typedef typename _Iterator::difference_type difference_type;
  };

  template &lt;typename _InputIterator&gt;
  inline typename iterator_traits&lt;_InputIterator&gt;::difference_type
  distance(_InputIterator, _InputIterator);

  double distance(const int&amp;, const int&amp;);

  void f() {
    int i = 0;
    int j = 0;
    double d = distance(i, j);
  }
</PRE>
<P>What happens is that <TT>iterator_traits&lt;int&gt;</TT>
is instantiated as part of
type deduction for the function template <TT>distance</TT>,
 and the instantiation
fails.  (Note that it can't be instantiation of <TT>distance&lt;int&gt;</TT>,
as I had originally posited, because in this case only a declaration, not a
definition, of that template is in scope.)</P>

<P><U>John Spicer:</U> Yes, I believe that is what is going on.</P>

<P><U>Mike Miller:</U> 
I seem to recall that there was some discussion of questions related
to this during the core meetings in Oxford.  I think Steve Adamczyk
said something to the effect that it's infeasible to suppress all
instantiation errors during template type deduction and simply call
any such errors a deduction failure.  (I could be misremembering, and
I could be misapplying that comment to this situation.)</P>

<P><U>John Spicer</U>:
Regardless of other conditions in which this may apply, I don't think
it would be reasonable for compilers to have to do "speculative
instantiations" during template argument deduction.  One class
instantiation could kick off a series of other instantiations, etc.</P>

<P><U>Mike Miller:</U>
I don't see anything in the Standard that tells me whether it's
legitimate or not to report an error in this case.  I hope John or
another template expert can enlighten me on that.</P>

<P><U>John Spicer:</U>
My opinion is that, because this case is not among those enumerated
that cause deduction failure (rather than being ill-formed) that
reporting an error is the right thing to do.</P>

<P><U>Mike Miller:</U>
I am still interested, though, in the question of why
14.8.3 [temp.over] says that
viable function template specializations are instantiated, even if they
are not selected by overload resolution.</P>

<P><U>John Spicer:</U>
I believe the wording in
14.8.3 [temp.over] is incorrect.  I researched this and
found that a change was made during the clause 14 restructuring that
was incorporated in March of 1996.  The prior wording was "the deduced
template arguments are used to generate a single template function".
This was changed to "deduced template arguments are used to
instantiate a single function template specialization".  I believe
this resulted from what was basically a global replace of "generate"
with "instantiate" and of "template function" with "function template
specialization".  In this case, the substitution changed the meaning.
This paragraph needs reworking.</P>

<P><B>Proposed resolution (April, 2006):</B></P>

<P>Change 14.8.3 [temp.over] paragraph 1 as indicated:</P>

<BLOCKQUOTE>

...For each function template, if the argument deduction and checking
succeeds, the <I>template-argument</I>s (deduced and/or explicit) are used to
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">instantiate</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">synthesize the declaration of</SPAN> a single
function template specialization which is added to the candidate
functions set to be used in overload resolution. If, for a given
function template, argument deduction fails, no such function is added
to the set of candidate functions for that template. The complete set
of candidate functions includes all the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">function templates
instantiated in this way</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">synthesized declarations</SPAN> and all
of the non-template overloaded functions of the same name. The
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">function template specializations</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">synthesized
declarations</SPAN> are treated like any other functions in the remainder
of overload resolution, except as explicitly noted in 13.3.3 [over.match.best].

</BLOCKQUOTE>

<BR><BR><HR><A NAME="208"></A><H4>208.
  
Rethrowing exceptions in nested handlers
</H4><B>Section: </B>15.1&#160; [except.throw]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Bill Wade
 &#160;&#160;&#160;

 <B>Date: </B>28 Feb 2000<BR>



<P>[Moved to DR at 4/01 meeting.]</P>

<P>Paragraph 7 of 15.1 [except.throw] discusses which exception
is thrown by a <I>throw-expression</I> with no operand.</P>

<P>May an expression which has been "finished" (paragraph 7) by an
inner catch block be rethrown by an outer catch block?</P>

<PRE>
    catch(...)    // Catch the original exception
    {
      try{ throw; }    // rethrow it at an inner level
                       // (in reality this is probably
                       // inside a function)
      catch (...)
      {
      }   // Here, an exception (the original object)
          // is "finished" according to 15.1p7 wording

      // 15.1p7 says that only an unfinished exception
      // may be rethrown.
      throw;    // Can we throw it again anyway?  It is
                // certainly still alive (15.1p4).
    }
</PRE>

<P>I believe this is ok, since the paragraph says that the exception
is finished when the "corresponding" catch clause exits.  However
since we have two clauses, and only one exception, it would seem that
the one exception gets "finished" twice.</P>

<P><B>Proposed resolution (04/01):</B></P>

<OL>
<LI><P>In 15.1 [except.throw] paragraph 4, change

<BLOCKQUOTE>

When the last handler being executed for the exception exits by any
means other than <TT>throw;</TT> ...

</BLOCKQUOTE>

to

<BLOCKQUOTE>

When the last remaining active handler for the exception exits by any
means other than <TT>throw;</TT> ...

</BLOCKQUOTE>
</P></LI>

<LI><P>In 15.1 [except.throw] paragraph 6, change

<BLOCKQUOTE>

A <I>throw-expression</I> with no operand rethrows the exception being
handled.

</BLOCKQUOTE>

to

<BLOCKQUOTE>

A <I>throw-expression</I> with no operand rethrows the currently
handled exception (15.3 [except.handle]).

</BLOCKQUOTE>
</P></LI>

<LI><P>Delete 15.1 [except.throw] paragraph 7.</P></LI>

<LI><P>Add the following before 15.1 [except.throw] paragraph
6:

<BLOCKQUOTE>

An exception is considered caught when a handler for that exception
becomes active (15.3 [except.handle]).  [<I>Note:</I> an
exception can have active handlers and still be considered uncaught if
it is rethrown.]

</BLOCKQUOTE>
</P></LI>

<LI><P>Change 15.3 [except.handle] paragraph 8 from

<BLOCKQUOTE>

An exception is considered handled upon entry to a handler.
[<I>Note:</I> the stack will have been unwound at that point.]

</BLOCKQUOTE>

to

<BLOCKQUOTE>

<P>A handler is considered active when initialization is complete for
the formal parameter (if any) of the catch clause.  [<I>Note:</I> the
stack will have been unwound at that point.]  Also, an implicit
handler is considered active when <TT>std::terminate()</TT> or
<TT>std::unexpected()</TT> is entered due to a throw.  A handler is no
longer considered active when the catch clause exits or when
<TT>std::unexpected()</TT> exits after being entered due to a throw.</P>

<P>The exception with the most recently activated handler that is
still active is called the <I>currently handled exception</I>.</P>

</BLOCKQUOTE>
</P></LI>

<LI><P>In 15.3 [except.handle] paragraph 16, change "exception
being handled" to "currently handled exception."
</P></LI>
</OL>

<BR><BR><HR><A NAME="428"></A><H4>428.
  
Mention of expression with reference type
</H4><B>Section: </B>15.1&#160; [except.throw]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>14 July 2003<BR>


<P>[Voted into WP at March 2004 meeting.]</P>

<P>15.1 [except.throw] paragraph 3 says that the type of a throw
expression shall not be
a pointer or reference to an incomplete type.  But an expression never
has reference type.</P>

<P><B>Proposed Resolution (October 2003):</B></P>

<P>Change the penultimate sentence of 15.1 [except.throw]
 paragraph 3 as follows:</P>
<BLOCKQUOTE>
The type of the <I>throw-expression</I> shall not be an
incomplete type, or a pointer <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or reference</SPAN>
to an incomplete type <SPAN style="font-weight:bold;background-color:#A0FFA0">other than (possibly cv-qualified)
<TT>void</TT></SPAN><SPAN style="text-decoration:line-through;background-color:#FFA0A0">, other than <TT>void*</TT>,
<TT>const void*</TT>, <TT>volatile void*</TT>, or
<TT>const volatile void*</TT></SPAN>.
</BLOCKQUOTE>

<BR><BR><HR><A NAME="479"></A><H4>479.
  
Copy elision in exception handling
</H4><B>Section: </B>15.1&#160; [except.throw]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>07 Oct 2004<BR>


<P>[Voted into WP at April, 2006 meeting.]</P>



<P>I have noticed a couple of confusing and overlapping passages
dealing with copy elision.  The first is 15.1 [except.throw] paragraph 5:</P>

<BLOCKQUOTE>

If the use of the temporary object can be eliminated without
changing the meaning of the program except for the execution of
constructors and destructors associated with the use of the
temporary object (12.2 [class.temporary]), then the exception
in the handler can be initialized directly with the argument of
the throw expression.

</BLOCKQUOTE>

<P>The other is 15.3 [except.handle] paragraph 17:</P>

<BLOCKQUOTE>

If the use of a temporary object can be eliminated without
changing the meaning of the program except for execution of
constructors and destructors associated with the use of the
temporary object, then the optional name can be bound directly to
the temporary object specified in a <I>throw-expression</I>
causing the handler to be executed.

</BLOCKQUOTE>

<P>I <I>think</I> these two passages are intended to describe the
same optimization.  However, as is often the case where something
is described twice, there are significant differences.  One is
just different terminology &#8212; is &#8220;the exception in the
handler&#8221; the same as &#8220;the object declared in the
<I>exception-declaration</I> or, if the
<I>exception-declaration</I> does not specify a name, a temporary
object of that type&#8221; (15.3 [except.handle] paragraph
16)?</P>

<P>More significant, there is a difference in which kinds of
<I>throw-expression</I>s are eligible for the optimization.  In
15.1 [except.throw] paragraph 5, it appears that any
object is a candidate, while in 15.3 [except.handle]
paragraph 17 the thrown object must be
a temporary (&#8220;the temporary object specified in a
<I>throw-expression</I>&#8221;).  For example, it's not clear
looking at these two passages whether the copy of a local
automatic can be elided.  I.e., by analogy with the return value
optimization described in 12.8 [class.copy] paragraph
15:</P>

<PRE>
    X x;
    return x;    // copy may be elided

    X x;
    throw x;     // unclear whether copy may be elided
</PRE>

<P>Which brings up another point: 12.8 [class.copy]
paragraph 15 purports to be an exhaustive list in which copy
elision is permitted even if the constructor and/or destructor
have side effects; however, these two passages describe another
case that is not mentioned in 12.8 [class.copy]
paragraph 15.</P>

<P>A final point of confusion: in the unoptimized abstract
machine, there are actually <I>two</I> copies in throwing and
handling an exception: the copy from the object being thrown to
the exception object, and the copy from the exception object to
the object or temporary in the <I>exception-declaration</I>.
15.1 [except.throw] paragraph 5 speaks only of eliminating
the exception object, copying the thrown object directly into the
<I>exception-declaration</I> object, while 15.3 [except.handle] paragraph 17 refers to directly binding the
<I>exception-declaration</I> object to the thrown object (if it's
a temporary).  Shouldn't these be separated, with a throw of an
automatic object or temporary being like the return value
optimization and the initialization of the object/temporary in
the <I>exception-declaration</I> being a separate optimizable
step (which could, presumably, be combined to effectively alias
the <I>exception-declaration</I> onto the thrown object)?</P>

<P>(See paper J16/04-0165 = WG21 N1725.)</P>

<P><B>Proposed resolution (April, 2005):</B></P>

<OL><LI><P>Add two items to the bulleted list in 12.8 [class.copy]
paragraph 15 as follows: </P>

<BLOCKQUOTE>

<P>This elision of copy operations is permitted in the following
circumstances (which may be combined to eliminate multiple copies):</P>

<UL>

<LI><P>in a <TT>return</TT> statement in a function with a class return type,
when the expression is the name of a non-volatile automatic object
with the same cv-unqualified type as the function return type, the
copy operation can be omitted by constructing the automatic object
directly into the function's return value</P></LI>

<SPAN style="font-weight:bold;background-color:#A0FFA0"><LI><P>in a <I>throw-expression</I>, when the operand is the name
of a non-volatile automatic object, the copy operation from the
operand to the exception object (15.1 [except.throw]) can be
omitted by constructing the automatic object directly into the
exception object</P></LI></SPAN>

<LI><P>when a temporary class object that has not been bound to a
reference (12.2 [class.temporary]) would be copied to a class
object with the same cv-unqualified type, the copy operation can be
omitted by constructing the temporary object directly into the target
of the omitted copy</P></LI>

<SPAN style="font-weight:bold;background-color:#A0FFA0"><LI><P>when the <I>exception-declaration</I> of an exception
handler (clause 15 [except]) declares an object of the
same type (except for cv-qualification) as the exception object
(15.1 [except.throw]), the copy operation can be omitted by
treating the <I>exception-declaration</I> as an alias for the
exception object if the meaning of the program will be unchanged
except for the execution of constructors and destructors for the
object declared by the <I>exception-declaration</I></P></LI></SPAN>

</UL>

</BLOCKQUOTE>

</LI>

<LI><P>Change 15.1 [except.throw] paragraph 5 as follows:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">If the use of the temporary object can be eliminated without
changing the meaning of the program except for the execution of
constructors and destructors associated with the use of the temporary
object (12.2 [class.temporary]), then the exception in the handler
can be initialized directly with the argument of the throw
expression.</SPAN> When the thrown object is a class object, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">and</SPAN>
the copy constructor <SPAN style="text-decoration:line-through;background-color:#FFA0A0">used to initialize the temporary copy is not</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">and the destructor shall be</SPAN> accessible, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the program is
ill-formed (even when the temporary object could otherwise be
eliminated)</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">even if the copy operation is elided (12.8 [class.copy])</SPAN>. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">Similarly, if the destructor for that object is
not accessible, the program is ill-formed (even when the temporary
object could otherwise be eliminated).</SPAN>

</BLOCKQUOTE>

</LI>

<LI><P>Change 15.3 [except.handle] paragraph 17 as follows:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">If the use of a temporary object can be eliminated without changing
the meaning of the program except for execution of constructors and
destructors associated with the use of the temporary object, then the
optional name can be bound directly to the temporary object specified
in a <I>throw-expression</I> causing the handler to be executed.</SPAN>  The
copy constructor and destructor associated with the object shall be
accessible even <SPAN style="text-decoration:line-through;background-color:#FFA0A0">when the temporary object is eliminated</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">if the copy operation is elided (12.8 [class.copy])</SPAN>.

</BLOCKQUOTE>

</LI>

</OL>

<BR><BR><HR><A NAME="592"></A><H4>592.
  
Exceptions during construction of local static objects
</H4><B>Section: </B>15.2&#160; [except.ctor]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>30 August 2006<BR>


<P>[Voted into the WP at the September, 2008 meeting (resolution
in paper N2757).]</P>

<P>According to 15.2 [except.ctor] paragraph 2,</P>

<BLOCKQUOTE>

An object that is partially constructed or partially destroyed
will have destructors executed for all of its fully constructed
subobjects, that is, for subobjects for which the principal
constructor (12.6.2 [class.base.init]) has completed
execution and the destructor has not yet begun
execution. Similarly, if the non-delegating constructor for an
object has completed execution and a delegating constructor for
that object exits with an exception, the object's destructor will
be invoked. Should a constructor for an element of an automatic
array throw an exception, only the constructed elements of that
array will be destroyed.

</BLOCKQUOTE>

<P>The requirement for destruction of array elements explicitly
applies only to automatic arrays, and one might conclude from the
context that only automatic class objects are in view as well,
although that is not explicitly stated.  What about local static
arrays and class objects?  Are they intended also to be subject
to the requirement that fully-constructed subobjects are to be
destroyed?</P>

<P><B>Proposed resolution (October, 2006):</B></P>

<P>Change 15.2 [except.ctor] paragraph 2 as follows:</P>

<BLOCKQUOTE>

An object that is partially constructed or partially destroyed will
have destructors executed for all of its fully constructed subobjects,
that is, for subobjects for which the principal constructor
(12.6.2 [class.base.init]) has completed execution and the
destructor has not yet begun execution. Similarly, if the
non-delegating constructor for an object has completed execution and a
delegating constructor for that object exits with an exception, the
object's destructor will be invoked. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">Should a constructor for an
element of an automatic array throw an exception, only the constructed
elements of that array will be destroyed.</SPAN> If the object or array was
allocated in a <I>new-expression</I>, the matching deallocation
function (3.7.4.2 [basic.stc.dynamic.deallocation], 5.3.4 [expr.new], 12.5 [class.free]), if any, is called to
free the storage occupied by the object.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="87"></A><H4>87.
  
Exception specifications on function parameters
</H4><B>Section: </B>15.4&#160; [except.spec]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>25 Jan 1999<BR>



<P>[Moved to DR at 4/01 meeting.]</P>

<P>In
15.4 [except.spec]

paragraph 2:</P>
<BLOCKQUOTE>An exception-specification shall appear only on a function
declarator in a function, pointer, reference or pointer to member declaration
or definition.</BLOCKQUOTE>
Does that mean in the top-level function declarator, or one at any level?
Can one, for example, specify an exception specification on a pointer-to-function
parameter of a function?
<PRE>
    void f(int (*pf)(float) throw(A))
</PRE>
Suggested answer: no. The exception specifications are valid only on the
top-level function declarators.
    
<P>However, if exception specifications are made part of a function's type
as has been tentatively agreed, they would have to be allowed on any function
declaration. </P>

<P>There is already an example
of an exception specification for a parameter in the example in
15.4 [except.spec]
 paragraph 1.</P>

<P><B>Proposed resolution (04/01):</B>

Change text in 15.4 [except.spec] paragraph 1 from:</P>

<BLOCKQUOTE>An <I>exception-specification</I> shall appear only on
a function declarator in a function, pointer, reference or pointer to member
declaration or definition.</BLOCKQUOTE>
to:
<BLOCKQUOTE>

An <I>exception-specification</I> shall appear only on a function
declarator for a function type, pointer to function type, reference to
function type, or pointer to member function type that is the
top-level type of a declaration or definition, or on such a type
appearing as a parameter or return type in a function declarator.

</BLOCKQUOTE>
<P>(See also issues <A HREF="
     cwg_defects.html#25">25</A>,
<A HREF="
     cwg_active.html#92">92</A>, and
<A HREF="
     cwg_closed.html#133">133</A>.)</P>
<BR><BR><HR><A NAME="394"></A><H4>394.
  
<I>identifier-list</I> is never defined
</H4><B>Section: </B>16&#160; [cpp]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Nicola Musatti
 &#160;&#160;&#160;

 <B>Date: </B>16 Dec 2002<BR>


<P>[Voted into WP at October 2004 meeting.]</P>

<P>In clause 16 [cpp], paragraph 1, the
<I>control-line</I> non-terminal symbol
is defined in terms of the <I>identifier-list</I> non-terminal, which is
never defined within the standard document.</P>

<P>The same definition is repeated in clause A.14 [gram.cpp].</P>

<P>I suggest that the following definition is added to clause
16 [cpp], paragraph 1, after the one for
<I>replacement-list</I>:</P>
<UL>
<I>identifier-list</I>:
<UL><I>identifier</I>
<BR><I>identifier-list</I> , <I>identifier</I>
</UL>
</UL>

<P>This should be repeated again in clause A.14 [gram.cpp],
again after the one for <I>replacement-list</I>. It might also be
desirable to include a third repetition in clause 16.3 [cpp.replace],
paragraph 9.</P>

<P><B>Proposed Resolution (Clark Nelson, Dec 2003):</B></P>

<P>In clause 16 [cpp], paragraph 1, immediately
before the definition of <I>replacement-list</I>, add:</P>
<UL>
<I>identifier-list</I>:
<UL><I>identifier</I>
<BR><I>identifier-list</I> , <I>identifier</I>
</UL>
</UL>

<P>If the correct TROFF macros are used, the definition will appear
automatically in appendix A. It doesn't need to be repeated in 16.3p9.</P>

<P>With respect to the question of having the preprocessor description be
synchronized with C99, this would fall into the category of a justified
difference. (Other justified differences include those for Boolean
expressions, alternative tokens, and terminology differences.)</P>

<BR><BR><HR><A NAME="370"></A><H4>370.
  
Can <TT>#include &lt;...&gt;</TT> form be used other than for standard C++ headers?
</H4><B>Section: </B>16.2&#160; [cpp.include]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Beman Dawes
 &#160;&#160;&#160;

 <B>Date: </B>01 August 2002<BR>


<P>[Voted into WP at the October, 2006 meeting.]</P>

<P>The motivation for this issue is a desire to write portable programs which 
will work with any conforming implementation.</P>
<P>The C++ Standard (16.2 [cpp.include]) provides two forms of
<TT>#include</TT> directives, with the &lt;...&gt; form being described
(16.2 [cpp.include] paragraph 2) as "for a header", and
the "..." form (16.2 [cpp.include] paragraph 3) as
for "the source file" identified between the delimiters. When the 
standard uses the term "header", it often appears to be limiting
the term to apply to the Standard Library headers only. Users of the
standard almost always use the term "header" more broadly, to
cover all <TT>#include</TT>d source files, but 
particularly those containing interface declarations.</P>

<P>Headers, including source files, can be categorized according to
their origin and usage:</P>
<OL>
  <LI>C++ Standard Library headers (which aren't necessarily files).</LI>
  <LI>Other standard libraries such as the POSIX headers.</LI>
  <LI>Operating system API's such as <I>windows.h</I>.</LI>
  <LI>Third party libraries, such as Boost, ACE, or commercial offerings.</LI>
  <LI>Organization-wide "standard" header files, such as a company's <I>
  config.hpp</I>.</LI>
  <LI>A project's "public" header files, often shared by all
      developers working on the same project.</LI>
  <LI>A project or user's "private", "local", or
      "detail" headers, in the same directory or sub-directory
      as the compilation unit.</LI>
</OL>
<P>Existing practice varies widely, but it is fairly easy to find users 
advocating:</P>
<UL>
  <LI>For (1), Standard Library headers, use &lt;...&gt;. All others
      use "...".</LI>
  <LI>For (7),  use "...". All others use &lt;...&gt;.</LI>
  <LI>Draw a line somewhere below (1) and above (7), and use
      &lt;...&gt; above the line and "..." below.
      The exact location of the line may be based on a perception of
      how often the header involved changes; some "make" utilities
      use this to optimize builds.</LI>
</UL>
<P>Do any of the practices A, B, or C result in programs which can be rejected 
by a conforming implementation?</P>

<P>The first defect is that readers of the standard have not been
able to reach consensus on the answers to the above question.</P>

<P>A second possible defect is that if A, B, or C can be rejected by a 
conforming implementation, then the standard should be changed because would 
mean there is a wide variance between the standard and existing practice.</P>

<P><U>Matt Austern</U>:
I really only see two positions:</P>
<OL>
<LI>Implementations have some unspecified mechanism (copying
files to a magic directory, adding a magic flag,...) such that the
line <TT>#include &lt;foo&gt;</TT> results in textual inclusion of
the file foo.</LI>
<LI>Implementations are not required to have any mechanism for
getting <TT>#include &lt;foo&gt;</TT> to perform textual inclusion of an 
arbitrary file <TT>foo</TT>.  That form is reserved for standard
library headers only.</LI>
</OL>
<P>I agree that the standard should clarify which of those two is the
case (I imagine it'll hinge on finding one crucual sentence that
either says "implementation defined" or "unspecified"), but from
the standpoint of portability I don't see much difference between
the two.  I claim that, with either of those two interpretations, using
<TT>#include &lt;foo&gt;</TT> is already nonportable.</P>

<P>(Of course, I claim that almost anything having to do with headers,
including the <TT>#include "foo"</TT> form, is also nonportable.  In practice
there's wide variation in how compilers handle paths, especially
relative paths.)</P>

<P><U>Beman Dawes</U>:
The whole issue can be resolved by replacing "header" with "header or 
source file" in 16.2 [cpp.include] paragraph 2.
That will bring the standard into 
alignment with existing practice by both users and implementations.  
The "header and/or source file" wording is used at least three other 
places in the standard where otherwise there might be some confusion.</P>

<P><U>John Skaller</U>:
In light of Andrew Koenig's comments, this doesn't appear to be the case,
since the mapping of include names to file names is implementation defined,
and therefore source file inclusion cannot be made portable
within the ISO C/C++ standards (since that provision obviously cannot be
removed).</P>

<P>A possible idea is to create a binding standard, outside the
C/C++ ISO Standards, which specifies not only the path lookup
mechanism but also the translation from include names to file
names. Clearly that is OS dependent, encoding dependent, etc,
but there is no reason not to have a binding standard for Unix,
Windows, etc, and specify these bindings in such a way that
copying directories from one OS to the other can result in
programs working on both OS's.</P>

<P><U>Andy Koenig</U>:
An easier solution might be to specify a (presumably unbounded, or
bounded only by implementation capacity) collection of header-file
names that every implementation must make it possible for programs
to access somehow, without specifying exactly how.</P>

<P><B>Notes from October 2002 meeting:</B></P>

<P>This was discussed at some length.  While there was widespread
agreement that such inclusion is inherently implementation-dependent,
we agreed to try to add wording that would make it clear that
implementations are permitted (but not required) to allow inclusion
of files using the &lt;...&gt; form of <TT>#include</TT>.</P>

<P><B>Proposed resolution (April, 2005):</B></P>

<P>Change 16.2 [cpp.include] paragraph 7 from:</P>

<BLOCKQUOTE>

[<I>Example:</I> The most common uses of <TT>#include</TT> preprocessing
directives are as in the following:

<PRE>
    #include &lt;stdio.h&gt;
    #include "myprog.h"
</PRE>

&#8212;<I>end example</I>] 

</BLOCKQUOTE>

<P>to:</P>

<BLOCKQUOTE>

[<I>Note:</I> Although an implementation may provide a mechanism for
making arbitrary source files available to the <TT>&lt; &gt;</TT>
search, in general programmers should use the <TT>&lt; &gt;</TT> form
for headers provided with the implementation, and the <TT>" "</TT>
form for sources outside the control of the implementation. For
instance:

<PRE>
    #include &lt;stdio.h&gt;
    #include &lt;unistd.h&gt;
    #include "usefullib.h"
    #include "myprog.h"
</PRE>

&#8212;<I>end note</I>] 

</BLOCKQUOTE>

<P><B>Notes from October, 2005 meeting:</B></P>

<P>Some doubt was expressed as to whether the benefit of this
non-normative clarification outweighs the overall goal of synchronizing
clause 16 with the corresponding text in the C99 Standard.  As a
result, this issue is being left in &#8220;review&#8221; status to
allow further discussion.</P>

<P><B>Additional notes (October, 2006):</B></P>

<P>WG14 takes no position on this change.</P>

<BR><BR><HR><A NAME="106"></A><H4>106.
  
Creating references to references during template deduction/instantiation
</H4><B>Section: </B>unknown&#160; [unknown]
 &#160;&#160;&#160;

 <B>Status: </B>CD1
 &#160;&#160;&#160;

 <B>Submitter: </B>Bjarne Stroustrup
 &#160;&#160;&#160;

 <B>Date: </B>unknown<BR>



<P>[Moved to DR at 10/01 meeting.]</P>

<P>The main defect is in the library, where the binder template can
easily lead to reference-to-reference situations.</P>

<P><B>Proposed resolution (04/01):</B></P>

<OL>

<LI>
Add the following as paragraph 6 of 7.1.3 [dcl.typedef]:

<BLOCKQUOTE>

<P>If a typedef <TT>TD</TT> names a type "reference to
<I>cv1</I> <TT>S</TT>," an attempt to create the type
"reference to <I>cv2</I> <TT>TD</TT>" creates the type
"reference to <I>cv12"</I> <TT>S</TT>," where <I>cv12</I> is the
union of the cv-qualifiers <I>cv1</I> and <I>cv2</I>.
Redundant qualifiers are ignored.  [<I>Example:</I></P>

<PRE>
    int i;
    typedef int&amp; RI;
    RI&amp; r = i;          // r <I>has the type</I> int&amp;
    const RI&amp; r = i;    // r <I>has the type</I> const int&amp;
</PRE>

&#8212;<I>end example</I>]
</BLOCKQUOTE>
</LI>

<LI>
Add the following as paragraph 4 of 14.3.1 [temp.arg.type]:

<BLOCKQUOTE>

<P>If a <I>template-argument</I> for a <I>template-parameter</I>
<TT>T</TT> names a type "reference to <I>cv1</I> <TT>S</TT>,"
an attempt to create the type "reference to <I>cv2</I> <TT>T</TT>"
creates the type "reference to <I>cv12</I> <TT>S</TT>," where
<I>cv12</I> is the union of the cv-qualifiers <I>cv1</I> and
<I>cv2</I>.  Redundant cv-qualifiers are ignored.
[<I>Example:</I></P>

<PRE>
    template &lt;class T&gt; class X {
        f(const T&amp;);
        /* ... */
    };
    X&lt;int&amp;&gt; x;    // X&lt;int&amp;&gt;::f <I>has the parameter type</I> const int&amp;
</PRE>

&#8212;<I>end example</I>]

</BLOCKQUOTE>
</LI>

<LI>In 14.8.2 [temp.deduct] paragraph 2 bullet 3 sub-bullet
5, remove the indicated text:

<BLOCKQUOTE>

Attempting to create <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a reference to a reference type or</SPAN> a
reference to <TT>void</TT>.

</BLOCKQUOTE>
</LI>
</OL>

<P>(See also paper J16/00-0022 = WG21 N1245.)</P>

<BR><BR><BR><BR><HR><A NAME="CD2 Status"></A><H3>Issues with "CD2" Status</H3>
<HR><A NAME="816"></A><H4>816.
  
Diagnosing violations of <TT>[[final]]</TT>
</H4><B>Section: </B>_N3225_.7.6.4&#160; [dcl.attr.final]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>UK
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK108">N2800 comment
  UK&#160;108<BR></A>

<P>[Voted into WP at July, 2009 meeting.]</P>

<P>According to _N3225_.7.6.4 [dcl.attr.final] paragraph 2, overriding a
virtual function with the <TT>[[final]]</TT> attribute renders a program
ill-formed, but no diagnostic is required.  This is easily diagnosable
and a diagnostic should be required in this case.</P>

<P><B>Notes from the March, 2009 meeting:</B></P>

<P>This specification was a deliberate decision on the part of the
EWG; the general rule was that it should be possible to ignore
attributes without changing the meaning of a program.  However, the
consensus of the CWG was that violation of the <TT>[[final]]</TT>
attribute should require a diagnostic.</P>

<P><B>Proposed resolution (March, 2009):</B></P>

<P>Change _N3225_.7.6.4 [dcl.attr.final] paragraph 2 as follows:</P>

<BLOCKQUOTE>

If a virtual member function <TT>f</TT> in some class <TT>B</TT> is
marked <TT>final</TT> and in a class <TT>D</TT> derived from
<TT>B</TT> a function <TT>D::f</TT> overrides <TT>B::f</TT>, the
program is ill-formed<SPAN style="text-decoration:line-through;background-color:#FFA0A0">; no diagnostic
required</SPAN>. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">[<I>Footnote:</I> If an implementation does not emit
a diagnostic it should execute the program as if final were not
present. &#8212;<I>end footnote</I>]</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="817"></A><H4>817.
  
Meaning of <TT>[[final]]</TT> applied to a class definition
</H4><B>Section: </B>_N3225_.7.6.4&#160; [dcl.attr.final]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#US42">N2800 comment
  US&#160;42<BR></A>

<P>[Voted into WP at March, 2010 meeting.]</P>

<P>According to _N3225_.7.6.4 [dcl.attr.final] paragraph 1, the
<TT>[[final]]</TT> attribute applied to a class is just a shorthand
notation for marking each of the class's virtual functions as
<TT>[[final]]</TT>.  This is different from the similar usage in
other languages, where it means that the class so marked cannot be
used as a base class.  This discrepancy is confusing, and the
definition used by the other languages is more useful.</P>

<P><B>Notes from the March, 2009 meeting:</B></P>

<P>The intent of the <TT>[[final]]</TT> attribute is as an aid in
optimization, to avoid virtual function calls when the final
overrider is known. It is possible to use the <TT>[[final]]</TT>
attribute to prevent derivation by marking the destructor as
<TT>[[final]]</TT>; in fact, as most polymorphic classes will, as
a matter of good programming practice, have a virtual destructor,
marking the class as <TT>[[final]]</TT> will have the effect of
preventing derivation.</P>

<P>Nonetheless, the general consensus of the CWG was to change the
meaning of class <TT>[[final]]</TT> to parallel the usage in other
languages.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<OL><LI><P>Change _N3225_.7.6.4 [dcl.attr.final] paragraph 1 and add a
new paragraph, as follows:</P></LI>

<BLOCKQUOTE>

<P>The <I>attribute-token</I> <TT>final</TT> specifies <SPAN style="font-weight:bold;background-color:#A0FFA0">derivation
semantics for a class and</SPAN> overriding semantics for a virtual
function.  It shall appear at most once in each <I>attribute-list</I>
and no <I>attribute-argument-clause</I> shall be present.  The
attribute applies to class definitions and to virtual member functions
being declared in a class definition. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">If the attribute is specified
for a class definition, it is equivalent to being specified for each
virtual member function of that class, including inherited member
functions.</SPAN></P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">If some class <TT>B</TT> is marked <TT>final</TT> and a class
<TT>D</TT> is derived from <TT>B</TT> the program is
ill-formed.</SPAN></P>

</BLOCKQUOTE>

<LI><P>Change the example in _N3225_.7.6.4 [dcl.attr.final] paragraph 3
as follows:</P></LI>

<PRE>
  struct B<SPAN style="font-weight:bold;background-color:#A0FFA0">1</SPAN> {
    virtual void f [[ final ]] ();
  };

  struct D<SPAN style="font-weight:bold;background-color:#A0FFA0">1</SPAN> : B<SPAN style="font-weight:bold;background-color:#A0FFA0">1</SPAN> {
    void f();          //<SPAN style="font-family:Times;font-style:italic"> ill-formed</SPAN>
  };

<SPAN style="font-weight:bold;background-color:#A0FFA0">  struct [[ final ]] B2 {
  };

  struct D2 : B2 {    //<SPAN style="font-family:Times;font-style:italic"> ill-formed</SPAN>
  };</SPAN>
</PRE>

</OL>

<BR><BR><HR><A NAME="690"></A><H4>690.
  
The dynamic type of an rvalue reference
</H4><B>Section: </B>1.3&#160; [intro.defs]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Eelis van der Weegen
 &#160;&#160;&#160;

 <B>Date: </B>7 April, 2008<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#FR5">N2800 comment
  FR&#160;5<BR></A>

<P>[Voted into WP at March, 2010 meeting as document N3055.]</P>

<P>According to 1.3 [intro.defs], &#8220;dynamic type,&#8221;</P>

<BLOCKQUOTE>

The dynamic type of an rvalue expression is its static type.

</BLOCKQUOTE>

<P>This is not true of an rvalue reference, which can be bound
to an object of a class type derived from the reference's static
type.</P>

<P><B>Proposed resolution (June, 2008):</B></P>

<P>Change 1.3 [intro.defs], &#8220;dynamic type,&#8221;
as follows:</P>

<BLOCKQUOTE>

the type of the most derived object (1.8 [intro.object]) to
which <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the lvalue denoted by</SPAN> an lvalue <SPAN style="font-weight:bold;background-color:#A0FFA0">or an rvalue-reference
(clause 5 [expr])</SPAN> expression
refers. [<I>Example:</I> if a pointer (8.3.1 [dcl.ptr])
<TT>p</TT> whose static type is &#8220;pointer to class
<TT>B</TT>&#8221; is pointing to an object of class <TT>D</TT>,
derived from <TT>B</TT> (clause 10 [class.derived]), the dynamic
type of the expression <TT>*p</TT> is &#8220;D.&#8221; References
(8.3.2 [dcl.ref]) are treated similarly. &#8212;<I>end
example</I>] The dynamic type of an rvalue expression <SPAN style="font-weight:bold;background-color:#A0FFA0">that is not an
rvalue reference</SPAN> is its static type.

</BLOCKQUOTE>

<P><B>Notes from the June, 2008 meeting:</B></P>

<P>Because expressions have an rvalue reference type only fleetingly,
immediately becoming either lvalues or rvalues and no longer
references, the CWG expressed a desire for a different approach that
would somehow describe an rvalue that resulted from an rvalue
reference instead of using the concept of an expression that is an
rvalue reference, as above.  This approach could also be used in the
resolution of <A HREF="
     cwg_defects.html#664">issue 664</A>.</P>

<P><B>Additional note (August, 2008):</B></P>

<P>This issue, along with <A HREF="
     cwg_defects.html#664">issue 664</A>,
indicates that rvalue references have more in common with lvalues
than with other rvalues: they denote particular objects, thus
allowing object identity and polymorphic behavior.  That suggests
that these issues may be just the tip of the iceberg: restrictions
on out-of-lifetime access to objects, the aliasing rules, and many
other specifications are written to apply only to lvalues, on the
assumption that only lvalues refer to specific objects.  That
assumption is no longer valid with rvalue references.</P>

<P>This suggests that it might be better to classify all rvalue
references, not just named rvalue references, as lvalues instead
of rvalues, and then just change the reference binding, overload
resolution, and template argument deduction rules to cater to the
specific kind of lvalues that are associated with rvalue references.</P>

<P><B>Additional note, May, 2009:</B></P>

<P>Another place in the Standard where the assumption is made that
only lvalues can have dynamic types that differ from their static
types is 5.2.8 [expr.typeid] paragraph 2.</P>

<P>(See also issues <A HREF="
     cwg_defects.html#846">846</A> and
<A HREF="
     cwg_defects.html#863">863</A>.)</P>

<P><B>Additional note, September, 2009:</B></P>

<P>Yet another complication is the statement in 3.10 [basic.lval] paragraph 9 stating that &#8220;non-class rvalues always
have cv-unqualified types.&#8221; If an rvalue reference is an rvalue,
then the following example is well-formed:</P>

<PRE>
    void f(int&amp;&amp;);    //<SPAN style="font-family:Times;font-style:italic"> reference to non-const</SPAN>
    void g() {
        const int i = 0;
        f(static_cast&lt;const int&amp;&amp;&gt;(i));
    }
</PRE>

<P>The <TT>static_cast</TT> binds an rvalue reference to the const
object <TT>i</TT>, but the fact that it's an rvalue means that the
cv-qualification is lost, effectively allowing the parameter of
<TT>f</TT>, a reference to non-const, to bind directly to the const
object.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>See paper N3030.</P>

<BR><BR><HR><A NAME="612"></A><H4>612.
  
Requirements on a conforming implementation
</H4><B>Section: </B>1.9&#160; [intro.execution]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Clark Nelson
 &#160;&#160;&#160;

 <B>Date: </B>23 January 2007<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>The execution requirements on a conforming implementation are
described twice in the Standard, once in 1.9 [intro.execution]
paragraphs 5-6 and again in paragraph 11.  These descriptions differ
in at least a couple of important ways:</P>

<P>The most significant discrepancy has to do with the way output is
described. In paragraph 11, the least requirements are described in
terms of data written at program termination, clearly allowing
arbitrary buffering, whereas in paragraph 6, the observable behavior
is described in terms of calls to I/O functions.  For example, there
are compilers which transform a call to printf with a single argument
into a call to fputs.  That's valid under paragraph 11, but not under
paragraph 6.</P>

<P>Also, in paragraph 6, volatile accesses and I/O operations are
included in a single sequence, suggesting that they are equally
constrained by sequencing requirements, whereas in paragraph 11, they
are clearly not.</P>

<P>There are also editorial discrepancies that should be cleaned
up.</P>

<P><B>Proposed resolution (September, 2009):</B></P>

<P>The resolution of <A HREF="
     cwg_defects.html#785">issue 785</A> also
resolves this issue.</P>

<BR><BR><HR><A NAME="785"></A><H4>785.
  
&#8220;Execution sequence&#8221; is inappropriate phraseology
</H4><B>Section: </B>1.9&#160; [intro.execution]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>US/UK
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#US16">N2800 comment
  US&#160;16<BR></A>
<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK8">N2800 comment
  UK&#160;8<BR></A>
<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK7">N2800 comment
  UK&#160;7<BR></A>

<P>[Voted into WP at October, 2009 meeting.]</P>

<P>In the presence of threads, it is no longer appropriate to characterize
the abstract machine as having an &#8220;execution sequence.&#8221;</P>

<P><B>Proposed resolution (September, 2009):</B></P>

<OL><LI><P>Change 1.9 [intro.execution] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

...An instance of the abstract machine can thus have more than one
possible execution <SPAN style="text-decoration:line-through;background-color:#FFA0A0">sequence</SPAN> for a given program and a given input.

</BLOCKQUOTE>

<LI><P>Change 1.9 [intro.execution] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

A conforming implementation executing a well-formed program shall
produce the same observable behavior as one of the possible
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">execution sequences</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">executions</SPAN> of the
corresponding instance of the abstract machine with the same program
and the same input. However, if any such execution <SPAN style="text-decoration:line-through;background-color:#FFA0A0">sequence</SPAN>
contains an undefined operation, this International Standard places no
requirement on the implementation executing that program with that
input (not even with regard to operations preceding the first
undefined operation).

</BLOCKQUOTE>

<LI><P>Delete 1.9 [intro.execution] paragraph 6, including the
footnote:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The observable behavior of the abstract machine is its sequence
of reads and writes to <TT>volatile</TT> data and calls to library I/O
functions. [<I>Footnote:</I> An implementation can offer additional
library I/O functions as an extension.  Implementations that do so
should treat calls to those functions as &#8220;observable
behavior&#8221; as well. &#8212;<I>end footnote</I>]</SPAN>

</BLOCKQUOTE>

<LI><P>Change 1.9 [intro.execution] paragraph 9 as follows:</P></LI>

<BLOCKQUOTE>

<P>The least requirements on a conforming implementation are:</P>

<UL><LI><P>Access to volatile objects are evaluated strictly according
to the rules of the abstract machine.</P></LI>

<LI><P>At program termination, all data written into files shall be
identical to one of the possible results that execution of the program
according to the abstract semantics would have produced.</P></LI>

<LI><P>The input and output dynamics of interactive devices shall take
place in such a fashion that <SPAN style="text-decoration:line-through;background-color:#FFA0A0">prompting messages actually appear
prior to a program waiting</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">prompting output is actually
delivered before a program waits</SPAN> for input. What constitutes an
interactive device is implementation-defined.</P></LI>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">These collectively are referred to as the observable behavior
of the program.</SPAN> [<I>Note:</I> more stringent correspondences
between abstract and actual semantics may be defined by each
implementation. &#8212;<I>end note</I>]</P>

</BLOCKQUOTE>

</OL>

<P>(Note; this resolution also resolves <A HREF="
     cwg_defects.html#612">issue 612</A>.)</P>

<BR><BR><HR><A NAME="726"></A><H4>726.
  
Atomic and non-atomic objects in the memory model
</H4><B>Section: </B>1.10&#160; [intro.multithread]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Clark Nelson
 &#160;&#160;&#160;

 <B>Date: </B>30 September, 2008<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>In general, the description of the memory model is very careful to
specify when the objects under discussion are atomic or
non-atomic. However, there are a few cases where it could be
clearer.</P>

<P><B>Proposed resolution (March, 2009):</B></P>

<OL>
<LI><P>Modify 1.10 [intro.multithread] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

All modifications to a particular atomic object <I>M</I>
occur in some particular total order, called the
<I>modification order of M</I>. If <I>A</I> and <I>B</I> are
modifications of an atomic object <I>M</I> and <I>A</I> happens before
(as defined below) <I>B</I>, then <I>A</I> shall precede <I>B</I> in
the modification order of <I>M</I>, which is defined below.
[<I>Note:</I> This states that the modification orders must respect
<I>happens before</I>.  &#8212;<I>end note</I>] [<I>Note:</I> There is
a separate order for each <SPAN style="text-decoration:line-through;background-color:#FFA0A0">scalar</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">atomic</SPAN> object.  There
is no requirement that these can be combined into a single total order
for all objects.  In general this will be impossible since different
threads may observe modifications to different variables in
inconsistent orders. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Modify 1.10 [intro.multithread] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

Certain library calls <I>synchronize with</I> other library calls
performed by another thread.  In particular, an atomic operation
<I>A</I> that performs a release operation on an <SPAN style="font-weight:bold;background-color:#A0FFA0">atomic</SPAN> object
<I>M</I> synchronizes with an atomic operation <I>B</I> that performs
an acquire operation on <I>M</I> and reads a value written by any side
effect in the release sequence headed by <I>A</I>...

</BLOCKQUOTE>

<LI><P>Modify 1.10 [intro.multithread] paragraph 12 as follows:</P></LI>

<BLOCKQUOTE>

<P>A <I>visible side effect A</I> on <SPAN style="text-decoration:line-through;background-color:#FFA0A0">an</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">a scalar</SPAN>
object <SPAN style="font-weight:bold;background-color:#A0FFA0">or bit-field</SPAN> <I>M</I> with respect to a value
computation <I>B</I> of <I>M</I> satisfies the conditions:</P>

<UL><LI><P><I>A</I> happens before <I>B</I>, and</P></LI>

<LI><P>there is no other side effect <I>X</I> to <I>M</I> such that
<I>A</I> happens before <I>X</I> and <I>X</I> happens before
<I>B</I>.</P></LI>

</UL>

<P>The value of a non-atomic scalar object <SPAN style="font-weight:bold;background-color:#A0FFA0">or bit-field</SPAN>
<I>M</I>, as determined by evaluation <I>B</I>, shall be the value
stored by the visible side effect <I>A</I>. [<I>Note:</I> If there is
ambiguity about which side effect to a non-atomic object <SPAN style="font-weight:bold;background-color:#A0FFA0">or
bit-field</SPAN> is visible, then there is a data race, and the
behavior is undefined.  &#8212;<I>end note</I>] ...</P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="740"></A><H4>740.
  
Incorrect note on data races
</H4><B>Section: </B>1.10&#160; [intro.multithread]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Wolf Lammen
 &#160;&#160;&#160;

 <B>Date: </B>3 November, 2008<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>1.10 [intro.multithread] paragraph 12 says,</P>

<BLOCKQUOTE>

<P>A <I>visible side effect A</I> on an object <I>M</I> with
respect to a value computation <I>B</I> of <I>M</I> satisfies the
conditions:</P>

<UL><LI><P><I>A</I> happens before <I>B</I>, and</P></LI>

<LI><P>there is no other side effect <I>X</I> to <I>M</I> such that
<I>A</I> happens before <I>X</I> and <I>X</I> happens before
<I>B</I>.</P></LI>

</UL>

<P>The value of a non-atomic scalar object <I>M</I>, as determined by
evaluation <I>B</I>, shall be the value stored by the visible side
effect <I>A</I>. [<I>Note:</I> If there is ambiguity about which side
effect to a non-atomic object is visible, then there is a data race,
and the behavior is undefined.  &#8212;<I>end note</I>]</P>

</BLOCKQUOTE>

<P>The note here suggests that, except in the case of a data race,
visible side effects to value computation can always be determined.
But unsequenced and indeterminately sequenced side effects on the same
object create ambiguities with respect to a later value computation as
well. So the wording needs to be revisited, see the following
examples.</P>

<PRE>
    int main(){
      int i = 0;
      i = // unsequenced side effect A
      i++; // unsequenced side effect B
      return i; // value computation C
    }
</PRE>

<P>According to the definition in the draft, both A and B are visible
side effects to C. However, there is no data race, because (paragraph
14) a race involves at least two threads. So the note in paragraph 12
is logically false.</P>

<P>The model introduces the special case of indeterminately sequenced
side effects, that leave open what execution order is taken in a
concrete situation. If the execution paths access the same data,
unpredictable results are possible, just as it is the case with data
races. Whereas data races constitute undefined behavior,
indeterminatedly sequenced side effects on the same object do not. As
a consequence of this disparity, indeterminately sequenced execution
occasionally needs exceptional treatment.</P>

<PRE>
    int i = 0;
    int f(){
      return
      i = 1; // side effect A
    }
    int g(){
      return
      i = 2; // side effect B
    }
    int h(int, int){
      return i; // value computation C
    }
    int main(){
      return h(f(),g()); // function call D returns 1 or 2?
    }
</PRE>

<P>Here, either A or B is the visible side effect on the value
computation C, but you cannot tell which (cf. 1.9 [intro.execution]
paragraph 16).  Although an ambiguity is present, it is neither
because of a data race, nor is the behavior undefined, in total
contradiction to the note.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 1.10 [intro.multithread] paragraph 12 as follows:</P>

<BLOCKQUOTE>

...The value of a non-atomic scalar object or bit-field <I>M</I>, as
determined by evaluation <I>B</I>, shall be the value stored by the
visible side effect <I>A</I>. [<I>Note:</I> If there is ambiguity
about which side effect to a non-atomic object or bit-field is
visible, then <SPAN style="text-decoration:line-through;background-color:#FFA0A0">there is a data race, and</SPAN> the behavior is
<SPAN style="font-weight:bold;background-color:#A0FFA0">either unspecified or</SPAN> undefined. &#8212;<I>end note</I>]...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="786"></A><H4>786.
  
Definition of &#8220;thread&#8221;
</H4><B>Section: </B>1.10&#160; [intro.multithread]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#US17">N2800 comment
  US&#160;17<BR></A>

<P>[Voted into WP at October, 2009 meeting.]</P>

<P>The term &#8220;thread&#8221; is introduced but not defined in
1.10 [intro.multithread] paragraph 1.  A definition is needed.</P>

<P><B>Proposed resolution (September, 2009):</B></P>

<P>Chamge 1.10 [intro.multithread] paragraph 1 as follows:</P>

<BLOCKQUOTE>

<SPAN style="font-weight:bold;background-color:#A0FFA0">A <I>thread of execution</I> (a.k.a. <I>thread</I>) is a single
flow of control within a program, including the initial invocation of
a specific top-level function, and recursively including every
function invocation subsequently executed by the thread. [<I>Note:</I>
When one thread creates another, the initial call to the top-level
function of the new thread is executed by the new thread, not by the
creating thread. &#8212;<I>end note</I>] Every thread in a program can
potentially access every object and function in the program.
[<I>Footnote:</I> An object with automatic or thread storage duration
(3.7 [basic.stc]) is associated with one specific thread, and
can be accessed by a different thread only indirectly through a
pointer or reference (3.9.2 [basic.compound]).  &#8212;<I>end
footnote</I>]</SPAN> Under a hosted implementation, a C++ program can
have more than one <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>thread of execution</I>
(a.k.a. <I>thread</I>)</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">thread</SPAN> running concurrently...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="787"></A><H4>787.
  
Unnecessary lexical undefined behavior
</H4><B>Section: </B>2.2&#160; [lex.phases]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>UK
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK9">N2800 comment
  UK&#160;9<BR></A>
<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK12">N2800 comment
  UK&#160;12<BR></A>

<P>[Voted into WP at March, 2010 meeting.]</P>

<P>There are several instances of undefined behavior in lexical
processing:</P>

<UL><LI><P>2.2 [lex.phases] paragraph 1, phase 2: a
universal-character-name resulting from a line splice.
</P></LI>

<LI><P>2.2 [lex.phases] paragraph 1, phase 2: a file ending
without a new-line character or with a new-line character that is spliced
away.</P></LI>

<LI><P>2.2 [lex.phases] paragraph 1, phase 4: a
universal-character-name resulting from macro token concatenation.</P></LI>

<LI><P>2.9 [lex.header] paragraph 2: <TT>'</TT>, <TT>\</TT>,
<TT>/*</TT>, <TT>//</TT>, or <TT>"</TT> appearing in a <I>header-name</I>.
</P></LI>

</UL>

<P>These would be more appropriately handled as conditionally-supported
behavior, requiring implementations either to document their handling
of these constructs or to issue a diagnostic.</P>

<P><B>Additional note, March, 2009:</B></P>

<P>The undefined behavior referred to above regarding
universal-character-names is the result of the considerations
described in <A href="http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf">
the C99 Rationale</A>, section 5.2.1, in the part entitled &#8220;UCN
models.&#8221; Three different models for support of UCNs are
described, each involving different conversions between UCNs and wide
characters and/or at different times during program translation.
Implementations, as well as the specification in a language standard,
can employ any of the three, but it must be impossible for a
well-defined program to determine which model was actually employed by
implementation.  The implication of this &#8220;equivalence
principle&#8221; is that any construct that would give different
results under the different models must be classified as undefined
behavior.  For example, an apparent UCN resulting from a line-splice
would be recognized as a UCN by an implementation in which all wide
characters were translated immediately into UCNs, as described in C++
phase 1, but would not be recognized as a UCN by another
implementation in which all UCNs were translated immediately into wide
characters (a possibility mentioned parenthetically in C++ phase
1).</P>

<P>There are additional implications for this &#8220;equivalence
principle&#8221; beyond the ones identified in the UK CD comments.
See also <A HREF="
     cwg_active.html#578">issue 578</A>; presumably a string
like the one in that issue should also be described as having
undefined behavior.  Also, because C++'s model introduces backslash
characters as part of UCNs for any character outside the basic source
character set, any <I>header-name</I> that contains such a character
(e.g., <TT>#include "@.h"</TT>) will have undefined behavior in C++.
This is also the reason that UCNs are translated into wide characters
inside raw strings: two of the three models articulated in the C99
Rationale translate to or from UCNs in phase 1, before raw strings
are recognized as tokens in phase 3, so raw strings cannot treat UCNs
differently from the way they are treated in other contexts.
  See also <A HREF="
     cwg_defects.html#789">issue 789</A> for
similar points regarding trigraphs.
</P>

<P><B>Notes from the October, 2009 meeting:</B></P>

<P>The CWG decided that the non-UCN aspects of this issue should be
resolved, while the overall questions regarding trigraphs, UCNs, and
raw strings will be investigated separately.
</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<OL><LI><P>Change 2.2 [lex.phases] paragraph 1 phase 2 as
follows:</P></LI>

<BLOCKQUOTE>

...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">If a</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">A</SPAN> source file that is not empty <SPAN style="font-weight:bold;background-color:#A0FFA0">and
that</SPAN> does not end in a new-line character, or <SPAN style="font-weight:bold;background-color:#A0FFA0">that</SPAN>
ends in a new-line character immediately preceded by a backslash
character before any such splicing takes place, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the behavior is
undefined</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">shall be processed as if an additional new-line
character were appended to the file</SPAN>.

</BLOCKQUOTE>

<LI><P>Change 2.9 [lex.header] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">If</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">The appearance of</SPAN> either of the characters
<TT>'</TT> or <TT>\</TT><SPAN style="text-decoration:line-through;background-color:#FFA0A0">,</SPAN> or <SPAN style="font-weight:bold;background-color:#A0FFA0">of</SPAN> either of the
character sequences <TT>/*</TT> or <TT>//</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">appears</SPAN> in a
<I>q-char-sequence</I> or <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an</SPAN>
<I>h-char-sequence</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">is conditionally-supported with
implementation-defined semantics</SPAN>, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">as is
the appearance of</SPAN> the character <TT>"</TT>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">appears</SPAN> in <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an</SPAN>
<I>h-char-sequence</I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">, the behavior is undefined</SPAN>.
[<I>Footnote:</I> Thus, <SPAN style="font-weight:bold;background-color:#A0FFA0">a</SPAN> sequence<SPAN style="text-decoration:line-through;background-color:#FFA0A0">s</SPAN> of
characters that resemble<SPAN style="font-weight:bold;background-color:#A0FFA0">s an</SPAN> escape sequence<SPAN style="text-decoration:line-through;background-color:#FFA0A0">s cause
undefined behavior</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">might result in an error, be interpreted
as the character corresponding to the escape sequence, or have a
completely different meaning, depending on the
implementation</SPAN>. &#8212;<I>end footnote</I>]

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="630"></A><H4>630.
  
Equality of narrow and wide character values in the basic character set
</H4><B>Section: </B>2.3&#160; [lex.charset]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Tom Plum
 &#160;&#160;&#160;

 <B>Date: </B>21 April 2007<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>WG14 accepted
<A href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_279.htm">
DR 279</A> regarding the rule known colloquially as the
<TT>L'x'=='x'</TT> rule.  This change was made to C99 in TC2.  The
Austin Group subsequently opened
<A href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_321.htm">
DR 321</A> against TC2, observing that the change made in TC2 would
invalidate existing conforming C code that relied on the
<TT>L'x'=='x'</TT> rule.</P>

<P>DR 321 is now closed and will be included in the TC3 to C99.  This
change defines a new standard macro, which WG14 drafted as follows:</P>

<BLOCKQUOTE>

<TT>__STDC_MB_MIGHT_NEQ_WC__</TT>: The integer constant <TT>1</TT>,
intended to indicate that there might be some
character <TT>x</TT> in the basic character set, such
that <TT>'x'</TT> need not be equal to <TT>L'x'</TT>.

</BLOCKQUOTE>

<P>WG14 requests that WG21 adopt this revision and this macro in
C++0x.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Add the following to 16.8 [cpp.predefined] paragraph 2:</P>

<BLOCKQUOTE>

<DL><DT><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>__STDC_MB_MIGHT_NEQ_WC__</TT></SPAN></DT>

<DD><SPAN style="font-weight:bold;background-color:#A0FFA0">The integer constant <TT>1</TT>, intended to indicate that,
in the encoding for <TT>wchar_t</TT>, a member of the basic character
set need not have a code value equal to its value when used as the
lone character in an ordinary character literal.</SPAN></DD>

</DL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="788"></A><H4>788.
  
Relationship between locale and values of the execution character set
</H4><B>Section: </B>2.3&#160; [lex.charset]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>FR
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#FR10">N2800 comment
  FR&#160;10<BR></A>

<P>[Voted into WP at March, 2010 meeting.]</P>

<P>According to 2.3 [lex.charset] paragraph 3,</P>

<BLOCKQUOTE>

The values of the members of the execution character sets are
implementation-defined, and any additional members
are locale-specific.

</BLOCKQUOTE>

<P>This makes it sound as if the locale determines only whether an
extended character (one not in the basic execution character set)
exists, not its value (which is just implementation-defined, not
locale-specific).  The description should be clarified to indicate
that the value of a given character can vary between locales, as
well.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 2.3 [lex.charset] paragraph 3 as follows:</P>

<BLOCKQUOTE>

...The<I> execution character set</I> and the <I>execution
wide-character set</I> are <SPAN style="font-weight:bold;background-color:#A0FFA0">implementation-defined</SPAN>
supersets of the basic execution character set and the basic
execution wide-character set, respectively.  The values of the
members of the execution character sets <SPAN style="font-weight:bold;background-color:#A0FFA0">and the sets of
additional members</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">are implementation-defined, and any
additional members</SPAN> are locale-specific.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="789"></A><H4>789.
  
Deprecating trigraphs
</H4><B>Section: </B>2.4&#160; [lex.trigraph]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>UK
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK11">N2800 comment
  UK&#160;11<BR></A>

<P>[Voted into WP at March, 2010 meeting as document N3077.]</P>

<P>
Trigraphs are a complicated solution to an
old problem, that cause more problems than they solve in
the modern environment. Unexpected trigraphs in string
literals and occasionally in comments can be very confusing
for the non-expert. They should be deprecated.
</P>

<P><B>Notes from the March, 2009 meeting:</B></P>

<P>IBM, at least, uses trigraphs in its header files in conditional
compilation directives to select character-set dependent content in a
character-set independent fashion and would thus be negatively affected
by the removal of trigraphs.  One possibility that was discussed was
to avoid expanding trigraphs inside character string literals, which is
the context that causes most surprise and confusion, but still to
support them in the rest of the program text.  Specifying that approach,
however, would be challenging because trigraphs are replaced in phase 1,
before character strings are recognized in phase 3.  See also the similar
discussion of universal-character-names in <A HREF="
     cwg_defects.html#787">issue 787</A>.</P>

<P>The consensus of the CWG was that trigraphs should be deprecated.</P>

<P><B>Proposed resolution (September, 2009):</B></P>

<P>See paper PL22.16/09-0168 = WG21 N2978.</P>

<P><B>Notes from the October, 2009 meeting:</B></P>

<P>The CWG is interested in exploring other alternatives that address
the particular problem of trigraphs in raw strings but that do not
require the grammar changes of the approach in N2978.  One possibility
might be to recognize raw strings in some way in translation phase
1.</P>

<P><B>Notes from the March, 2010 meeting:</B></P>

<P>The CWG decided not to deprecate trigraphs, acknowledging that
there are communities in which they are viewed as necessary.  Instead,
it was decided to address what was considered to be the most pressing
issue regarding trigraphs, that is, recognizing trigraph sequences
inside raw string literals.</P>

<BR><BR><HR><A NAME="832"></A><H4>832.
  
Value of preprocessing numbers
</H4><B>Section: </B>2.10&#160; [lex.ppnumber]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>UK
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK13">N2800 comment
  UK&#160;13<BR></A>

<P>[Voted into WP at October, 2009 meeting.]</P>

<P>2.10 [lex.ppnumber] paragraph 2 says,</P>

<BLOCKQUOTE>

A preprocessing number does not have a type or a value; it acquires
both after a successful conversion (as part of translation phase 7,
2.2 [lex.phases]) to an integral literal token or a
floating literal token.

</BLOCKQUOTE>

<P>However, preprocessing directives are executed in phase 4, and
the evaluation of <I>constant-expression</I>s in <TT>#if</TT>
directives requires that preprocessing numbers have values.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 2.10 [lex.ppnumber] paragraph 2 as follows:</P>

<BLOCKQUOTE>

A preprocessing number does not have a type or a value; it acquires
both after a successful conversion <SPAN style="text-decoration:line-through;background-color:#FFA0A0">(as part of translation phase
7 (2.2 [lex.phases]))</SPAN> to an integral literal token or a
floating literal token.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="933"></A><H4>933.
  
32-bit UCNs with 16-bit <TT>wchar_t</TT>
</H4><B>Section: </B>2.14.3&#160; [lex.ccon]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>7 July, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>According to 2.14.3 [lex.ccon] paragraph 2,</P>

<BLOCKQUOTE>

A character literal that begins with the letter <TT>L</TT>, such as
<TT>L'x'</TT>, is a wide-character literal.  A wide-character literal
has type <TT>wchar_t</TT>. The value of a wide-character literal
containing a single <I>c-char</I> has value equal to the numerical
value of the encoding of the <I>c-char</I> in the execution
wide-character set.

</BLOCKQUOTE>

<P>A <I>c-char</I> that is a universal character name might, when
translated to the execution character set, result in a multi-character
sequence that is larger than can be represented in a <TT>wchar_t</TT>.
There is wording that prevents this in <TT>char16_t</TT> literals, but
not for <TT>wchar_t</TT> literals.  This seems undesirable.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<OL><LI><P>Change 2.14.3 [lex.ccon] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

...The value of a wide-character literal containing a single
<I>c-char</I> has value equal to the numerical value of the encoding
of the <I>c-char</I> in the execution wide-character set<SPAN style="font-weight:bold;background-color:#A0FFA0">, unless
the <I>c-char</I> has no representation in the execution
wide-character set, in which case the value is
implementation-defined. [<I>Note:</I> The type <TT>wchar_t</TT> is
able to represent all members of the execution wide-character set, see
3.9.1 [basic.fundamental]. &#8212;<I>end note</I>]</SPAN>.  The value
of a wide-character literal containing multiple <I>c-char</I>s is
implementation-defined.

</BLOCKQUOTE>

<LI><P>Change 2.14.3 [lex.ccon] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

A universal-character-name is translated to the encoding, in the
<SPAN style="font-weight:bold;background-color:#A0FFA0">appropriate</SPAN> execution character set, of the character
named...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="790"></A><H4>790.
  
Concatenation of raw and non-raw string literals
</H4><B>Section: </B>2.14.5&#160; [lex.string]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>JP
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#JP5">N2800 comment
  JP&#160;5<BR></A>

<P>[Voted into WP at October, 2009 meeting.]</P>

<P>The description of concatenation of string literals in
2.14.5 [lex.string] paragraph 11 does not mention raw
strings explicitly, so it is not clear whether, and if so, how, they
combine with non-raw strings.</P>

<P><B>Notes from the March, 2009 meeting:</B></P>

<P>A raw string should be considered equivalent to the corresponding
non-raw string in string literal concatenation.</P>

<P><B>Proposed resolution (September, 2009):</B></P>

<OL><LI><P>In 2.14.5 [lex.string], replace the definition of
<I>string-literal</I> with:</P></LI>

<UL><I>string-literal:</I>
<UL><I>encoding-prefix<SUB>opt</SUB></I> <TT>"</TT> <I>s-char-sequence<SUB>opt</SUB></I> <TT>"</TT></UL>
<UL><I>encoding-prefix<SUB>opt</SUB></I> <TT>R</TT> <I>raw-string</I></UL>
</UL><BR>

<UL><I>encoding-prefix:</I>
<UL><TT>u8</TT></UL>
<UL><TT>u</TT></UL>
<UL><TT>U</TT></UL>
<UL><TT>L</TT></UL>
</UL>

<LI><P>Change 2.14.5 [lex.string] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">After translation phase 6, a</SPAN> string literal
that does not begin with <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>u8</TT>, <TT>u</TT>, <TT>U</TT>, or
<TT>L</TT></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an <I>encoding-prefix</I></SPAN> is an ordinary
string literal, and is initialized with the given characters.

</BLOCKQUOTE>

<LI><P>Change 2.14.5 [lex.string] paragraph 12 as follows:</P></LI>

<BLOCKQUOTE>

In translation phase 6 (2.2 [lex.phases]), adjacent string
literals are concatenated.  If both string literals have the same
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">prefix</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>encoding-prefix</I></SPAN>, the resulting
concatenated string literal has that <SPAN style="text-decoration:line-through;background-color:#FFA0A0">prefix</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>encoding-prefix</I></SPAN>. If one string literal has no
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">prefix</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>encoding-prefix</I></SPAN>, it is treated as
a string literal of the same <SPAN style="text-decoration:line-through;background-color:#FFA0A0">prefix</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>encoding-prefix</I></SPAN> as the other operand.  If a UTF-8
string literal token is adjacent to a wide string literal token, the
program is ill-formed.  Any other concatenations are conditionally
supported with implementation-defined behavior.  [<I>Note:</I> This
concatenation is an interpretation, not a conversion. <SPAN style="font-weight:bold;background-color:#A0FFA0">Because the
interpretation happens in translation phase 6 (after each character
from each literal has been translated into a value from the
appropriate character set), a string literal's initial rawness has no
effect on the interpretation or well-formedness of the
concatenation.</SPAN> &#8212;<I>end note</I>] [<I>Example:</I>...

</BLOCKQUOTE>

</OL>

<P>(Note: this resolution also resolves <A HREF="
     cwg_defects.html#834">issue 834</A>.)</P>

<BR><BR><HR><A NAME="834"></A><H4>834.
  
What is an &#8220;ordinary string literal&#8221;?
</H4><B>Section: </B>2.14.5&#160; [lex.string]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>6 March, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>According to 2.14.5 [lex.string] paragraph 4,</P>

<BLOCKQUOTE>

A string literal that does not begin with <TT>u8</TT>, <TT>u</TT>,
<TT>U</TT>, or <TT>L</TT> is an ordinary string literal, and is
initialized with the given characters.

</BLOCKQUOTE>

<P>This is not as clear as it could be that a string like
<TT>u8R"[xxx]"</TT> is not an ordinary string literal, because the
string's prefix is not one of those listed (i.e., it's not obvious
that possible substrings of the prefix are in view). This would be
clearer if it simply said,</P>

<BLOCKQUOTE>

A string literal with no prefix or a prefix of <TT>R</TT> is an
ordinary string literal.

</BLOCKQUOTE>

<P><B>Proposed resolution (September, 2009):</B></P>

<P>This issue is resolved by the resolution of <A HREF="
     cwg_defects.html#790">issue 790</A>.</P>

<BR><BR><HR><A NAME="872"></A><H4>872.
  
Lexical issues with raw strings
</H4><B>Section: </B>2.14.5&#160; [lex.string]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Joseph Myers
 &#160;&#160;&#160;

 <B>Date: </B>16 April, 2009<BR>


<P>[Voted into WP at March, 2010 meeting as document N3077.]</P>

<P>The specification of raw string literals interacts poorly with
the specification of preprocessing tokens.  The grammar in
2.5 [lex.pptoken] has a production reading</P>

<UL>each non-white-space character that cannot be one of the above</UL>

<P>This is echoed in the max-munch rule in paragraph 3:</P>

<BLOCKQUOTE>

If the input stream has been parsed into preprocessing tokens up to a
given character, the next preprocessing token is the longest sequence
of characters that could constitute a preprocessing token, even if
that would cause further lexical analysis to fail.

</BLOCKQUOTE>

<P>This raises questions about the handling of raw string literals.
Consider, for instance,</P>

<PRE>
    #define R "x"
    const char* s = R"y";
</PRE>

<P>The character sequence <TT>R"y"</TT> does not satisfy the
syntactic requirements for a raw string.  Should it be diagnosed as
an ill-formed attempt at a raw string, or should it be well-formed,
interpreting <TT>R</TT> as a preprocessor token that is a macro name and
thus initializing <TT>s</TT> with a pointer to the string
<TT>"xy"</TT>?</P>

<P>For another example, consider:</P>

<PRE>
    #define R "]"
    const char* x = R"foo[";
</PRE>

<P>Presumably this means that the entire rest of the file must be
scanned for the characters <TT>]foo"</TT> and, if they are not
found, macro-expand <TT>R</TT> and initialize <TT>x</TT> with a pointer to
the string <TT>"]foo["</TT>.  Is this the intended result?</P>

<P>Finally, does the requirement in 2.14.5 [lex.string]
that</P>

<BLOCKQUOTE>

A <I>d-char-sequence</I> shall consist of at most 16 characters.

</BLOCKQUOTE>

<P>mean that</P>

<PRE>
    #define R "x"
    const char* y = R"12345678901234567[y]12345678901234567";
</PRE>

<P>is ill-formed, or a valid initialization of <TT>y</TT> with a
pointer to the string <TT>"x12345678901234567[y]12345678901234567"</TT>?</P>

<P><B>Additional note, June, 2009:</B></P>



<P>The translation of characters that are not in the basic source
character set into universal-character-names in translation phase 1
raises an additional problem: each such character will occupy at
least six of the 16 <I>r-char</I>s that are permitted.  Thus, for
example, <TT>R"@@@[]@@@"</TT> is ill-formed because <TT>@@@</TT>
becomes <TT>\u0040\u0040\u0040</TT>, which is 18 characters.</P>

<P>One possibility for addressing this might be to disallow the
<TT>\</TT> character completely as an <I>d-char</I>, which would
have the effect of restricting <I>r-char</I>s to the basic source
character set.</P>



<P><B>Proposed resolution (October, 2009):</B></P>

<OL><LI><P>Change the grammar in 2.14.5 [lex.string] as
follows:</P></LI>

<UL><I>d-char:</I>
<UL>any member of the basic source character set except:
<UL>space, the left square bracket <TT>[</TT>,
the right square bracket <TT>]</TT>, <SPAN style="font-weight:bold;background-color:#A0FFA0">the backslash <TT>\</TT>,</SPAN>
and the control characters representing horizontal tab,
vertical tab, form feed, and newline.</UL>
</UL>
</UL>

<LI><P>Change 2.14.5 [lex.string] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

<P>A string literal that has an <TT>R</TT> in the prefix is a
<I>raw string literal</I>. The <I>d-char-sequence</I> serves as a
delimiter.  The terminating <I>d-char-sequence</I> of a raw-string is the
same sequence of characters as the initial <I>d-char-sequence</I>. A
<I>d-char-sequence</I> shall consist of at most 16 characters.
<SPAN style="font-weight:bold;background-color:#A0FFA0">If the input stream contains a sequence of characters that could
be the prefix and initial double quote of a raw string literal, such
as <TT>R"</TT>, those characters are considered to begin a raw string
literal even if that literal is not well-formed. [<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  #define R "x"
  const char* s = R"y"; //<SPAN style="font-family:Times;font-style:italic"> ill-formed raw string, not </SPAN>"x" "y"
</SPAN></PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="932"></A><H4>932.
  
UCNs in closing delimiters of raw string literals
</H4><B>Section: </B>2.14.5&#160; [lex.string]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>7 July, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>Since members of the basic source character set can be written inside
a string using a universal character name, it is not clear whether a UCN
that represents <TT>']'</TT> or one of the characters in the terminating
<I>d-char-sequence</I> should be interpreted as that character or as
an attempt to &#8220;escape&#8221; that character and prevent its
interpretation as part of the terminating sequence of a raw character
string.</P>

<P><B>Notes from the July, 2009 meeting:</B></P>

<P>The CWG supported a resolution in which the <I>d-char-sequence</I>
of a raw string literal is considered to be outside the literal and
thus, by 2.3 [lex.charset] paragraph 2, could not contain a UCN
designating a member of the basic source character set.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 2.3 [lex.charset] paragraph 2 as follows:</P>

<BLOCKQUOTE>

Additionally, if the hexadecimal value for a universal-character-name
outside <SPAN style="font-weight:bold;background-color:#A0FFA0">the <I>c-char-sequence</I>, <I>s-char-sequence</I>, or
<I>r-char-sequence</I> of</SPAN> a character or string literal
corresponds to a control character (in either of the ranges 0x00-0x1F
or 0x7F-0x9F, both inclusive) or to a character in the basic source
character set, the program is ill-formed.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="931"></A><H4>931.
  
Confusing reference to the length of a user-defined string literal
</H4><B>Section: </B>2.14.8&#160; [lex.ext]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>6 July, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>2.14.8 [lex.ext] paragraph 5 says,</P>

<BLOCKQUOTE>

If <I>L</I> is a <I>user-defined-string-literal</I>, let <I>str</I> be
the literal without its <I>ud-suffix</I> and let <I>len</I> be the
number of characters (or code points) in <I>str</I> (i.e., its length
excluding the terminating null character).

</BLOCKQUOTE>

<P>The length of a null-terminated string is defined in 17.5.2.1.4.1 [byte.strings] as the number of bytes preceding the terminator,
but a single code point in a UTF-8 string can require more than one
byte, so this sentence is inconsistent and needs to be revised to make
clear which definition is in view.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 2.14.8 [lex.ext] paragraph 5 as follows:</P>

<BLOCKQUOTE>

If <I>L</I> is a <I>user-defined-string-literal</I>, let <I>str</I> be
the literal without its <I>ud-suffix</I> and let <I>len</I> be the
number of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">characters (or code points)</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">code units</SPAN>
in <I>str</I> (i.e., its length excluding the terminating null
character)...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="633"></A><H4>633.
  
Specifications for variables that should also apply to references
</H4><B>Section: </B>3&#160; [basic]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>17 May 2007<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK22">N2800 comment
  UK&#160;22<BR></A>

<P>[Voted into WP at March, 2010 meeting as document N2993.]</P>

<P>There are a number of specifications in the Standard that should
also apply to references.  For example:</P>

<UL>
<LI><P>3 [basic] paragraphs 3-4 indicate that a reference
cannot have a name because it is not an entity.  (See also
<A HREF="
     cwg_defects.html#485">issue 485</A>.)</P></LI>

<LI><P>3.4.1 [basic.lookup.unqual] paragraph 13 covers unqualified
lookup in the initializer of a variable member of a namespace but not
that of a reference member of a namespace.  It would be very strange
if the lookup in these two cases were different.</P></LI>

<LI><P>3.5 [basic.link] paragraph 8 prohibits use of a type
without linkage as the type of a variable with linkage, but not as the
type of a reference with linkage.  (References with linkage are
explicitly mentioned earlier in the section.)</P></LI>

<LI><P>3.7.1 [basic.stc.static] paragraph 3 permits local static
variables but not local static references.</P></LI>

</UL>

<P>A number of other examples could be cited.  A thorough review
is needed to make sure that references are completely
specified.</P>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>The CWG expressed interest in an approach that would define
&#8220;variable&#8221; to include both objects and references and
to use that for both this issue and <A HREF="
     cwg_defects.html#570">issue 570</A>.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>See paper PL22.16/09-0183 = WG21 N2993.  This resolution also resolves
<A HREF="
     cwg_defects.html#570">issue 570</A>.</P>

<BR><BR><HR><A NAME="719"></A><H4>719.
  
Specifications for <I>operator-function-id</I> that should also apply to <I>literal-operator-id</I>
</H4><B>Section: </B>3&#160; [basic]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>19 September, 2008<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>When user-defined literals were added, a new form of operator
function was created.  Presumably many of the existing
specifications that deal with <I>operator-function-id</I>s (the
definition of <I>name</I>, for instance, in paragraph 4 of
3 [basic]) should also apply to
<I>literal-operator-id</I>s.</P>

<P><B>Proposed resolution (June, 2009):</B></P>

<OL><LI><P>Change 3 [basic] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

A <I>name</I> is a use of an <I>identifier</I> (2.11 [lex.name]),
<I>operator-function-id</I> (13.5 [over.oper]),
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>literal-operator-id</I> (13.5.8 [over.literal]),</SPAN>
<I>conversion-function-id</I> (12.3.2 [class.conv.fct]), or
<I>template-id</I> (14.2 [temp.names]) that denotes an entity
or <I>label</I> (6.6.4 [stmt.goto], 6.1 [stmt.label]).

</BLOCKQUOTE>

<LI><P>Change 5.1.1 [expr.prim.general] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

The operator <TT>::</TT> followed by an <I>identifier</I>, a
<I>qualified-id</I>, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN> an <I>operator-function-id</I><SPAN style="font-weight:bold;background-color:#A0FFA0">, or a
<I>literal-operator-id</I></SPAN> is a
<I>primary-expression</I>.  Its type is specified by the declaration
of the identifier, <I>qualified-id</I>, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN>
<I>operator-function-id</I><SPAN style="font-weight:bold;background-color:#A0FFA0">, or <I>literal-operator-id</I></SPAN>.
The result is the entity denoted by the identifier,
<I>qualified-id</I>, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN> <I>operator-function-id</I><SPAN style="font-weight:bold;background-color:#A0FFA0">, or
<I>literal-operator-id</I></SPAN>. The result is an
lvalue if the entity is a function or variable.  The identifier,
<I>qualified-id</I>, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN> <I>operator-function-id</I><SPAN style="font-weight:bold;background-color:#A0FFA0">, or
<I>literal-operator-id</I></SPAN> shall have global namespace scope or be
visible in global scope because of a
<I>using-directive</I> (7.3.4 [namespace.udir])...

</BLOCKQUOTE>

<LI><P>Add the following production to the grammar for
<I>qualified-id</I> in 5.1.1 [expr.prim.general] paragraph 7:</P></LI>

<UL><I>qualified-id:</I>
<UL><TT>::</TT><I><SUB>opt</SUB> nested-name-specifier</I> <TT>template</TT><I><SUB>opt</SUB> unqualified-id</I></UL>
<UL><TT>::</TT> <I>identifier</I></UL>
<UL><TT>::</TT> <I>operator-function-id</I></UL>
<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>::</TT> <I>literal-operator-id</I></SPAN></UL>
<UL><TT>::</TT> <I>template-id</I></UL>
</UL>

<LI><P>Add the following production to the grammar for
<I>template-id</I> in 14.2 [temp.names] paragraph 1:</P></LI>

<UL><I>template-id:</I>
<UL><I>simple-template-id</I></UL>
<UL><I>operator-function-id</I> <TT>&lt;</TT> <I>template-argument-list<SUB>opt</SUB></I> <TT>&gt;</TT></UL>
<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><I>literal-operator-id</I> <TT>&lt;</TT> <I>template-argument-list<SUB>opt</SUB></I> <TT>&gt;</TT></SPAN></UL>
</UL>

<LI><P>Change 14.2 [temp.names] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

After name lookup (3.4 [basic.lookup]) finds that a name is a
<I>template-name</I>, or that an <I>operator-function-id</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">or a
<I>literal-operator-id</I></SPAN> refers to a set of overloaded functions
any member of which is a function template...

</BLOCKQUOTE>

<LI><P>Change 14.4 [temp.type] paragraph 1 bullet 1 as
follows:</P></LI>

<UL><LI><P>their <I>template-name</I>s<SPAN style="font-weight:bold;background-color:#A0FFA0">,</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN>
<I>operator-function-id</I>s<SPAN style="font-weight:bold;background-color:#A0FFA0">, or <I>literal-operator-id</I>s</SPAN>
refer to the same template, and</P></LI></UL>

</OL>

<BR><BR><HR><A NAME="942"></A><H4>942.
  
Is <TT>this</TT> an entity?
</H4><B>Section: </B>3&#160; [basic]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Maurer
 &#160;&#160;&#160;

 <B>Date: </B>14 July, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>At least in the new wording for 5.1.2 [expr.prim.lambda] paragraph 10
as found in paper N2927, <TT>this</TT> is explicitly assumed to be an
entity.  It should be investigated whether <TT>this</TT> should be added
to the list of entities found in 3 [basic] paragraph 3.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<OL><LI><P>Change 3 [basic] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

An <I>entity</I> is a value, object, variable, reference, function,
enumerator, type, class member, template, template specialization,
namespace, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN> parameter pack<SPAN style="font-weight:bold;background-color:#A0FFA0">, or <TT>this</TT></SPAN>.

</BLOCKQUOTE>

<LI><P>Change 3.2 [basic.def.odr] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

...is immediately applied. <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>this</TT> is used if it appears as
a potentially-evaluated expression (including as the result of the
implicit transformation in the body of a non-static member function
(9.3.1 [class.mfct.non-static])).</SPAN> A virtual member function...

</BLOCKQUOTE>

<LI><P>Delete 5.1.2 [expr.prim.lambda] paragraph 7:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">For the purpose of describing the behavior of
<I>lambda-expression</I>s below, <TT>this</TT> is considered to be
&#8220;used&#8221; if replacing <TT>this</TT> by an invented variable
<TT>v</TT> with automatic storage duration and the same type as
<TT>this</TT> would result in <TT>v</TT> being used (3.2 [basic.def.odr]).</SPAN>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="570"></A><H4>570.
  
Are references subject to the ODR?
</H4><B>Section: </B>3.2&#160; [basic.def.odr]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Dave Abrahams
 &#160;&#160;&#160;

 <B>Date: </B>2 April 2006<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK26">N2800 comment
  UK&#160;26<BR></A>

<P>[Voted into WP at March, 2010 meeting as document N2993.]</P>



<P>3.2 [basic.def.odr] paragraph 1 says,</P>

<BLOCKQUOTE>

No translation unit shall contain more than one definition of any
variable, function, class type, enumeration type or template.

</BLOCKQUOTE>

<P>This says nothing about references.  Is it permitted to define a
reference more than once in a single translation unit?  (The list in
paragraph 5 of things that can have definitions in multiple translation
units does not include references.)</P>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>The CWG expressed interest in an approach that would define
&#8220;variable&#8221; to include both objects and references and
to use that for both this issue and <A HREF="
     cwg_defects.html#633">issue 633</A>.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>This issue is resolved by the resolution of <A HREF="
     cwg_defects.html#633">issue 633</A>.</P>

<BR><BR><HR><A NAME="481"></A><H4>481.
  
Scope of template parameters
</H4><B>Section: </B>3.3&#160; [basic.scope]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Gabriel Dos Reis
 &#160;&#160;&#160;

 <B>Date: </B>01 Nov 2004<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#FR16">N2800 comment
  FR&#160;16<BR></A>

<P>[Voted into WP at October, 2009 meeting.]</P>



<P>Sections 3.3.3 [basic.scope.block] to 3.3.7 [basic.scope.class] define and summarize different kinds of scopes
in a C++ program.  However it is missing a description for the
scope of template parameters.  I believe a section is needed
there &#8212; even though some information may be found in clause
14.</P>

<P><B>Proposed resolution (September, 2009):</B></P>

<OL><LI><P>Insert the following as a new paragraph following
3.3.2 [basic.scope.pdecl] paragraph 8:</P></LI>

<BLOCKQUOTE>

The point of declaration of a template parameter is immediately after
its complete <I>template-parameter</I>. [<I>Example:</I>

<PRE>
  typedef unsigned char T;
  template&lt;class T
       = T         //<SPAN style="font-family:Times;font-style:italic"> Lookup finds the typedef name of </SPAN>unsigned char.
  
       , T         //<SPAN style="font-family:Times;font-style:italic">Lookup finds the template parameter.</SPAN>
           N = 0&gt; struct A {};
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<LI><P>Delete 14.1 [temp.param] paragraph 14:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A <I>template-parameter</I> shall not be used in its own default
argument.</SPAN>

</BLOCKQUOTE>

<I>[Drafting note: This change conflicts with the resolution for
<A HREF="
     cwg_defects.html#187">issue 187</A> but is in accord with widespread
implementation practice.]</I>

<LI><P>Insert the following as a new section following
3.3.8 [basic.scope.enum]:</P></LI>

<BLOCKQUOTE>

<P><B>Template Parameter Scope [basic.scope.temp]</B></P>

<P>The declarative region of the name of a template parameter of a
template <I>template-parameter</I> is the smallest
<I>template-parameter-list</I> in which the name was introduced.</P>

<P>The declarative region of the name of a template parameter of a
template is the smallest <I>template-declaration</I> in which the name was
introduced. Only template parameter names belong to this declarative
region; any other kind of name introduced by the <I>declaration</I> of a
<I>template-declaration</I> is instead introduced into the same declarative
region where it would be introduced as a result of a non-template
declaration of the same name. [<I>Example:</I></P>

<PRE>
  namespace N {
    template&lt;class T&gt; struct A{};               //<SPAN style="font-family:Times;font-style:italic"> line 2</SPAN>
    template&lt;class U&gt; void f(U){}               //<SPAN style="font-family:Times;font-style:italic"> line 3</SPAN>
    struct B {
      template&lt;class V&gt;friend int g(struct C*); //<SPAN style="font-family:Times;font-style:italic"> line 5</SPAN>
    };
  }
</PRE>

<P>The declarative regions of <TT>T</TT>, <TT>U</TT> and <TT>V</TT>
are the <I>template-declaration</I>s on lines 2, 3 and 5,
respectively. But the names <TT>A</TT>, <TT>f</TT>, <TT>g</TT> and
<TT>C</TT> all belong to the same declarative region&#8212;namely, the
<I>namespace-body</I> of <TT>N</TT>. (<TT>g</TT> is still considered
to belong to this declarative region in spite of its being hidden
during qualified and unqualified name lookup.) &#8212;<I>end
example</I>]</P>

<P>The potential scope of a template parameter name begins at its
point of declaration (3.3.2 [basic.scope.pdecl]) and ends at the end
of its declarative region. [<I>Note:</I> this implies that a
<I>template-parameter</I> can be used in the declaration of subsequent
<I>template-parameter</I>s and their default arguments but cannot be
used in preceding <I>template-parameter</I>s or their default
arguments. For example,</P>

<PRE>
  template&lt;class T, T* p, class U = T&gt; class X { /* ... */ }; 
  template&lt;class T&gt; void f(T* p = new T); 
</PRE>

<P>This also implies that a <I>template-parameter</I> can be used in the
specification of base classes. For example,</P>

<PRE>
  template&lt;class T&gt; class X : public Array&lt;T&gt; { /* ... */ }; 
  template&lt;class T&gt; class Y : public T { /* ... */ }; 
</PRE>

<P>The use of a template parameter as a base class implies that a
class used as a template argument must be defined and not just
declared when the class template is instantiated. &#8212;<I>end
note</I>]</P>

<P>The declarative region of the name of a template parameter is
nested within the immediately-enclosing declarative
region. [<I>Note:</I> as a result, a <I>template-parameter</I> hides
any entity with the same name in an enclosing scope
(3.3.10 [basic.scope.hiding]). [<I>Example:</I></P>

<PRE>
  typedef int N;
  template&lt;N X, typename N, template&lt;N Y&gt; class T&gt;
    struct A;
</PRE>

<P>Here, <TT>X</TT> is a non-type template parameter of type
<TT>int</TT> and <TT>Y</TT> is a non-type template parameter of the
same type as the second template parameter of
<TT>A</TT>. &#8212;<I>end example</I>] &#8212;<I>end note</I>]</P>

<P>[<I>Note:</I> because the name of a template parameter cannot be
redeclared within its potential scope (14.6.1 [temp.local]), a
template parameter's scope is often its potential scope. However, it
is still possible for a template parameter name to be hidden; see
14.6.1 [temp.local]. &#8212;<I>end note</I>]</P>

</BLOCKQUOTE>

<LI><P>Delete 14.1 [temp.param] paragraph 13, including the
example:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The scope of a <I>template-parameter</I> extends...</SPAN>

</BLOCKQUOTE>

<LI><P>Delete 14.6.1 [temp.local] paragraph 6, including the
note and example:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The scope of a <I>template-parameter</I> extends...</SPAN>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="642"></A><H4>642.
  
Definition and use of &#8220;block scope&#8221; and &#8220;local scope&#8221;
</H4><B>Section: </B>3.3.3&#160; [basic.scope.block]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>6 Aug 2007<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>The Standard uses the terms &#8220;block scope&#8221; and &#8220;local
scope&#8221; interchangeably, but the former is never formally
defined.  Would it be better to use only one term consistently?
&#8220;Block scope&#8221; seems to be more frequently used.</P>

<P><B>Notes from the October, 2007 meeting:</B></P>

<P>The CWG expressed a preference for the term &#8220;local
scope.&#8221;</P>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>Reevaluating the relative prevalence of the two terms
(including the fact that new uses of &#8220;block scope&#8221;
are being introduced, e.g., in both the lambda and thread-local
wording) led to CWG reversing its previous preference for
&#8220;local scope.&#8221;  The resolution will need to add a
definition of &#8220;block scope&#8221; and should change the
title of 3.3.3 [basic.scope.block].</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<OL><LI><P>Change 3.3.2 [basic.scope.pdecl] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

<P>[<I>Note:</I> a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">nonlocal</SPAN> name <SPAN style="font-weight:bold;background-color:#A0FFA0">from an outer
scope</SPAN> remains visible up to the point of declaration of the
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">local</SPAN> name that hides it. [<I>Example:</I></P>

<PRE>
  const int i = 2;
  { int i[i]; }
</PRE>

<P>declares a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">local</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">block-scope</SPAN> array of two
integers. &#8212;<I>end example</I>] &#8212;<I>end note</I>]</P>

</BLOCKQUOTE>

<LI><P>Change the section heading of 3.3.3 [basic.scope.block] from
&#8220;Local scope&#8221; to &#8220;Block scope.&#8221;</P></LI>

<LI><P>Change 3.3.3 [basic.scope.block] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

A name declared in a block (6.3 [stmt.block]) is local to that
block<SPAN style="font-weight:bold;background-color:#A0FFA0">; it has <I>block scope</I></SPAN>.  Its potential scope
begins at its point of declaration (3.3.2 [basic.scope.pdecl]) and
ends at the end of its <SPAN style="text-decoration:line-through;background-color:#FFA0A0">declarative region</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">block. A
variable declared at block scope is a <I>local variable</I></SPAN>.

</BLOCKQUOTE>

<LI><P>Change 3.3.3 [basic.scope.block] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

The name <SPAN style="text-decoration:line-through;background-color:#FFA0A0">in a <TT>catch</TT> exception-declaration</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">declared in an <I>exception-declaration</I></SPAN> is local to the
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">handler</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>handler</I></SPAN> and shall not be
redeclared in the outermost block of the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">handler</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>handler</I></SPAN>.

</BLOCKQUOTE>

<LI><P>Change 3.3.10 [basic.scope.hiding] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

In a member function definition, the declaration of a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">local</SPAN>
name <SPAN style="font-weight:bold;background-color:#A0FFA0">at block scope</SPAN> hides the declaration of a member of
the class with the same name...

</BLOCKQUOTE>

<LI><P>Change 3.5 [basic.link] paragraph 8 as follows:</P></LI>

<BLOCKQUOTE>

...Moreover, except as noted, a name declared <SPAN style="text-decoration:line-through;background-color:#FFA0A0">in a local</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">at block</SPAN> scope (3.3.3 [basic.scope.block]) has no
linkage...

</BLOCKQUOTE>

<LI><P>Change 3.6.3 [basic.start.term] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...For an object of array or class type, all subobjects of that object
are destroyed before any <SPAN style="text-decoration:line-through;background-color:#FFA0A0">local</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">block-scope</SPAN>
object with static storage duration initialized during the
construction of the subobjects is destroyed.

</BLOCKQUOTE>

<LI><P>Change 3.6.3 [basic.start.term] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

If a function contains a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">local</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">block-scope</SPAN>
object of static or thread storage duration that has been destroyed
and the function is called during the destruction of an object with
static or thread storage duration, the program has undefined behavior
if the flow of control passes through the definition of the previously
destroyed <SPAN style="text-decoration:line-through;background-color:#FFA0A0">local</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">block-scope</SPAN> object.  Likewise,
the behavior is undefined if the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">function-local</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">block-scope</SPAN> object is used indirectly (i.e., through a
pointer) after its destruction.

</BLOCKQUOTE>

<LI><P>Change 3.6.3 [basic.start.term] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

If the completion of the initialization of a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-local</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">non-block-scope</SPAN> object with static storage duration is
sequenced before a call to <TT>std::atexit</TT> (see
<TT>&lt;cstdlib&gt;</TT>, 18.5 [support.start.term]), the call to the
function passed to <TT>std::atexit</TT> is sequenced before the call
to the destructor for the object. If a call to <TT>std::atexit</TT> is
sequenced before the completion of the initialization of a
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-local</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">non-block-scope</SPAN> object with static
storage duration, the call to the destructor...

</BLOCKQUOTE>

<P><I>[Editorial note: the occurrences of &#8220;non-local&#8221;
in this change are removed by the proposed resolution for
<A HREF="
     cwg_defects.html#946">issue 946</A>.]</I></P>

<LI><P>Change 6.3 [stmt.block] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...A compound statement defines a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">local</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">block</SPAN>
scope (3.3 [basic.scope])...

</BLOCKQUOTE>

<LI><P>Change 6.4 [stmt.select] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...The substatement in a <I>selection-statement</I> (each
substatement, in the <TT>else</TT> form of the <TT>if</TT> statement)
implicitly defines a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">local</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">block</SPAN> scope
(3.3 [basic.scope])...

</BLOCKQUOTE>

<LI><P>Change 6.4 [stmt.select] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

If a condition can be syntactically resolved as either an expression
or the declaration of a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">local</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">block-scope</SPAN> name,
it is interpreted as a declaration.

</BLOCKQUOTE>

<LI><P>Change 6.5 [stmt.iter] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

The substatement in an <I>iteration-statement</I> implicitly defines a
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">local</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">block</SPAN> scope (3.3 [basic.scope])
which is entered and exited each time through the loop.

</BLOCKQUOTE>

<LI><P>Change 6.7 [stmt.dcl] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

...A program that jumps<SUP>84</SUP> from a point where a
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">local</SPAN> variable with automatic storage duration...

</BLOCKQUOTE>

<LI><P>Change 6.7 [stmt.dcl] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

The zero-initialization (8.5 [dcl.init]) of all
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">local</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">block-scope</SPAN> objects with static storage
duration (3.7.1 [basic.stc.static]) or thread storage duration
(3.7.2 [basic.stc.thread]) is performed before any other
initialization takes place. Constant initialization (3.6.2 [basic.start.init]) of a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">local</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">block-scope</SPAN> entity
with static storage duration, if applicable, is performed before its
block is first entered. An implementation is permitted to perform
early initialization of other <SPAN style="text-decoration:line-through;background-color:#FFA0A0">local</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">block-scope</SPAN>
objects...

</BLOCKQUOTE>

<LI><P>Change 6.7 [stmt.dcl] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

The destructor for a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">local</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">block-scope</SPAN> object
with static or thread storage duration will be executed if and only if
the variable was constructed.  [<I>Note:</I> 3.6.3 [basic.start.term] describes the order in which <SPAN style="text-decoration:line-through;background-color:#FFA0A0">local</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">block-scope</SPAN> objects with static and thread storage duration
are destroyed.  &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Change 8.4 [dcl.fct.def] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

In the <I>function-body</I>, a <I>function-local predefined
variable</I> denotes a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">local</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">block-scope</SPAN> object
of static storage duration that is implicitly defined (see
3.3.3 [basic.scope.block]).

</BLOCKQUOTE>

<LI><P>Change the example in 9.1 [class.name] paragraph 2 as
follows:</P></LI>

<PRE>
  ...
  void g() {
    struct s;      //<SPAN style="font-family:Times;font-style:italic"> hide global </SPAN>struct s
                   //<SPAN style="font-family:Times;font-style:italic"> with a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">local</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">block-scope</SPAN> declaration</SPAN>
  ...
</PRE>

<LI><P>Change the example in 9.1 [class.name] paragraph 3 as
follows:</P></LI>

<PRE>
  ...
  void g(int s) {
    struct s* p = new struct s;   //<SPAN style="font-family:Times;font-style:italic"> global </SPAN>s
    p-&gt;a = s;                     //<SPAN style="font-family:Times;font-style:italic"> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">local</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">parameter</SPAN> </SPAN>s
  }
</PRE>

</OL>

<BR><BR><HR><A NAME="490"></A><H4>490.
  
Name lookup in friend declarations
</H4><B>Section: </B>3.4.1&#160; [basic.lookup.unqual]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Ben Hutchings
 &#160;&#160;&#160;

 <B>Date: </B>7 Dec 2004<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>When 3.4.1 [basic.lookup.unqual] paragraph 10 says,</P>

<BLOCKQUOTE>

In a <TT>friend</TT> declaration naming a member function, a name used in
the function declarator and not part of a <I>template-argument</I> in a
<I>template-id</I> is first looked up in the scope of the member
function's class. If it is not found, or if the name is part of a
<I>template-argument</I> in a <I>template-id</I>, the look up is
as described for unqualified names in the definition of the class
granting friendship.

</BLOCKQUOTE>

<P>what does &#8220;in the scope of the member function's
class&#8221; mean?  Does it mean that only members of the class
and its base classes are considered?  Or does it mean that the
same lookup is to be performed as if the name appeared in the
member function's class?  Implementations vary in this regard.
For example:</P>

<PRE>
     struct s1;

     namespace ns {
         struct s1;
     }

     struct s2 {
         void f(s1 &amp;);
     };

     namespace ns {
         struct s3 {
             friend void s2::f(s1 &amp;);
         };
     }
</PRE>

<P>Microsoft Visual C++ and Comeau C++ resolve <TT>s1</TT> in the
friend declaration to <TT>ns::s1</TT> and issue an error, while
g++ resolves it to <TT>::s1</TT> and accepts the code.</P>

<P><B>Notes from the April, 2005 meeting:</B></P>

<P>The phrase &#8220;looked up in the scope of [a] class&#8221; occurs
frequently throughout the Standard and always refers to the member name
lookup described in 10.2 [class.member.lookup].  This is the first
interpretation mentioned above (&#8220;only members of the class and its
base classes&#8221;), resolving <TT>s1</TT> to <TT>ns::s1</TT>.  A
cross-reference to 10.2 [class.member.lookup] will be added to
3.4.1 [basic.lookup.unqual] paragraph 10 to make this clearer.</P>

<P>In discussing this question, the CWG noticed another problem: the
text quoted above applies to all <I>template-argument</I>s appearing in
the function declarator.  The intention of this rule, however, is that
only <I>template-argument</I>s in the <I>declarator-id</I> should
ignore the member function's class scope; <I>template-argument</I>s
used elsewhere in the function declarator should be treated like other
names.  For example:</P>

<PRE>
     template&lt;typename T&gt; struct S;
     struct A {
       typedef int T;
       void foo(S&lt;T&gt;);
     };
     template &lt;typename T&gt; struct B {
       friend void A::foo(S&lt;T&gt;);  //<SPAN style="font-family:Times;font-style:italic"> i.e., </SPAN>S&lt;A::T&gt;
     };
</PRE>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 3.4.1 [basic.lookup.unqual] paragraph 10 as follows:</P>

<BLOCKQUOTE>

<P>In a <TT>friend</TT> declaration naming a member function, a
name used in the function declarator and not part of a
<I>template-argument</I> in <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a <I>template-id</I></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">the <I>declarator-id</I></SPAN> is first looked up in the
scope of the member function's class <SPAN style="font-weight:bold;background-color:#A0FFA0">(10.2 [class.member.lookup])</SPAN>. If it is not found, or if the name is part
of a <I>template-argument</I> in <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a <I>template-id</I></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">the <I>declarator-id</I></SPAN>, the look up is as described
for unqualified names in the definition of the class granting
friendship. [<I>Example:</I></P>

<PRE>
    struct A {
      typedef int AT;
      void f1(AT);
      void f2(float);
<SPAN style="font-weight:bold;background-color:#A0FFA0">      template&lt;typename T&gt; void f3();</SPAN>
    };
    struct B {
<SPAN style="font-weight:bold;background-color:#A0FFA0">      typedef char AT;</SPAN>
      typedef float BT;
      friend void A::f1(AT);    //<SPAN style="font-family:Times;font-style:italic"> parameter type is </SPAN>A::AT
      friend void A::f2(BT);    //<SPAN style="font-family:Times;font-style:italic"> parameter type is </SPAN>B::BT
<SPAN style="font-weight:bold;background-color:#A0FFA0">      friend void A::f3&lt;AT&gt;();  //<SPAN style="font-family:Times;font-style:italic"> template argument is </SPAN>B::AT</SPAN>
    };
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="598"></A><H4>598.
  
Associated namespaces of overloaded functions and function templates
</H4><B>Section: </B>3.4.2&#160; [basic.lookup.argdep]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>27 September 2006<BR>


<P>[Voted into the WP at the March, 2009 meeting.]</P>

<P>The resolution of <A HREF="
     cwg_defects.html#33">issue 33</A> added the
following wording in 3.4.2 [basic.lookup.argdep]:</P>

<BLOCKQUOTE>

In addition, if the argument is the name or address of a set of
overloaded functions and/or function templates, its associated classes
and namespaces are the union of those associated with each of the
members of the set: the namespace in which the function or function
template is defined and the classes and namespaces associated with its
(non-dependent) parameter types and return type.

</BLOCKQUOTE>

<P>This wording is self-contradictory: although it claims that the
treatment of overload sets is intended to be &#8220;the union of those
associated with each of the members of the set,&#8221; it says that
the namespace of which each function or function template is a member
is to be considered an associated namespace.  That is different from
the case of a non-overloaded function argument; in that case, because
only the <I>type</I> of the argument is considered, the namespace of
which the function is a member is <I>not</I> an associated namespace.
This should be rectified so that overloaded and unoverloaded functions
really are treated the same.</P>

<P><B>Proposed resolution (June, 2008):</B></P>

<P>Change 3.4.2 [basic.lookup.argdep] paragraph 2 as follows:</P>

<BLOCKQUOTE>

...In addition, if the argument is the name or address of a set
of overloaded functions and/or function templates, its associated
classes and namespaces are the union of those associated with
each of the members of the set<SPAN style="text-decoration:line-through;background-color:#FFA0A0">: the namespace in which the
function or function template is defined and</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">, i.e.,</SPAN>
the classes and namespaces associated with its (non-dependent)
parameter types and return type.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="705"></A><H4>705.
  
Suppressing argument-dependent lookup via parentheses
</H4><B>Section: </B>3.4.2&#160; [basic.lookup.argdep]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>29 July, 2008<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>During the discussion of <A HREF="
     cwg_defects.html#704">issue 704</A>,
some people expressed a desire to reconsider whether parentheses
around the name of the function in a function call should suppress
argument-dependent lookup, on the basis that this is overly subtle
and not obvious.  Others pointed out that this technique is used
(both intentionally and inadvertently) in existing code and changing
the behavior could cause problems.</P>

<P>It was also observed that the normative text that specifies this
behavior is itself subtle, relying an a very precise interpretation
of the preposition used in 3.4.2 [basic.lookup.argdep] paragraph 1:</P>

<BLOCKQUOTE>

When an unqualified name is used as the <I>postfix-expression</I>
in a function call...

</BLOCKQUOTE>

<P>This is taken to mean that something like <TT>(f)(x)</TT>
is not subject to argument-dependent lookup because the name
<TT>f</TT> is used <I>in</I> but not <I>as</I> the
<I>postfix-expression</I>.  This could be confusing, especially
in light of the use of the term <I>postfix-expression</I> to
refer to the name inside the parentheses, not to the
parenthesized expression, in 13.3.1.1 [over.match.call]
paragraph 1.  If the decision is to preserve this effect of
a parenthesized name in a function call, the wording should
probably be revised to specify it more explicitly.</P>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>The CWG agreed that the suppression of argument-dependent
lookup by parentheses surrounding the <I>postfix-expression</I>
is widely known and used in the C++ community and must be
preserved.  The wording should be changed to make this
effect clearer.</P>

<P><B>Proposed resolution (September, 2008):</B></P>

<P>Change 3.4.2 [basic.lookup.argdep] paragraph 1 as follows:</P>

<BLOCKQUOTE>

When <SPAN style="text-decoration:line-through;background-color:#FFA0A0">an unqualified name is used as</SPAN> the
<I>postfix-expression</I> in a function call (<sectkion_ref ref="5.2.2">5.2.2 [expr.call]</sectkion_ref>) <SPAN style="font-weight:bold;background-color:#A0FFA0">is an <I>unqualified-id</I></SPAN>, other
namespaces not considered during the usual unqualified lookup
(3.4.1 [basic.lookup.unqual]) may be searched...

</BLOCKQUOTE>

<P><B>Proposed resolution (September, 2009):</B></P>

<P>Change 3.4.2 [basic.lookup.argdep] paragraph 1 as follows:</P>

<BLOCKQUOTE>

<P>When <SPAN style="text-decoration:line-through;background-color:#FFA0A0">an unqualified name is used as</SPAN> the
<I>postfix-expression</I> in a function call (5.2.2 [expr.call]) <SPAN style="font-weight:bold;background-color:#A0FFA0">is an <I>unqualified-id</I></SPAN>, other
namespaces not considered during the usual unqualified lookup
(3.4.1 [basic.lookup.unqual]) may be searched, and in those namespaces,
namespace- scope friend function declarations (11.3 [class.friend]) not otherwise visible may be found.  These modifications
to the search depend on the types of the arguments (and for template
template arguments, the namespace of the template argument).
<SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">    namespace N {
      struct S { };
      void f(S);
    }

    void g() {
      N::S s;
      f(s);      //<SPAN style="font-family:Times;font-style:italic"> calls </SPAN>N::f
      (f)(s);    //<SPAN style="font-family:Times;font-style:italic"> error: </SPAN>N::f<SPAN style="font-family:Times;font-style:italic"> not considered; parentheses prevent argument-dependent lookup</SPAN>
    }
</SPAN></PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1000"></A><H4>1000.
  
Mistaking member typedefs for constructors
</H4><B>Section: </B>3.4.3.1&#160; [class.qual]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>20 November, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>The recent addition to support inherited constructors changed
3.4.3.1 [class.qual] paragraph 2 to say that</P>

<BLOCKQUOTE>

if the name specified after the <I>nested-name-specifier</I> is
the same as the <I>identifier</I> or the
<I>simple-template-id</I>'s <I>template-name</I> in the last
component of the <I>nested-name-specifier</I>,

</BLOCKQUOTE>

<P>the <I>qualified-id</I> is considered to name a constructor.  This
causes problems for a common naming scheme used in some class libraries:</P>

<PRE>
  struct A {
    typedef int type;
  };
  struct B {
    typedef A type;
  };
  B::type::type t;
</PRE>

<P>This change causes this to name the <TT>A</TT> constructor instead
of the <TT>A::type</TT> typedef.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 3.4.3.1 [class.qual] paragraph 2 as follows:</P>

<BLOCKQUOTE>

<P>In a lookup in which the constructor is an acceptable lookup
result and the <I>nested-name-specifier</I> nominates a class
<TT>C</TT>:</P>

<UL><LI><P>if the name specified after the
<I>nested-name-specifier</I>, when looked up in <TT>C</TT>, is
the injected-class-name of <TT>C</TT> (Clause 9 [class]), or</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">in a <I>using-declaration</I> (7.3.3 [namespace.udecl]) that is a <I>member-declaration</I>,</SPAN> if the
name specified after the <I>nested-name-specifier</I> is the same
as the <I>identifier</I> or the <I>simple-template-id</I>'s
<I>template-name</I> in the last component of the
<I>nested-name-specifier</I>,</P></LI>

</UL>

<P>the name is instead considered to name the constructor of
class <TT>C</TT>...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="861"></A><H4>861.
  
Unintended ambiguity in inline namespace lookup
</H4><B>Section: </B>3.4.3.2&#160; [namespace.qual]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Michael Wong
 &#160;&#160;&#160;

 <B>Date: </B>7 April, 2009<BR>


<P>[Voted into WP at March, 2010 meeting as part of document N3079.]</P>

<P>The algorithm for namespace-qualified lookup is given in
3.4.3.2 [namespace.qual] paragraph 2:</P>

<BLOCKQUOTE>

Given <TT>X::m</TT> (where <TT>X</TT> is a user-declared namespace),
or given <TT>::m</TT> (where <TT>X</TT> is the global namespace), let
<TT>S</TT> be the set of all declarations of <TT>m</TT> in <TT>X</TT>
and in the transitive closure of all namespaces nominated by
<I>using-directive</I>s in <TT>X</TT> and its used namespaces, except that
<I>using-directive</I>s that nominate non-inline namespaces
(7.3.1 [namespace.def]) are ignored in any namespace, including
<TT>X</TT>, directly containing one or more declarations of
<TT>m</TT>.

</BLOCKQUOTE>

<P>Consider the following example:</P>

<PRE>
    namespace A {
        inline namespace B {
            namespace C {
                int i;
            }
            using namespace C;
        }
        int i;
    }

    int j = A::i;     // ambiguous
</PRE>

<P>The transitive closure includes <TT>B</TT> because it is
<TT>inline</TT>, and it includes <TT>C</TT> because there is
no declaration of <TT>i</TT> in <TT>B</TT>.  As a result,
<TT>A::i</TT> finds both the <TT>i</TT> declared in <TT>A</TT>
and the one declared in <TT>C</TT>, and the lookup is ambiguous.</P>

<P>This result is apparently unintended.</P>

<P><B>Proposed resolution (November, 2009):</B></P>

<OL><LI><P>Change 7.3.1 [namespace.def] paragraph 9 as follows:</P></LI>

<BLOCKQUOTE>

These properties are transitive: if a namespace <TT>N</TT> contains an
inline namespace <TT>M</TT>, which in turn contains an inline
namespace <TT>O</TT>, then the members of <TT>O</TT> can be used as
though they were members of <TT>M</TT> or <TT>N</TT>. <SPAN style="font-weight:bold;background-color:#A0FFA0">The
transitive closure of all inline namespaces in <TT>N</TT> is the
<I>inline namespace set</I> of <TT>N</TT>.</SPAN> The set of namespaces
consisting of the innermost non-inline namespace enclosing an inline
namespace <TT>O</TT>, together with any intervening inline namespaces,
is the <I>enclosing namespace set</I> of <TT>O</TT>.

</BLOCKQUOTE>

<LI><P>Insert a new paragraph before 3.4.3.2 [namespace.qual]
paragraph 2 and change the existing paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">For a namespace <TT>X</TT> and name <TT>m</TT>, the
namespace-qualified lookup set <TT>S(X,m)</TT> is defined as
follows: Let <TT>S'(X,m)</TT> be the set of all declarations of
<TT>m</TT> in <TT>X</TT> and the inline namespace set of
<TT>X</TT> (7.3.1 [namespace.def]). If <TT>S'(X,m)</TT> is
not empty, <TT>S(X,m)</TT> is <TT>S'(X,m)</TT>; otherwise,
<TT>S(X,m)</TT> is the union of <TT>S(N<SUB>i</SUB>,m)</TT> for
all non-inline namespaces <TT>N<SUB>i</SUB></TT> nominated by
<I>using-directive</I>s in <TT>X</TT> and its inline namespace
set.</SPAN></P>

<P>Given <TT>X::m</TT> (where <TT>X</TT> is a user-declared
namespace), or given <TT>::m</TT> (where <TT>X</TT> is the global
namespace), <SPAN style="text-decoration:line-through;background-color:#FFA0A0">let <TT>S</TT> be the set of all declarations of
<TT>m</TT> in <TT>X</TT> and in the transitive closure of all
namespaces nominated by <I>using-directive</I>s in <TT>X</TT> and
its used namespaces, except that <I>using-directive</I>s that
nominate non-inline namespaces (7.3.1 [namespace.def]) are
ignored in any namespace, including <TT>X</TT>, directly
containing one or more declarations of <TT>m</TT>.  No namespace
is searched more than once in the lookup of a name.  If</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">if</SPAN> <TT>S<SPAN style="font-weight:bold;background-color:#A0FFA0">(X,m)</SPAN></TT> is the empty set, the
program is ill-formed. Otherwise, if <TT>S<SPAN style="font-weight:bold;background-color:#A0FFA0">(X,m)</SPAN></TT>
has exactly one member, or if the context of the reference is a
<I>using-declaration</I> (7.3.3 [namespace.udecl]),
<TT>S<SPAN style="font-weight:bold;background-color:#A0FFA0">(X,m)</SPAN></TT> is the required set of declarations of
<TT>m</TT>. Otherwise if the use of <TT>m</TT> is not one that
allows a unique declaration to be chosen from
<TT>S<SPAN style="font-weight:bold;background-color:#A0FFA0">(X,m)</SPAN></TT>, the program is
ill-formed. [<I>Example:</I>...</P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="527"></A><H4>527.
  
Problems with linkage of types
</H4><B>Section: </B>3.5&#160; [basic.link]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>28 July 2005<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>The resolution of <A HREF="
     cwg_defects.html#389">issue 389</A> makes code
like</P>

<PRE>
    static struct {
        int i;
        int j;
    } X;
</PRE>

<P>ill-formed.  This breaks a lot of code for no apparent reason,
since the name <TT>X</TT> is not known outside the translation
unit in which it appears; there is therefore no danger of collision
and no need to mangle its name.</P>

<P>There has also been recent discussion on the email reflectors as to
whether the restrictions preventing use of types without linkage as
template arguments is needed or not, with the suggestion that a
mechanism like that used to give members of the unnamed namespace
unique names could be used for unnamed and local types.
 See also <A HREF="
     cwg_defects.html#488">issue 488</A>, which would become moot if types without linkage could be
used as template parameters.
</P>

<P><B>Notes from the October, 2005 meeting:</B></P>

<P>The Evolution Working Group is discussing changes that would
address this issue.  CWG will defer consideration until the outcome
of the EWG discussions is clear.</P>

<P><B>Notes from the April, 2006 meeting:</B></P>

<P>The CWG agreed that the restriction in 3.5 [basic.link]
paragraph 8 on use of a type without linkage should apply only to
variables and functions with external linkage, not to variables and
functions with internal linkage (i.e., the example should be
accepted).  This is a separate issue from the question before the EWG
and should be resolved independently.</P>

<P><B>Additional note (April, 2006):</B></P>

<P>Even the restriction of the rule to functions and objects with
external linkage may not be exactly what we want.  Consider an example
like:</P>

<PRE>
    namespace {
        struct { int i; } s;
    }
</PRE>

<P>The variable <TT>s</TT> has external linkage but can't be named
outside its translation unit, so there's again no reason to prohibit
use of a type without linkage in its declaration.</P>

<P><B>Notes from the June, 2008 meeting:</B></P>

<P>Paper N2657, adopted at the June, 2008 meeting, allows local and
unnamed types to be used as template parameters.  That resolution
is narrowly focused, however, and does not address this issue.</P>

<P><B>Proposed resolution (June, 2009):</B></P>

<P>Change 3.5 [basic.link] paragraph 8 as follows:</P>

<BLOCKQUOTE>

<P>...A type without linkage shall not be used as the type of a
variable or function with <SPAN style="font-weight:bold;background-color:#A0FFA0">external</SPAN> linkage, unless</P>

<UL><LI><P>the variable or function has <SPAN style="text-decoration:line-through;background-color:#FFA0A0">extern "C"</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">C
language</SPAN> linkage (7.5 [dcl.link]), or</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">the variable or function is declared within an
unnamed namespace (7.3.1 [namespace.def]), or</SPAN></P></LI>

<LI><P>the variable or function is not used (3.2 [basic.def.odr])
or is defined in the same translation unit.</P></LI>

</UL>

</BLOCKQUOTE>

<P><I>[Drafting note: the context shown for the preceding resolution
assumes that the resolution for <A HREF="
     cwg_defects.html#757">issue 757</A>
has been applied.]</I></P>

<BR><BR><HR><A NAME="571"></A><H4>571.
  
References declared <TT>const</TT>
</H4><B>Section: </B>3.5&#160; [basic.link]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Dave Abrahams
 &#160;&#160;&#160;

 <B>Date: </B>31 March 2006<BR>


<P>[Voted into the WP at the March, 2009 meeting.]</P>



<P>According to 3.5 [basic.link] paragraph 3,</P>

<BLOCKQUOTE>

<P>A name having namespace scope (3.3.6 [basic.scope.namespace]) has
internal linkage if it is the name of</P>

<UL>
<LI><P>an object, reference, function or function template that is
explicitly declared <TT>static</TT> or,</P></LI>

<LI><P>an object or reference that is explicitly
declared <TT>const</TT> and neither explicitly
declared <TT>extern</TT> nor previously declared to have external
linkage;</P></LI>

</UL>

</BLOCKQUOTE>

<P>It is not possible to declare a reference to be <TT>const</TT>.</P>

<P><B>Proposed resolution (March, 2008):</B></P>

<P>Change 3.5 [basic.link] paragraph 3 as indicated (note
addition of punctuation in the first bullet):</P>

<BLOCKQUOTE>

<P>A name having namespace scope (3.3.6 [basic.scope.namespace]) has
internal linkage if it is the name of</P>

<UL>
<LI><P>an object, reference, function<SPAN style="font-weight:bold;background-color:#A0FFA0">,</SPAN> or function
template that is explicitly declared <TT>static</TT><SPAN style="font-weight:bold;background-color:#A0FFA0">;</SPAN>
or,</P></LI>

<LI><P>an object <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or reference</SPAN> that is explicitly declared
<TT>const</TT> and neither explicitly declared <TT>extern</TT>
nor previously declared to have external linkage; or</P></LI>

<LI><P>a data member of an anonymous union.</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="757"></A><H4>757.
  
Types without linkage in declarations
</H4><B>Section: </B>3.5&#160; [basic.link]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>23 December, 2008<BR>


<P>[Voted into WP at July, 2009 meeting.]</P>



<P>Paper N2657, adopted at the June, 2008 meeting, removed the prohibition
of local and unnamed types as template arguments.  As part of the change,
3.5 [basic.link] paragraph 8 was modified to read,</P>

<BLOCKQUOTE>

<P>A type without linkage shall not be used as the type of a variable or function with linkage, unless</P>

<UL>
<LI><P>the variable or function has extern "C" linkage (7.5 [dcl.link]), or</P></LI>

<LI><P>the type without linkage was named using a dependent type
(14.6.2.1 [temp.dep.type]).</P></LI>

</UL>

</BLOCKQUOTE>

<P>Because a type without linkage can only be named as a dependent type,
there are still some potentially useful things that cannot be done:</P>

<PRE>
    template &lt;class T&gt; struct A {
      friend void g(A, T);  // this can't be defined later
      void h(T);  // this cannot be explicitly specialized
    };

    template &lt;class T&gt; void f(T) {
      A&lt;T&gt; at;
      g(at, (T)0);
    }

    enum { e };

    void g(A&lt;decltype(e)&gt;, decltype(e)){}  // not allowed

    int main() {
      f(e);
    }
</PRE>

<P>These deficiencies could be addressed by allowing types without
linkage to be used as the type of a variable or function, but with
the requirement that any such entity that is used must also be
defined in the same translation unit.  This would allow issuing a
compile-time, instead of a link-time, diagnostic if the definition
were not provided, for example.  It also seems to be easier to
implement than the current rules.</P>

<P><B>Proposed resolution (March, 2009):</B></P>

<P>Change 3.5 [basic.link] paragraph 8 as follows:</P>

<BLOCKQUOTE>

<P>...A type without linkage shall not be used as the type of a variable
or function with linkage, unless</P>

<UL>
<LI><P>the variable or function has extern "C" linkage (7.5 [dcl.link]), or</P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">the type without linkage was named using a dependent type
(14.6.2.1 [temp.dep.type])</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">the variable or function is not
used (3.2 [basic.def.odr]) or is defined in the same translation
unit</SPAN>.</P></LI>

</UL>

<P>[<I>Note:</I> in other words, a type without linkage contains a class or
enumeration that cannot be named outside its translation unit. An
entity with external linkage declared using such a type could not
correspond to any other entity in another translation unit of the
program and thus <SPAN style="text-decoration:line-through;background-color:#FFA0A0">is not permitted</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">must be defined in the
translation unit if it is used</SPAN>.  Also note that classes with
linkage may contain members whose types do not have linkage, and that
typedef names are ignored in the determination of whether a type has
linkage. &#8212;<I>end note</I>] [<I>Example:</I></P>

<PRE>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">    void f() {
      struct A { int x; };    //<SPAN style="font-family:Times;font-style:italic"> no linkage</SPAN>
      extern A a;             //<SPAN style="font-family:Times;font-style:italic"> ill-formed</SPAN>
      typedef A B;
      extern B b;             //<SPAN style="font-family:Times;font-style:italic"> ill-formed</SPAN>
    }
</SPAN></PRE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">&#8212;<I>end example</I>]</SPAN></P>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">[<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">    template &lt;class T&gt; struct A {
      //<SPAN style="font-family:Times;font-style:italic"> in </SPAN>A&lt;X&gt;<SPAN style="font-family:Times;font-style:italic">, the following is allowed because the type with no linkage</SPAN>
      //<SPAN style="font-family:Times;font-style:italic"> </SPAN>X<SPAN style="font-family:Times;font-style:italic"> is named using template parameter </SPAN>T.
      friend void f(A, T){}
    };

    template &lt;class T&gt; void g(T t) {
      A&lt;T&gt; at;
      f(at, t);
    }

    int main() {
      class X {} x;
      g(x);
    }
</SPAN></PRE>

<PRE><SPAN style="font-weight:bold;background-color:#A0FFA0">
    template &lt;typename T&gt; struct B {
        void g(T){}
        void h(T);
        friend void i(B, T){}
    };

    void f() {
        struct A { int x; };  //<SPAN style="font-family:Times;font-style:italic"> no linkage</SPAN>
        A a = {1};
        B&lt;A&gt; ba;              //<SPAN style="font-family:Times;font-style:italic"> declares </SPAN>B&lt;A&gt;::g(A)<SPAN style="font-family:Times;font-style:italic"> and </SPAN>B&lt;A&gt;::h(A)
        ba.g(a);              //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
        ba.h(a);              //<SPAN style="font-family:Times;font-style:italic"> error: </SPAN>B&lt;A&gt;::h(A)<SPAN style="font-family:Times;font-style:italic"> not defined in the translation unit</SPAN>
        i(ba, a);             //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
    }
</SPAN></PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<P><I>[Drafting note: <A HREF="
     cwg_defects.html#527">issue 527</A> also
changes part of the same text.]</I></P>

<BR><BR><HR><A NAME="966"></A><H4>966.
  
Nested types without linkage
</H4><B>Section: </B>3.5&#160; [basic.link]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>15 September, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>The recent changes to allow use of unnamed types as template
arguments require some rethinking of how unnamed types are treated
in general.  At least, a class-scope unnamed type should have the
same linkage as its containing class.  For example:</P>

<PRE>
    //<SPAN style="font-family:Times;font-style:italic"> File "hdr.h"</SPAN>
    struct S {
      static enum { No, Yes } locked;
    };
    template&lt;class T&gt; void f(T);

    //<SPAN style="font-family:Times;font-style:italic"> File "impl1.c"</SPAN>
    #include "hdr.h"
    template void f(decltype(S::locked));

    //<SPAN style="font-family:Times;font-style:italic"> File "impl2.c"</SPAN>
    #include "hdr.h"
    template void f(decltype(S::locked));
</PRE>

<P>The two explicit instantiation directives should refer to the
same specialization.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 3.5 [basic.link] paragraph 8 as follows:</P>

<BLOCKQUOTE>

<P>Names not covered by these rules have no linkage.  Moreover,
except as noted, a name declared in a local scope (3.3.3 [basic.scope.block]) has no linkage. A type is said to have linkage if
and only if:</P>

<UL><LI><P>it is a class or enumeration type that is named (or
has a name for linkage purposes (7.1.3 [dcl.typedef])) and
the name has linkage; or</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">it is an unnamed class or enumeration member of a class
with linkage; or</SPAN></P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="792"></A><H4>792.
  
Effects of <TT>std::quick_exit</TT>
</H4><B>Section: </B>3.6.1&#160; [basic.start.main]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#US24">N2800 comment
  US&#160;24<BR></A>

<P>[Voted into WP at October, 2009 meeting.]</P>

<P>3.6.1 [basic.start.main] paragraph 4 discusses the effects of calling
<TT>std::exit</TT> but says nothing about <TT>std::quick_exit</TT>.
</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 3.6.1 [basic.start.main] paragraph 4 as follows:</P>

<BLOCKUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Calling the function <TT>std::exit(int)</TT> declared in
<TT>&lt;cstdlib&gt;</TT> (18.5 [support.start.term]) terminates</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">Terminating</SPAN> the program without leaving the current block
<SPAN style="font-weight:bold;background-color:#A0FFA0">(e.g., by calling the function <TT>std::exit(int)</TT>
(18.5 [support.start.term]))</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">and hence without
destroying</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">does not destroy</SPAN> any objects with
automatic storage duration (12.4 [class.dtor])...

</BLOCKUOTE>

<BR><BR><HR><A NAME="882"></A><H4>882.
  
Defining <TT>main</TT> as deleted
</H4><B>Section: </B>3.6.1&#160; [basic.start.main]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>27 April, 2009<BR>


<P>It should be stated in 3.6.1 [basic.start.main] that it a program
that defines <TT>main</TT> as deleted is ill-formed.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 3.6.1 [basic.start.main] paragraph 3 as follows:</P>

<BLOCKQUOTE>

...A program that declares <TT>main</TT> to be <TT>inline</TT>,
<TT>static</TT>, or <TT>constexpr</TT><SPAN style="font-weight:bold;background-color:#A0FFA0">, or that defines
<TT>main</TT> as deleted,</SPAN> is ill-formed...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="776"></A><H4>776.
  
Delegating constructors, destructors, and <TT>std::exit</TT>
</H4><B>Section: </B>3.6.3&#160; [basic.start.term]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Michael Wong
 &#160;&#160;&#160;

 <B>Date: </B>12 February, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>According to 3.6.3 [basic.start.term] paragraph 1,</P>

<BLOCKQUOTE>

Destructors (12.4 [class.dtor]) for initialized objects with
static storage duration are called as a result of returning from
<TT>main</TT> and as a result of calling <TT>std::exit</TT>
(18.5 [support.start.term]).

</BLOCKQUOTE>

<P>It is unclear, in the presence of delegating constructors, exactly
what an &#8220;initialized object&#8221; is. 3.8 [basic.life]
paragraph 1 says that the lifetime of an object does not begin until
it is completely initialized, i.e., when its principal constructor
finishes execution. 15.2 [except.ctor] paragraph 2 says that an
exception during the construction of class object only invokes
destructors for fully-constructed base and member sub-objects (those
for which the principal constructor has completed). On the other hand,
the destructor for a complete class object is called if its
non-delegating constructor has completed, even if the principal
constructor has not yet finished. Which of these models is appropriate
for the behavior of <TT>std::exit</TT>?</P>

<P><B>Notes from the March, 2009 meeting:</B></P>

<P>The CWG agreed that the destructor for a complete object should
be called by <TT>std::exit</TT> if its non-delegating constructor
has finished, just as for an exception.</P>

<P><B>Notes from the July, 2009 meeting:</B></P>

<P>The CWG decided that the direction adopted at the March, 2009
meeting was incorrect. Instead, the model should be the way
completely-constructed base and member subobjects are handled:
their destructors are called when an exception is thrown but not
when <TT>std::exit</TT> is called.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 3.6.3 [basic.start.term] paragraph 1 as follows:</P>

<BLOCKQUOTE>

Destructors (12.4 [class.dtor]) for initialized objects
<SPAN style="font-weight:bold;background-color:#A0FFA0">(that is, objects whose lifetime (3.8 [basic.life]) has
begun)</SPAN> with static storage duration are called as a result of
returning from main and as a result of calling <TT>std::exit</TT>
(18.5 [support.start.term]).  Destructors for initialized objects with
thread storage duration...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="946"></A><H4>946.
  
Order of destruction of local static objects and calls to <TT>std::atexit</TT>
</H4><B>Section: </B>3.6.3&#160; [basic.start.term]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Fraser Ross
 &#160;&#160;&#160;

 <B>Date: </B>28 July, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>18.5 [support.start.term] paragraph 7 says that the order of
destruction of objects with static storage duration and calls to
functions registered by calling <TT>std::atexit</TT> is given in
3.6.3 [basic.start.term].  Paragraph 1 of 3.6.3 [basic.start.term]
says,</P>

<BLOCKQUOTE>

If the completion of the constructor or dynamic initialization of an
object with static storage duration is sequenced before that of
another, the completion of the destructor of the second is sequenced
before the initiation of the destructor of the first.

</BLOCKQUOTE>

<P>This wording covers both local and namespace-scope objects, so it
fixes the relative ordering of local object destructors with respect
to those of namespace scope.  Paragraph 3 says,</P>

<BLOCKQUOTE>

If the completion of the initialization of a non-local object with
static storage duration is sequenced before a call to
<TT>std::atexit</TT> (see <TT>&lt;cstdlib&gt;</TT>, 18.5 [support.start.term]), the call to the function passed to <TT>std::atexit</TT> is
sequenced before the call to the destructor for the object. If a call
to <TT>std::atexit</TT> is sequenced before the completion of the
initialization of a non-local object with static storage duration, the
call to the destructor for the object is sequenced before the call to
the function passed to <TT>std::atexit</TT>.

</BLOCKQUOTE>

<P>This fixes the relative ordering of destructors for namespace
scope objects with respect to calls of <TT>atexit</TT> functions.
However, the relative ordering of local destructors and
<TT>atexit</TT> functions is left unspecified.</P>

<P>In the 2003 Standard, this was clear: 18.3 paragraph 8 said,</P>

<BLOCKQUOTE>

A local static object <TT>obj3</TT> is destroyed at the same time it
would be if a function calling the <TT>obj3</TT> destructor were
registered with <TT>atexit</TT> at the completion of the <TT>obj3</TT>
constructor.

</BLOCKQUOTE>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 3.6.3 [basic.start.term] paragraph 3 as follows:</P>

<BLOCKQUOTE>

If the completion of the initialization of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a non-local</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">an</SPAN> object with static storage duration is sequenced before
a call to <TT>std::atexit</TT> (see <TT>&lt;cstdlib&gt;</TT>,
18.5 [support.start.term]), the call to the function passed to
<TT>std::atexit</TT> is sequenced before the call to the destructor
for the object. If a call to <TT>std::atexit</TT> is sequenced before
the completion of the initialization of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a non-local</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">an</SPAN> object with static storage duration, the call to the
destructor for the object is sequenced before the call to the function
passed to <TT>std::atexit</TT>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="735"></A><H4>735.
  
Missing case in specification of safely-derived pointers
</H4><B>Section: </B>3.7.4.3&#160; [basic.stc.dynamic.safety]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Jens Maurer
 &#160;&#160;&#160;

 <B>Date: </B>14 October, 2008<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#DE3">N2800 comment
  DE&#160;3<BR></A>

<P>[Voted into WP at October, 2009 meeting.]</P>

<P>The bullets in 3.7.4.3 [basic.stc.dynamic.safety] paragraph 2 do not
appear to cover the following example:</P>

<PRE>
   int&amp; i = *new int(5);
   // do something with i
   delete &amp;i;
</PRE>

<P>Should <TT>&amp;i</TT> be a safely-derived pointer value?</P>

<P><B>Proposed resolution (September, 2009):</B></P>

<P>Change 3.7.4.3 [basic.stc.dynamic.safety] paragraph 2, bullet 2, as follows:</P>

<UL><LI>the result of taking the address of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a subobject of an
lvalue</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an object (or one of its subobjects) designated by
an lvalue</SPAN> resulting from dereferencing a safely-derived pointer
value;</LI></UL>

<BR><BR><HR><A NAME="853"></A><H4>853.
  
Support for relaxed pointer safety
</H4><B>Section: </B>3.7.4.3&#160; [basic.stc.dynamic.safety]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Jens Maurer
 &#160;&#160;&#160;

 <B>Date: </B>3 April, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>According to 20.8.4 [util.dynamic.safety] paragraph 16,
when <TT>std::get_pointer_safety()</TT> returns
<TT>std::pointer_safety::relaxed</TT>,</P>

<BLOCKQUOTE>

pointers that are not safely derived will be treated the same as
pointers that are safely derived for the duration of the program.

</BLOCKQUOTE>

<P>However, 3.7.4.3 [basic.stc.dynamic.safety] paragraph 4 says
unconditionally that</P>

<BLOCKQUOTE>

If a pointer value that is not a safely-derived pointer value is
dereferenced or deallocated, and the referenced complete object is of
dynamic storage duration and has not previously been declared
reachable (20.8.4 [util.dynamic.safety]), the behavior is undefined.

</BLOCKQUOTE>

<P>This is a contradiction: the library clause attempts to constrain
undefined behavior, which by definition is unconstrained.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 3.7.4.3 [basic.stc.dynamic.safety] paragraph 4 as follows to
define the terms &#8220;strict pointer safety&#8221; and
&#8220;relaxed pointer safety,&#8221; which could then be used by
the library clauses to achieve the desired effect:</P>

<BLOCKQUOTE>

<SPAN style="font-weight:bold;background-color:#A0FFA0">An implementation may have <I>relaxed pointer safety</I>, in which
case the validity of a pointer value does not depend on whether it is
a safely-derived pointer value or not.  Alternatively, an
implementation may have <I>strict pointer safety</I>, in which case
if</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">If</SPAN> a pointer value that is not a safely-derived pointer
value is dereferenced or deallocated, and the referenced complete
object is of dynamic storage duration and has not previously been
declared reachable (20.8.4 [util.dynamic.safety]), the behavior is
undefined.  [<I>Note:</I> this is true even if the unsafely-derived
pointer value might compare equal to some safely-derived pointer
value. &#8212;<I>end note</I>] <SPAN style="font-weight:bold;background-color:#A0FFA0">It is implementation-defined whether
an implementation has relaxed or strict pointer safety.</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="793"></A><H4>793.
  
Use of class members during destruction
</H4><B>Section: </B>3.8&#160; [basic.life]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#US26">N2800 comment
  US&#160;26<BR></A>

<P>[Voted into WP at March, 2010 meeting.]</P>

<P>Read literally, 3.8 [basic.life] paragraphs 1 and 5 would
make any access to non-static members of a class from the class's
destructor undefined behavior. This is clearly not the intent.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 3.8 [basic.life] paragraphs 5-6 as follows:</P>

<BLOCKQUOTE>

<P>...any pointer that refers to the storage location where the object
will be or was located may be used but only in limited ways.
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Such</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">For an object under construction or destruction,
see 12.7 [class.cdtor]. Otherwise, such</SPAN> a pointer refers
to allocated storage...</P>

<P>...any lvalue which refers to the original object may be used but
only in limited ways.  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">Such</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">For an object under
construction or destruction, see 12.7 [class.cdtor]. Otherwise,
such</SPAN> an lvalue refers to allocated storage...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="883"></A><H4>883.
  
<TT>std::memcpy</TT> vs <TT>std::memmove</TT>
</H4><B>Section: </B>3.9&#160; [basic.types]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Lawrence Crowl
 &#160;&#160;&#160;

 <B>Date: </B>29 April, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>The <TT>std::memcpy</TT> library function is singled out for
special treatment in 3.9 [basic.types] paragraph 3:</P>

<BLOCKQUOTE>

For any trivially copyable type <TT>T</TT>, if two pointers to
<TT>T</TT> point to distinct <TT>T</TT> objects <TT>obj1</TT> and
<TT>obj2</TT>, where neither <TT>obj1</TT> nor <TT>obj2</TT> is a
base-class subobject, if the value of <TT>obj1</TT> is copied into
<TT>obj2</TT>, using the <TT>std::memcpy</TT> library function,
<TT>obj2</TT> shall subsequently hold the same value as <TT>obj1</TT>.

</BLOCKQUOTE>

<P>This specification should not be restricted to <TT>std::memcpy</TT>
but should apply to any bytewise copying, including
<TT>std::memmove</TT> (as is done in the footnote in the preceding
paragraph, for example).</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 3.9 [basic.types] paragraph 3 as follows:</P>

<BLOCKQUOTE>

For any trivially copyable type <TT>T</TT>, if two pointers to
<TT>T</TT> point to distinct <TT>T</TT> objects <TT>obj1</TT> and
<TT>obj2</TT>, where neither <TT>obj1</TT> nor <TT>obj2</TT> is a
base-class subobject, if the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">value of</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">underlying bytes
(1.7 [intro.memory]) making up</SPAN> <TT>obj1</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">is</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">are</SPAN> copied into <TT>obj2</TT><SPAN style="text-decoration:line-through;background-color:#FFA0A0">, using the
<TT>std::memcpy</TT> library function</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Footnote</I>: By
using, for example, the library functions (17.6.1.2 [headers]) <TT>std::memcpy</TT> or <TT>std::memmove</TT>.
&#8212;<I>end footnote</I>]</SPAN>, <TT>obj2</TT> shall subsequently
hold the same value as <TT>obj1</TT>. [<I>Example:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="846"></A><H4>846.
  
Rvalue references to functions
</H4><B>Section: </B>3.10&#160; [basic.lval]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>23 March, 2009<BR>


<P>[Voted into WP at March, 2010 meeting as document N3055.]</P>

<P>The status of rvalue references to functions is not clear in the
current wording.  For example, 3.10 [basic.lval] paragraph 2
says,</P>

<BLOCKQUOTE>

An lvalue refers to an object or function. Some rvalue
expressions&#8212;those of (possibly cv-qualified) class or array
type&#8212;also refer to objects. [<I>Footnote:</I> Expressions such
as invocations of constructors and of functions that return a class
type refer to objects, and the implementation can invoke a member
function upon such objects, but the expressions are not lvalues.
&#8212;<I>end footnote</I>]

</BLOCKQUOTE>

<P>This would tend to indicate that there are no rvalues of function
type.  However, 5 [expr] paragraph 6 says,</P>

<BLOCKQUOTE>

If an expression initially has the type &#8220;rvalue reference to
T&#8221; (8.3.2 [dcl.ref], 8.5.3 [dcl.init.ref]), the
type is adjusted to &#8220;T&#8221; prior to any further analysis, and
the expression designates the object or function denoted by the rvalue
reference.  If the expression is the result of calling a function,
whether implicitly or explicitly, it is an rvalue; otherwise, it is an
lvalue.

</BLOCKQUOTE>

<P>This explicitly indicates that rvalue references to functions are
possible and that, in some cases, they yield function-typed rvalues.
Furthermore, _N2914_.20.2.4 [concept.operator] paragraph 20 describes the
concept <TT>Callable</TT> as:</P>

<PRE>
    auto concept Callable&lt;typename F, typename... Args&gt; {
      typename result_type;
      result_type operator()(F&amp;, Args...);
      result_type operator()(F&amp;&amp;, Args...);
    }
</PRE>

<P>It would be strange if <TT>Callable</TT> were satisfied for a
function object type but not for a function type.</P>

<P>However, assuming that rvalue references to functions are
intended to be supported, it is not clear how an rvalue of function
type is supposed to behave.  For instance, <sectioin_ref ref="5.2.2">5.2.2 [expr.call]</sectioin_ref>
paragraph 1 says,</P>

<BLOCKQUOTE>

For an ordinary function call, the postfix expression shall be either
an lvalue that refers to a function (in which case the
function-to-pointer standard conversion (4.3 [conv.func]) is
suppressed on the postfix expression), or it shall have pointer to
function type.

</BLOCKQUOTE>

<P>From this, it appears that an rvalue of function type cannot be
used in a function call.  It can't be converted to a pointer to
function, either, as 4.3 [conv.func] paragraph 1 says,</P>

<BLOCKQUOTE>

An lvalue of function type <TT>T</TT> can be converted to an rvalue of
type &#8220;pointer to <TT>T</TT>.&#8221; The result is a pointer to
the function.

</BLOCKQUOTE>

<P>(See also issues <A HREF="
     cwg_defects.html#664">664</A> and especially
<A HREF="
     cwg_defects.html#690">690</A>.  The approach described in the latter
issue, viewing rvalue references as essentially lvalues rather than
as essentially rvalues, could resolve the specification problems
described above by eliminating the concept of an rvalue of function
type.)</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>See paper N3030.</P>

<BR><BR><HR><A NAME="693"></A><H4>693.
  
New string types and deprecated conversion
</H4><B>Section: </B>4.2&#160; [conv.array]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>21 April, 2008<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#DE4">N2800 comment
  DE&#160;4<BR></A>

<P>[Voted into WP at October, 2009 meeting.]</P>



<P>The deprecated conversion from string literal to pointer to
(non-const) character in 4.2 [conv.array] paragraph 2
has been extended to apply to <TT>char16_t</TT> and
<TT>char32_t</TT> types, but not to UTF8 and raw string
literals.  Is this disparity intentional?  Should it be
extended to all new string types, reverted to just the original
character types, or revoked altogether?</P>

<P>Additional places in the Standard that may need to change
include 15.1 [except.throw] paragraph 3 and
13.3.3.2 [over.ics.rank] paragraph 3.</P>

<P><B>Additional discussion (August, 2008):</B></P>



<P>The removal of this conversion for current string literals
would affect overload resolution for existing programs.  For
example,</P>

<PRE>
    struct S {
        S(const char*);
    };
    int f(char *);
    int f(X);
    int i = f("hello");
</PRE>

<P>If the conversion were removed, the result would be a quiet
change in behavior.  Another alternative to consider would be a
required diagnostic (without making the program ill-formed).</P>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>The CWG agreed that the deprecated conversion should continue
to apply to the literals to which it applied in C++ 2003.  Consensus
was not reached regarding whether it should apply only to those
literals or to all the new literals as well, although it was agreed
that the current situation in which it applies to some, but not all,
of the new literals is unacceptable.</P>

<P><B>Notes from the July, 2009 meeting:</B></P>

<P>The CWG reached consensus that the deprecated conversion should
be removed altogether.</P>

<P><B>Proposed resolution (September, 2009):</B></P>

<OL><LI><P>Remove 4.2 [conv.array] paragraph 2:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A string literal (2.14.5 [lex.string]) with no prefix, with a
<TT>u</TT> prefix, with a <TT>U</TT> prefix, or with an <TT>L</TT>
prefix can be converted to an rvalue of type &#8220;pointer to
<TT>char</TT>&#8221;, &#8220;pointer to <TT>char16_t</TT>&#8221;,
&#8220;pointer to <TT>char32_t</TT>&#8221;, or &#8220;pointer to
<TT>wchar_t</TT>&#8221;, respectively. In any case, the result is a
pointer to the first element of the array. This conversion is
considered only when there is an explicit appropriate pointer target
type, and not when there is a general need to convert from an lvalue
to an rvalue. [<I>Note:</I> this conversion is deprecated.  See Annex
D [depr].  &#8212;<I>end note</I>] For the purpose of
ranking in overload resolution (13.3.3.1.1 [over.ics.scs]), this
conversion is considered an array-to-pointer conversion followed by a
qualification conversion (4.4 [conv.qual]).  [<I>Example:</I>
<TT>"abc"</TT> is converted to &#8220;pointer to <TT>const
char</TT>&#8221; as an array-to-pointer conversion, and then to
&#8220;pointer to <TT>char</TT>&#8221; as a qualification conversion.
&#8212;<I>end example</I>]</SPAN>

</BLOCKQUOTE>

<LI><P>Delete the indicated text from the third sub-bullet of the
first bullet of paragraph 3 of 13.3.3.2 [over.ics.rank]:</P></LI>

<UL><LI><P><TT>S1</TT> and <TT>S2</TT> differ only in their
qualification conversion and yield similar types <TT>T1</TT> and
<TT>T2</TT> (4.4 [conv.qual]), respectively, and the
cv-qualification signature of type <TT>T1</TT> is a proper subset of
the cv-qualification signature of type <TT>T2</TT><SPAN style="text-decoration:line-through;background-color:#FFA0A0">, and <TT>S1</TT>
is not the deprecated string literal array-to-pointer conversion
(<TT>4.2</TT>)</SPAN>. [<I>Example:</I> ...</P></LI></UL>

<LI><P>Delete the note from 15.1 [except.throw] paragraph 3
as follows:</P></LI>

<BLOCKQUOTE>

A <I>throw-expression</I> initializes a temporary object, called the
<I>exception object</I>, the type of which is determined by removing
any top-level <I>cv-qualifier</I>s from the static type of the operand
of <TT>throw</TT> and adjusting the type from &#8220;array of
<TT>T</TT>&#8221; or &#8220;function returning <TT>T</TT>&#8221; to
&#8220;pointer to <TT>T</TT>&#8221; or &#8220;pointer to function
returning <TT>T</TT>&#8221;, respectively. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">[<I>Note:</I> the temporary
object created for a <I>throw-expression</I> that is a string literal
is never of type <TT>char*</TT>, <TT>char16_t*</TT>,
<TT>char32_t*</TT>, or <TT>wchar_t*</TT>; that is, the special
conversions for string literals from the types &#8220;array of
<TT>const char</TT>&#8221;, &#8220;array of <TT>const
char16_t</TT>&#8221;, &#8220;array of <TT>const char32_t</TT>&#8221;,
and &#8220;array of <TT>const wchar_t</TT>&#8221; to the types
&#8220;pointer to <TT>char</TT>&#8221;, &#8220;pointer to
<TT>char16_t</TT>&#8221;, &#8220;pointer to <TT>char32_t</TT>&#8221;,
and &#8220;pointer to <TT>wchar_t</TT>&#8221;, respectively
(4.2 [conv.array]), are never applied to a
<I>throw-expression</I>. &#8212;<I>end note</I>]</SPAN> The temporary is
an lvalue...

</BLOCKQUOTE>

<LI><P>Change the discussion of 2.14.5 [lex.string] in
C.1.1 [diff.lex] as follows:</P></LI>

<BLOCKQUOTE>

<P><B>Change:</B> String literals made const<BR>
The type of a string literal is changed... &#8220;array of
<TT>const wchar_t</TT>.&#8221;</P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">    char* p = "abc";   //<SPAN style="font-family:Times;font-style:italic"> valid in C, invalid in C++</SPAN>
</SPAN></PRE>

<P>...</P>

<P><B>Difficulty of converting:</B> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">Simple syntactic
transformation, because string literals can be converted to
<TT>char*</TT>; (4.2 [conv.array]). The most common cases are
handled by a new but deprecated standard conversion</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">Syntactic transformation. The fix is to add a cast</SPAN>:</P>

<PRE>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">  char* p = "abc";                //<SPAN style="font-family:Times;font-style:italic"> valid in C, deprecated in C++</SPAN>
  char* q = expr ? "abc" : "de";  //<SPAN style="font-family:Times;font-style:italic"> valid in C, invalid in C++</SPAN></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  void f(char*) {
      char* p = (char*)"abc";  //<SPAN style="font-family:Times;font-style:italic"> cast added</SPAN>
      f(p);
      f((char*)"def");         //<SPAN style="font-family:Times;font-style:italic"> cast added</SPAN>
   }</SPAN>
</PRE>

</BLOCKQUOTE>

<LI><P>Delete _N3000_.D.4 [depr.string]:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><B>D.4 Implicit conversion from const strings
[depr.string]</B></SPAN></P>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">The implicit conversion from const to non-const qualification
for string literals (4.2 [conv.array]) is deprecated.</SPAN></P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="685"></A><H4>685.
  
Integral promotion of enumeration ignores fixed underlying type
</H4><B>Section: </B>4.5&#160; [conv.prom]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Alberto Ganesh Barbati
 &#160;&#160;&#160;

 <B>Date: </B>6 January, 2008<BR>


<P>[Voted into WP at July, 2009 meeting.]</P>

<P>According to 4.5 [conv.prom] paragraph 2,</P>

<BLOCKQUOTE>

An rvalue of an unscoped enumeration type (7.2 [dcl.enum]) can be converted to an rvalue of the first of the
following types that can represent all the values of the
enumeration (i.e. the values in the range <I>b<SUB>min</SUB></I>
to <I>b<SUB>max</SUB></I> as described in 7.2 [dcl.enum]): <TT>int</TT>, <TT>unsigned int</TT>, <TT>long
int</TT>, <TT>unsigned long int</TT>, <TT>long long int</TT>, or
<TT>unsigned long long int</TT>.

</BLOCKQUOTE>

<P>This wording may have surprising behavior in this case:</P>

<PRE>
    enum E: long { e };

    void f(int);
    void f(long);

    void g() {
        f(e);    //<SPAN style="font-family:Times;font-style:italic"> Which </SPAN>f<SPAN style="font-family:Times;font-style:italic"> is called?</SPAN>
    }
</PRE>

<P>Intuitively,  as the programmer has explicitly expressed
preference for <TT>long</TT> as the underlying type, he/she might
expect <TT>f(long)</TT> to be called.  However, if <TT>long</TT>
and <TT>int</TT> happen to have the same size, then <TT>e</TT> is
promoted to <TT>int</TT> (as it is the first type in the list that
can represent all values of <TT>E</TT>) and <TT>f(int)</TT> is
called instead.</P>

<P>According to 7.2 [dcl.enum] the underlying type of an
enumeration is always well-defined for both the fixed and the
non-fixed cases, so it makes sense simply to promote to the
underlying type unless such a type would itself require promotion.</P>

<P><U>Suggested resolution</U>:</P>

<P>In 4.5 [conv.prom] paragraph 2, replace all the text
from &#8220;An rvalue of an unscoped enumeration type&#8221; through
the end of the paragraph with the following:</P>

<BLOCKQUOTE>

An rvalue of an unscoped enumeration type (7.2 [dcl.enum])
is converted to an rvalue of its underlying type if it is different
from <TT>char16_t</TT>, <TT>char32_t</TT>, <TT>wchar_t</TT>, or has
integer conversion rank greater than or equal to <TT>int</TT>.
Otherwise, it is converted to an rvalue of the first of the following
types that can represent all the values of its underlying type:
<TT>int</TT>, <TT>unsigned int</TT>, <TT>long int</TT>,
<TT>unsigned long int</TT>, <TT>long long int</TT>, or
<TT>unsigned long long int</TT>.

</BLOCKQUOTE>

<P>(Note that this wording no longer needs to mention extended
integer types as special cases.)</P>

<P><B>Proposed resolution (August, 2008):</B></P>

<P>Move the following text from 4.5 [conv.prom] paragraph
2 into a separate paragraph, making the indicated changes, and add
the following new paragraph after it:</P>

<BLOCKQUOTE>

<P>An rvalue of an unscoped enumeration type <SPAN style="font-weight:bold;background-color:#A0FFA0">whose underlying
type is not fixed</SPAN> (7.2 [dcl.enum]) can be converted
to an rvalue of the first of the following types that can
represent all the values of the enumeration (i.e. the values in
the range <I>b<SUB>min</SUB></I> to <I>b<SUB>max</SUB></I> as
described in 7.2 [dcl.enum]): <TT>int</TT>,
<TT>unsigned int</TT>, <TT>long int</TT>, <TT>unsigned long
int</TT>, <TT>long long int</TT>, or <TT>unsigned long long
int</TT>.  If none of the types in that list can represent all
the values of the enumeration, an rvalue of an unscoped
enumeration type can be converted to an rvalue of the extended
integer type with lowest integer conversion rank (4.13 [conv.rank]) greater than the rank of <TT>long long</TT> in
which all the values of the enumeration can be represented.  If
there are two such extended types, the signed one is chosen.</P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">An rvalue of an unscoped enumeration type whose underlying
type is fixed (7.2 [dcl.enum]) can be converted to an
rvalue of its underlying type. Moreover, if integral promotion
can be applied to its underlying type, an rvalue of an unscoped
enumeration type whose underlying type is fixed can also be
converted to an rvalue of the promoted underlying type.</SPAN></P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="707"></A><H4>707.
  
Undefined behavior in integral-to-floating conversions
</H4><B>Section: </B>4.9&#160; [conv.fpint]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Alberto Ganesh Barbati
 &#160;&#160;&#160;

 <B>Date: </B>2 Aug, 2008<BR>


<P>[Voted into WP at July, 2009 meeting.]</P>



<P>The current wording of 4.9 [conv.fpint] paragraph 2
does not specify what should happen when converting an integer
value that is outside the representable range of the target floating
point type.  The C99 Standard covers this case explicitly in
6.3.1.4 paragraph 2:</P>

<BLOCKQUOTE>

When a value of integer type is converted to a real floating
type, if the value being converted can be represented exactly in
the new type, it is unchanged.  If the value being converted is
in the range of values that can be represented but cannot be
represented exactly, the result is either the nearest higher or
nearest lower representable value, chosen in an
implementation-defined manner.  If the value being converted is
outside the range of values that can be represented, the behavior
is undefined.

</BLOCKQUOTE>

<P>While the current C++ specification requires defined behavior
in all cases, the C specification allows for use of NaNs and
traps, if those are needed for efficiency.</P>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>The CWG agreed that the C approach should be adopted.</P>

<P><B>Proposed resolution (March, 2009):</B></P>

<P>Change 4.9 [conv.fpint] paragraph 2 as indicated:</P>

<BLOCKQUOTE>

An rvalue of an integer type or of an unscoped enumeration type can be
converted to an rvalue of a floating point type.  The result is exact
if possible.  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">Otherwise</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">If the value being converted is in
the range of values that can be represented but cannot be represented
exactly</SPAN>, it is an implementation-defined choice of
either the next lower or higher representable value.  [<I>Note:</I>
loss of precision occurs if the integral value cannot be represented
exactly as a value of the floating type.  &#8212;<I>end note</I>]
<SPAN style="font-weight:bold;background-color:#A0FFA0">If the value being converted is outside the range of values that
can be represented, the behavior is undefined.</SPAN> If the source type
is <TT>bool</TT>, the value <TT>false</TT> is converted to zero and
the value <TT>true</TT> is converted to one.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="438"></A><H4>438.
  
Possible flaw in wording for multiple accesses to object between sequence points
</H4><B>Section: </B>5&#160; [expr]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>29 Oct 2003<BR>


<P>Lisa Lippincott mentioned this case to me:</P>
<PRE>
  A[0] = 0;
  A[A[0]] = 1;
</PRE>
<P>This seems to use the old value of A[0] other than to calculate the new
value, which is said to be undefined, but it also seems reasonable, since
the old value is used in order to select the object to modify, so there's
no ordering ambiguity.</P>

<P><U>Steve Adamczyk</U>: the ordering rule referred to is in
5 [expr] paragraph 4.</P>

<P><B>Notes from the March 2004 meeting:</B></P>

<P>Clark Nelson mentions that the C committee may have done something on
this.</P>

<P><B>Note (July, 2009):</B></P>

<P>This issue was resolved by the adoption of the &#8220;sequenced
before&#8221; wording.</P>

<BR><BR><HR><A NAME="695"></A><H4>695.
  
Compile-time calculation errors in constexpr functions
</H4><B>Section: </B>5&#160; [expr]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>9 June, 2008<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>Evaluating an expression like <TT>1/0</TT> is intended to produce
undefined behavior during the execution of a program but be ill-formed
at compile time.  The wording for this is in 5 [expr]
paragraph 4:</P>

<BLOCKQUOTE>

If during the evaluation of an expression, the result is not
mathematically defined or not in the range of representable values for
its type, the behavior is undefined, unless such an expression appears
where an integral constant expression is required (5.19 [expr.const]), in which case the program is ill-formed.

</BLOCKQUOTE>

<P>The formulation &#8220;appears where an integral constant
expression is required&#8221; is intended as an acceptable
Standardese circumlocution for &#8220;evaluated at compile time,&#8221;
a concept that is not directly defined by the Standard.  It is not
clear that this formulation adequately covers constexpr functions.</P>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>The CWG felt that the concept of &#8220;compile-time
evaluation&#8221; needs to be defined for use in discussing
constexpr functions.  There is a tension between wanting to
diagnose errors at compile time versus not diagnosing errors
that will not actually occur at runtime.  In this context, a
constexpr function might never be invoked, either in a
constant expression context or at runtime, although the
requirement that the expression in a constexpr function be a
potential constant expression could be interpreted as triggering
the provisions of 5 [expr] paragraph 4.</P>

<P>There are also contexts in which it is not known in advance
whether an expression must be constant or not, notably in the
initializer of a const integer variable, where the nature of
the initializer determines whether the variable can be used in
constant expressions or not.  In such a case, it is not clear
whether an erroneous expression should be considered ill-formed
or simply non-constant (and thus subject to runtime undefined
behavior, if it is ever evaluated).  The consensus of the CWG
was that an expression like <TT>1/0</TT> should simply be
considered non-constant; any diagnostic would result from the
use of the expression in a context requiring a constant
expression.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#699">issue 699</A>.</P>

<BR><BR><HR><A NAME="835"></A><H4>835.
  
Scoped enumerations and the &#8220;usual arithmetic conversions&#8221;
</H4><B>Section: </B>5&#160; [expr]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Beman Dawes
 &#160;&#160;&#160;

 <B>Date: </B>5 March, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>A number of the operators described in clause 5 [expr]
take operands of enumeration type, relying on the &#8220;usual
arithmetic conversions&#8221; (5 [expr] paragraph 10)
to convert them to an appropriate integral type.  The assumption
behind this pattern is invalid when one or more of the operands has
a scoped enumeration type.</P>

<P>Each operator that accepts operands of enumeration type should be
evaluated as to whether the operation makes sense for scoped
enumerations (for example, it is probably a good idea to allow
comparison of operands having the same scoped enumeration type
and conditional expressions in which the second and third operands
have the same scoped enumeration type) and, if so, create a
special case.  The usual arithmetic conversions should not be
invoked for scoped enumeration types.</P>

<P>(See also <A HREF="
     cwg_defects.html#880">issue 880</A>.)</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<OL><LI><P>Change 5 [expr] paragraph 10 as follows:</P></LI>

<BLOCKQUOTE>

<P>...This pattern is called the usual arithmetic conversions, which
are defined as follows:</P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">If either operand is of scoped enumeration type
(7.2 [dcl.enum]), no conversions are performed, and if the
other operand does not have the same type, the expression is
ill-formed.</SPAN></P></LI>

<LI><P>If either operand is of type <TT>long double</TT>...</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 5.2.1 [expr.sub] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...One of the expressions shall have the type &#8220;pointer to
<TT>T</TT>&#8221; and the other shall have <SPAN style="font-weight:bold;background-color:#A0FFA0">unscoped</SPAN>
enumeration or integral type...

</BLOCKQUOTE>

<LI><P>Change 5.3 [expr.unary] paragraphs 7-8 and 10 as
follows:</P></LI>

<BLOCKQUOTE>

<P>The operand of the unary <TT>+</TT> operator shall have arithmetic,
<SPAN style="font-weight:bold;background-color:#A0FFA0">unscoped</SPAN> enumeration, or pointer type...</P>

<P>The operand of the unary <TT>-</TT> operator shall have arithmetic or
<SPAN style="font-weight:bold;background-color:#A0FFA0">unscoped</SPAN> enumeration type...</P>

<P>The operand of <TT>~</TT> shall have integral or <SPAN style="font-weight:bold;background-color:#A0FFA0">unscoped</SPAN>
enumeration type...</P>

</BLOCKQUOTE>

<LI><P>Change 5.3.4 [expr.new] paragraph 6 as follows:</P></LI>

<BLOCKQUOTE>

...The expression in a <I>noptr-new-declarator</I> shall be of
integral type, <SPAN style="font-weight:bold;background-color:#A0FFA0">unscoped</SPAN> enumeration type, or a class type
for which a single non-explicit conversion function to integral or
<SPAN style="font-weight:bold;background-color:#A0FFA0">unscoped</SPAN> enumeration type exists (12.3 [class.conv]).  If the expression...

</BLOCKQUOTE>

<LI><P>Change 5.6 [expr.mul] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

The operands of <TT>*</TT> and <TT>/</TT> shall have arithmetic or
<SPAN style="font-weight:bold;background-color:#A0FFA0">unscoped</SPAN> enumeration type; the operands of <TT>%</TT> shall
have integral or <SPAN style="font-weight:bold;background-color:#A0FFA0">unscoped</SPAN> enumeration type....

</BLOCKQUOTE>

<LI><P>Change 5.7 [expr.add] paragraph 1-2 as follows:</P></LI>

<BLOCKQUOTE>

<P>...For addition, either both operands shall have arithmetic or
<SPAN style="font-weight:bold;background-color:#A0FFA0">unscoped</SPAN> enumeration type, or one operand shall be a
pointer to a completely-defined effective object type and the other
shall have integral or <SPAN style="font-weight:bold;background-color:#A0FFA0">unscoped</SPAN> enumeration type.</P>

<P>For subtraction, one of the following shall hold:</P>

<UL><LI><P>both operands have arithmetic or <SPAN style="font-weight:bold;background-color:#A0FFA0">unscoped</SPAN>
enumeration type; or</P></LI>

<LI><P>both operands are pointers to cv-qualified or cv-unqualified
versions of the same completely-defined effective object type;
or</P></LI>

<LI><P>the left operand is a pointer to a completely-defined effective
object type and the right operand has integral or <SPAN style="font-weight:bold;background-color:#A0FFA0">unscoped</SPAN>
enumeration type.</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 5.8 [expr.shift] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...The operands shall be of integral or <SPAN style="font-weight:bold;background-color:#A0FFA0">unscoped</SPAN>
enumeration type...

</BLOCKQUOTE>

<LI><P>Change 5.9 [expr.rel] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

If both operands (after conversions) are of arithmetic <SPAN style="font-weight:bold;background-color:#A0FFA0">or
enumeration</SPAN> type, each of the operators shall yield
<TT>true</TT> if the specified relationship is true and <TT>false</TT>
if it is false.

</BLOCKQUOTE>

<LI><P>Change 5.11 [expr.bit.and] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...The operator applies only to integral or <SPAN style="font-weight:bold;background-color:#A0FFA0">unscoped</SPAN>
enumeration operands.

</BLOCKQUOTE>

<LI><P>Change 5.12 [expr.xor] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...The operator applies only to integral or <SPAN style="font-weight:bold;background-color:#A0FFA0">unscoped</SPAN>
enumeration operands.

</BLOCKQUOTE>

<LI><P>Change 5.13 [expr.or] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...The operator applies only to integral or <SPAN style="font-weight:bold;background-color:#A0FFA0">unscoped</SPAN>
enumeration operands.

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="858"></A><H4>858.
  
Example binding an rvalue reference to an lvalue
</H4><B>Section: </B>5&#160; [expr]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>6 April, 2009<BR>


<P>[Voted into WP at March, 2010 meeting as part of document N3055.]</P>



<P>The adoption of paper N2844 made it ill-formed to attempt to bind
an rvalue reference to an lvalue, but the example in 5 [expr]
paragraph 6 was overlooked in making this change:</P>

<PRE>
    struct A { };
    A&amp;&amp; operator+(A, A);
    A&amp;&amp; f();

    A a;
    A&amp;&amp; ar = a;
</PRE>

<P>The last line should be changed to use something like
<TT>static_cast&lt;A&amp;&amp;&gt;(a)</TT>.</P>

<P>(See also <A HREF="
     cwg_defects.html#847">issue 847</A>.)</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change the example in 5 [expr] paragraph 6 as follows:</P>

<BLOCKQUOTE>

<P>[<I>Example:</I></P>

<PRE>
  struct A { };
  A&amp;&amp; operator+(A, A);
  A&amp;&amp; f();

  A a;
  A&amp;&amp; ar = <SPAN style="font-weight:bold;background-color:#A0FFA0">static_cast&lt;A&amp;&amp;&gt;(</SPAN>a<SPAN style="font-weight:bold;background-color:#A0FFA0">)</SPAN>;
</PRE>

<P>The expressions <TT>f()</TT> and <TT>a + a</TT> are rvalues of type
<TT>A</TT>. The expression <TT>ar</TT> is an lvalue of type
<TT>A</TT>. &#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="743"></A><H4>743.
  
Use of <TT>decltype</TT> in a <I>nested-name-specifier</I>
</H4><B>Section: </B>5.1.1&#160; [expr.prim.general]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Jaakko J&#228;rvi
 &#160;&#160;&#160;

 <B>Date: </B>12 November, 2008<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#JP8">N2800 comment
  JP&#160;8<BR></A>

<P>[Voted into WP at March, 2010 meeting as document N3049.]</P>



<P>The grammar for <I>nested-name-specifier</I> in 5.1.1 [expr.prim.general]
paragraph 7 does not allow <TT>decltype</TT> to be used in a
<I>qualified-id</I>.  This could be useful for cases like:</P>

<PRE>
   auto vec = get_vec();
   decltype(vec)::value_type v = vec.first();
</PRE>

(See also <A HREF="
     cwg_defects.html#950">issue 950</A>.)

<P><B>Proposed resolution (September, 2009):</B></P>

<P>See paper PL22.16/09-0181 = WG21 N2991.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>See paper PL22.16/10-0021 = WG21 N3031.</P>

<BR><BR><HR><A NAME="760"></A><H4>760.
  
<TT>this</TT> inside a nested class of a non-static member function
</H4><B>Section: </B>5.1.1&#160; [expr.prim.general]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>3 February, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P><TT>this</TT> is a keyword and thus not subject to ordinary name
lookup.  That makes the interpretation of examples like the following
somewhat unclear:</P>

<PRE>
    struct outer {
      void f() {
        struct inner {
          int a[sizeof(*this)];  // #1
        };
      }
    };
</PRE>

<P>According to 5.1.1 [expr.prim.general] paragraph 3,</P>

<BLOCKQUOTE>

The keyword <TT>this</TT> shall be used only inside a non-static class
member function body (9.3 [class.mfct]) or in a
<I>brace-or-equal-initializer</I> for a non-static data member.

</BLOCKQUOTE>

<P>Should the use of <TT>this</TT> at #1 be interepreted as a well-formed
reference to <TT>outer::f()</TT>'s <TT>this</TT> or as an ill-formed
attempt to refer to a <TT>this</TT> for <TT>outer::inner</TT>?</P>

<P>One possible interpretation is that the intent is as if <TT>this</TT>
were an ordinary identifier appearing as a parameter in each non-static
member function.  (This view applies to the initializers of non-static
data members as well if they are considered to be rewritten as
<I>mem-initializer</I>s in the constructor body.)  Under this
interpretation, the prohibition against using <TT>this</TT> in other
contexts simply falls out of the fact that name lookup would fail to
find <TT>this</TT> anywhere else, so the reference in the example is
well-formed.  (Implementations vary in their treatment of this
example, so clearer wording is needed, whichever way the
interpretation goes.)</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 5.1.1 [expr.prim.general] paragraph 2 as follows:</P>

<BLOCKQUOTE>

<P>...The keyword <TT>this</TT> shall be used only inside <SPAN style="font-weight:bold;background-color:#A0FFA0">the
body of</SPAN> a non-static <SPAN style="text-decoration:line-through;background-color:#FFA0A0">class</SPAN> member function
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">body</SPAN> (9.3 [class.mfct]) <SPAN style="font-weight:bold;background-color:#A0FFA0">of the nearest
enclosing class</SPAN> or in a <I>brace-or-equal-initializer</I>
for a non-static data member <SPAN style="font-weight:bold;background-color:#A0FFA0">(9.2 [class.mem])</SPAN>.  The type of the expression is a pointer to
the class of the function or non-static data member, possibly
with cv-qualifiers on the class type. The expression is an
rvalue. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  class Outer {
    int a[sizeof(*this)];            //<SPAN style="font-family:Times;font-style:italic"> error: not inside a member function</SPAN>
    unsigned int sz = sizeof(*this); //<SPAN style="font-family:Times;font-style:italic"> OK, in brace-or-equal-initializer</SPAN>

    void f() {
      int b[sizeof(*this)];          //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>

      struct Inner {
        int c[sizeof(*this)];        //<SPAN style="font-family:Times;font-style:italic"> error: not inside a member function of </SPAN>Inner
      };
    }
  };</SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="850"></A><H4>850.
  
Restrictions on use of non-static data members
</H4><B>Section: </B>5.1.1&#160; [expr.prim.general]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>1 April, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>The resolution of <A HREF="
     cwg_defects.html#613">issue 613</A>, as
reflected in the sixth bullet of 5.1.1 [expr.prim.general] paragraph
10, allows an <I>id-expression</I> designating a non-static data member
to be used</P>

<BLOCKQUOTE>

<UL><LI>if... it is the sole constituent of an unevaluated operand,
except for optional enclosing parentheses.</LI></UL>

</BLOCKQUOTE>

<P>The requirement that the <I>id-expression</I> be the &#8220;sole
constituent&#8221; of the unevaluated operand seems unnecessarily
strict, forbidding such plausible use cases as</P>

<PRE>
    struct S {
        int ar[42];
    };
    int i = sizeof(S::ar[0]);
</PRE>

<P>or the use of the member as a function argument in template
metaprogramming.  The more general version of the restriction seems
not to be very difficult to implement and may actually represent a
simplification in some implementations.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 5.1.1 [expr.prim.general] paragraph 10 as follows:</P>

<UL><LI><P>...</P></LI>

<LI><P>if that <I>id-expression</I> denotes a non-static data member
and it <SPAN style="text-decoration:line-through;background-color:#FFA0A0">is the sole constituent of</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">appears in</SPAN> an
unevaluated operand<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, except for optional enclosing
parentheses</SPAN>. [<I>Example:</I></P>

<PRE>
  struct S {
    int m;
  };
  int i = sizeof(S::m);        //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
  int j = sizeof(S::m + 42);   //<SPAN style="font-family:Times;font-style:italic"> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">error: reference to non-static member in subexpression</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">OK</SPAN></SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

</LI>

</UL>

<BR><BR><HR><A NAME="720"></A><H4>720.
  
Need examples of <I>lambda-expression</I>s
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>20 September, 2008<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#DE9">N2800 comment
  DE&#160;9<BR></A>

<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>

<P>There is not a single example of a <I>lambda-expression</I> in
their specification.  The Standard would be clearer if a few
judiciously-chosen examples were added.</P>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="750"></A><H4>750.
  
Implementation constraints on reference-only closure objects
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>10 December, 2008<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#US73">N2800 comment
  US&#160;73<BR></A>

<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>



<P>Consider an example like:</P>

<PRE>
    void f(vector&lt;double&gt; vec) {
      double x, y, z;
      fancy_algorithm(vec, [&amp;]() { /* use x, y, and z in various ways */ });
    }
</PRE>

<P>5.1.2 [expr.prim.lambda] paragraph 8 requires that the closure
class for this lambda will have three reference members, and paragraph
12 requires that it be derived from <TT>std::reference_closure</TT>,
implying two additional pointer members.  Although 8.3.2 [dcl.ref] paragraph 4 allows a reference to be implemented without
allocation of storage, current ABIs require that references be
implemented as pointers.  The practical effect of these requirements
is that the closure object for this lambda expression will contain
five pointers.  If not for these requirements, however, it would be
possible to implement the closure object as a single pointer to the
stack frame, generating data accesses in the function-call operator as
offsets relative to the frame pointer.  The current specification is
too tightly constrained.</P>

<P><U>Lawrence Crowl</U>:</P>

<P>The original intent was that the reference members could be omitted
from the closure object by an implementation.  The problem we had was
that we want the call to <TT>f</TT> in</P>

<PRE>
    extern f(std::reference_closure&lt;void()&gt;);
    extern f(std::function&lt;void()&gt;);
    f([&amp;](){});
</PRE>

<P>to unambiguously bind to the <TT>reference_closure</TT>; using
<TT>reference_closure</TT> can be an order of magnitude faster
than using <TT>function</TT>.</P>

<P>(See also <A HREF="
     cwg_defects.html#751">issue 751</A>.)</P>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.  (See also document
PL22.16/09-0035 = WG21 N2845, which partially addressed this issue
by the removal of <TT>std::reference_clossure.)</TT></P>

<BR><BR><HR><A NAME="751"></A><H4>751.
  
Deriving from closure classes
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>11 December, 2008<BR>


<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>



<P>During the discussion of <A HREF="
     cwg_defects.html#750">issue 750</A>, it
was suggested that an implementation might be permitted to omit fields
in the closure object of a lambda expression if the implementation does
not need them to address the corresponding automatic variables.  If
permitted, this implementation choice might be visible to the program
via inheritance.  Consider:</P>

<PRE>
    void f() {
      int const N = 10;
      typedef decltype([&amp;N](){}) F;
      struct X: F {
        void n() { float z[N]; } // Error?
      };
    }
</PRE>

<P>If it is implementation-defined or unspecified whether the reference
member <TT>F::N</TT> will exist, then it is unknown whether the
the reference to <TT>N</TT> in <TT>X::n()</TT> will be an error
(because lookup finds <TT>F::N</TT>, which is private) or well-formed
(because there is no <TT>F::N</TT>, so the reference is to the local
automatic variable).</P>

<P>If implementations can omit fields, the implementation dependency
might be addressed by either treating the lookup &#8220;as if&#8221;
the fields existed, even if they are not present in the object
layout, or by defining the names of the fields in the closure class
to be unique identifiers, similar to the names of unnamed namespaces
(7.3.1.1 [namespace.unnamed]).</P>

<P>Another suggestion was made that derivation from a closure class
should be prohibited, at least for now.  However, it was pointed out
that inheritance is frequently used to give stateless function objects
some state, suggesting a use case along the lines of:</P>

<PRE>
    template&lt;class T&gt; struct SomeState: T {
      // ...
    };
    template&lt;class F, typename T&lt; void algo(T functor, ...) {
      SomeState&lt;T&lt; state(functor);
      ...
    }

    ... algo([](int a){ return 2*a; }) ...
</PRE>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="752"></A><H4>752.
  
Name lookup in nested <I>lambda-expression</I>s
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>10 December, 2008<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#US31">N2800 comment
  US&#160;31<BR></A>

<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>



<P>How does name binding work in nested <I>lambda-expression</I>s? For
example,</P>

<PRE>
    void f1() {
      float v;
      []() { return [v]() { return v; } }
    }

    void f2() {
      float v;
      [v]() { return [v]() { return v; } }
    }
</PRE>

<P>According to 5.1.2 [expr.prim.lambda] paragraph 3,</P>

<BLOCKQUOTE>

A name in the <I>lambda-capture</I> shall be in scope in the context
of the lambda expression, and shall be <TT>this</TT> or shall refer to
a local variable or reference with automatic storage duration.

</BLOCKQUOTE>

<P>One possible interpretation is that the lambda expression in
<TT>f1</TT> is ill-formed because <TT>v</TT> is used in the
<I>compound-statement</I> of the outer lambda expression but does not
appear in its effective capture set.  However, the appearance of
<TT>v</TT> in the inner <I>lambda-capture</I> is not a
&#8220;use&#8221; in the sense of 3.2 [basic.def.odr] paragraph
2, because a <I>lambda-capture</I> is not an <I>expression</I>, and
it's not clear whether the reference in the inner lambda expression's
<TT>return</TT> expression should be considered a use of the automatic
variable or of the member of the inner lambda expression's closure
object.</P>

<P>Similarly, the lambda expression in <TT>f2</TT> could be deemed
to be ill-formed because the reference to <TT>v</TT> in the inner
lambda expression's <I>lambda-capture</I> would refer to the field
of the outer lambda-expression's closure object, not to a local
automatic variable; however, it's not clear whether the inner
lambda expression should be evaluated <I>in situ</I> or as part of
the generated <TT>operator()</TT> member of the outer lambda
expression's closure object.</P>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="753"></A><H4>753.
  
Array names in lambda capture sets
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>10 December, 2008<BR>


<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>



<P>The current specification does not adequately describe what happens
when an array name is part of the effective capture set of a lambda
expression.  5.1.2 [expr.prim.lambda] paragraph 13 says that the
array member of the closure object is direct-initialized by the local
array; however, 8.5 [dcl.init] paragraph 16 says that such
an initialization is ill-formed.  There are several possibilities for
handling this problem:</P>

<OL><LI><P>This results in an array member of the closure object,
which is initialized by copying each element, along the lines of
12.8 [class.copy] paragraph 8.</P></LI>

<LI><P>This results in a pointer member of the closure object,
initialized to point to the first element of the array (i.e., the
array lvalue decays to a pointer rvalue).</P></LI>

<LI><P>This is ill-formed.</P></LI>

<LI><P>This results in a reference-to-array member of the closure
object, initialized to refer to the array, regardless of whether
<TT>&amp;</TT> was used or not.</P></LI>

<LI><P>This is ill-formed unless the capture is &#8220;by
reference.&#8221;</P></LI>

</OL>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="754"></A><H4>754.
  
Lambda expressions in default arguments of block-scope function declarations
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>10 December, 2008<BR>


<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>



<P>Is a lambda expression permitted in a default argument expression
for a block-scope function declaration? For example,</P>

<PRE>
    void g() {
      void f(std::reference_closure&lt;void()&gt; rc = []() {});
      f();
    }
</PRE>

<P>This was not discussed in either the Evolution Working Group nor
in the Core Working Group, and it is possible that some of the same
implementation difficulties that led to prohibiting use of automatic
variables in such default argument expressions (8.3.6 [dcl.fct.default]
paragraph 7) might also apply to closure objects, even though they are
not automatic variables.</P>

(See also <A HREF="
     cwg_defects.html#772">issue 772</A>.)

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="756"></A><H4>756.
  
Dropping cv-qualification on members of closure objects
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>15 December, 2008<BR>


<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>



<P>Consider the following example:</P>

<PRE>
    void f() {
      int const N = 10;
      [=]() mutable { N = 30; }  // Okay: this-&gt;N has type int, not int const.
      N = 20;  // Error.
    }
</PRE>

<P>That is, the <TT>N</TT> that is a member of the closure object is not
const, even though the captured variable is const.  This seems strange,
as capturing is basically a means of capturing the local environment in a
way that avoids lifetime issues.  More seriously, the change of type
means that the results of <TT>decltype</TT>, overload resolution, and
template argument deduction applied to a captured variable inside a
lambda expression can be different from those in the scope containing
the lambda expression, which could be a subtle source of bugs.</P>

<P>On the other hand, the copying involved in capturing has uses beyond
avoiding lifetime issues (taking snapshots of values, avoiding data
races, etc.), and the value of a cv-qualified object is not cv-qualified.</P>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="759"></A><H4>759.
  
Destruction of closure objects
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>22 January, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK39">N2800 comment
  UK&#160;39<BR></A>

<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>



<P>The specification of closure objects is missing a couple of important
points regarding their destruction.  First, although 5.1.2 [expr.prim.lambda]
paragraph 11 mentions other implicitly-declared special member functions,
it is silent on the destructor, leading to questions about whether the
closure class has one or not.</P>

<P>Second, nothing is said about the timing of the destruction of a
closure object: is it normally destroyed at the end of the full-expression
to which the lambda expression belongs, and is its lifetime extended if
the closure object is bound to a reference?  These questions would be
addressed if paragraph 2 defined the closure object as a temporary instead
of just as an rvalue.  (It should be noted that 5.2.3 [expr.type.conv]
also does not define the conceptually-similar <TT>T()</TT> as a
temporary.)</P>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.  (The question regarding
the failure of 5.2.3 [expr.type.conv] failing to categorize
<TT>T()</TT> as a temporary was split off into a separate issue; see
<A HREF="
     cwg_active.html#943">issue 943</A>.)</P>

<BR><BR><HR><A NAME="761"></A><H4>761.
  
Inferred return type of closure object call operator
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>5 February, 2009<BR>


<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>

<P>According to 5.1.2 [expr.prim.lambda] paragraph 10, the following
lambda expressions are ill-formed because the return types of the
generated <TT>operator()</TT> functions are an array type and a function
type, respectively:</P>

<PRE>
    void f() {
      []{ return ""; };
      []{ return f; };
    }
</PRE>

<P>It would seem reasonable to expect the array-to-pointer and
function-to-pointer decay to apply to these return values and
hence to the inferred return type of <TT>operator()</TT>.</P>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="762"></A><H4>762.
  
Name lookup in the <I>compound-statement</I> of a lambda expression
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>5 February, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#US29">N2800 comment
  US&#160;29<BR></A>
<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#US30">N2800 comment
  US&#160;30<BR></A>

<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>

<P>The current wording of 5.1.2 [expr.prim.lambda] is not clear as to
how name lookup is to be performed for names appearing in the
<I>compound-statement</I> of a lambda expression.  Consider, for
example:</P>

<PRE>
    int fac(int n) {
      return [=]{ return n &lt;= 1 ? 1 : n*operator()(n-1); }();
    }
</PRE>

<P>There is no <TT>operator()</TT> in scope in the context of the
lambda expression.  Consequently, according to bullet 5 of paragraph 10,
the reference to <TT>operator()</TT> is not transformed to the class
member access syntax but appears untransformed in the closure object's
function call operator, where presumably it is interpreted as a
recursive call to itself.</P>

<P>A similar question (although it does not involve name lookup per
se) arises with respect to use of <TT>this</TT> in the
<I>compound-statement</I> of a lambda expression that does not appear
in the body of a non-static member function; for example,</P>

<PRE>
    void f() {
      float v;
      [v]() { return v+this-&gt;v; }
    }
</PRE>

<P><TT>this</TT> cannot refer to anything except the closure object,
so are the two references to <TT>v</TT> equivalent?</P>

<P>The crux of this question is whether the lookups for names in the
<I>compound-statement</I> are done in the context of the lambda
expression or from the call operator of the closure object.  The note at
the end of paragraph 10 bullet 5 would tend to support the latter
interpretation:</P>

<BLOCKQUOTE>

[<I>Note:</I> Reference to captured variables or references within
the <I>compound-statement</I> refer to the data members of <TT>F</TT>.
&#8212;<I>end note</I>]

</BLOCKQUOTE>

<P>Another possible interpretation of the current wording is that
there are two distinct <I>compound-statement</I>s in view: the
<I>compound-statement</I> that is part of the <I>lambda-expression</I>
and the body of the closure object's function call operator that is
&#8220;obtained from&#8221; the former.  If this is the intended
interpretation, one way of addressing the issues regarding the
<TT>operator()</TT> example above would be to state that it is an
error if the lookup of a name in the <I>compound-statement</I> fails,
making the example ill-formed.</P>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="763"></A><H4>763.
  
Is a closure object's <TT>operator()</TT> inline?
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>6 February, 2009<BR>


<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>

<P>A lambda expression appearing in local scope presumably creates a
local class (in the sense of 9.8 [class.local]) as the type of the
closure object, because that class is &#8220;considered to be defined at
the point where the lambda expression occurs&#8221;
(5.1.2 [expr.prim.lambda] paragraph 7), and in the absence of any
indication to the contrary that class must satisfy the restrictions of
9.8 [class.local] on local classes.  One such restriction is that
all its member functions must be defined within the class definition,
making them inline.  However, nothing is said about whether the function
call operator for a non-local closure class is inline, and even for the
local case it would be better if the specification were explicit.
</P>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="764"></A><H4>764.
  
Capturing unused variables in a lambda expression
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>6 February, 2009<BR>


<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>

<P>5.1.2 [expr.prim.lambda] paragraph 5 says,</P>

<BLOCKQUOTE>

 The <I>compound-statement</I> of a lambda expression shall use
(3.2 [basic.def.odr]) an automatic variable or reference from the
context where the lambda expression appears only if the name of the
variable or reference is a member of the effective capture set...

</BLOCKQUOTE>

<P>The reference to 3.2 [basic.def.odr] makes clear that the
technical meaning of &#8220;use&#8221; is in view here, and that the
names of variables can appear without being captured if they are
constants used as values or if they are unevaluated operands.</P>

<P>There appears to be a disconnect with the preceding paragraph,
however, in the description of which variables are implicitly
captured by a <I>capture-default</I>:</P>

<BLOCKQUOTE>

for each name <TT>v</TT> that appears in the lambda expression and denotes a
local variable or reference with automatic storage duration in the
context where the lambda expression appears and that does not appear
in the <I>capture-list</I> or as a parameter name in the
<I>lambda-parameter-declaration-list</I>...

</BLOCKQUOTE>

<P>It would be more consistent if only variables that were required by
paragraph 5 to be captured were implicitly captured, i.e., if
&#8220;that appears in the lambda expression&#8221; were replaced by
&#8220;that is used (3.2 [basic.def.odr]) in the
<I>compound-statement</I> of the lambda expression.&#8221;  For
example,</P>

<PRE>
    struct A {
      A();
      A(const A&amp;);
      ~A();
    };
    void f() {
      A a;
      int i = [=]() { return sizeof a; }();
    }
</PRE>

<P>Here, <TT>a</TT> will be captured (and copied), even though it is
not &#8220;used&#8221; in the lambda expression.</P>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="766"></A><H4>766.
  
Where may lambda expressions appear?
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>6 February, 2009<BR>


<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>

<P>According to 5.1.2 [expr.prim.lambda] paragraph 7, the appearance of
a lambda expression results in the definition of a class &#8220;considered
to be defined at the point where the lambda expression occurs.&#8221;  It
is not clear whether that means that a lambda expression cannot appear
at any point where it is not permitted to define a class type.  For
example, 8.3.5 [dcl.fct] paragraph 10 says, &#8220;Types shall
not be defined in return or parameter types.&#8221;  Does that mean that
a function declaration like</P>

<PRE>
    void f(int a[sizeof ([]{ return 0; })]);
</PRE>

<P>is ill-formed, because the parameter type defines the closure class
for the lambda expression? (<A HREF="
     cwg_defects.html#686">Issue 686</A> lists
many contexts in which type definitions are prohibited.  Each of these
should be examined to see whether a lambda expression should be allowed
or prohibited there.)</P>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="767"></A><H4>767.
  
<TT>void</TT> and other unnamed <I>lambda-parameter</I>s
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>5 February, 2009<BR>


<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>

<P>The grammar in 5.1.2 [expr.prim.lambda] for <I>lambda-parameter</I>
specifies that a <I>declarator</I> must be present, i.e., that all
<I>lambda-parameter</I>s must be named.  This also has the effect of
prohibiting a lambda like <TT>[](void){}</TT>.  It is not clear that
there is a good reason for these restrictions; programmers could
reasonably expect that <I>lambda-parameter</I>s were like ordinary
function parameters in these regards.
</P>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="768"></A><H4>768.
  
Ellipsis in a lambda parameter list
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>5 February, 2009<BR>


<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>

<P>The grammar in 5.1.2 [expr.prim.lambda] for
<I>lambda-parameter-declaration</I> does not allow for an ellipsis.
Is this a desirable restriction?</P>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="769"></A><H4>769.
  
Initialization of closure objects
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>9 February, 2009<BR>


<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>

<P>5.1.2 [expr.prim.lambda] paragraph 13 says simply,</P>

<BLOCKQUOTE>

The closure object is initialized by direct-initializing each member
<TT>N</TT> of <TT>F</TT> with the local variable or reference named
<TT>N</TT>; the member <TT>t</TT> is initialized with <TT>this</TT>.

</BLOCKQUOTE>

<P>The mechanism for this initialization is not specified. In
particular, does the closure class have a default constructor that
performs this initialization?</P>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="771"></A><H4>771.
  
Move-construction of reference members of closure objects
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Jonathan Caves
 &#160;&#160;&#160;

 <B>Date: </B>9 February, 2009<BR>


<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>

<P>According to 5.1.2 [expr.prim.lambda] paragraph 11, the closure
class &#8220;has a public move constructor that performs a
member-wise move.&#8221; Although the terms &#8220;move
constructor&#8221; and &#8220;member-wise move&#8221; are not currently
defined (see <A HREF="
     cwg_defects.html#680">issue 680</A>), this presumably
means that a lambda like <TT>[&amp;i]{}</TT> results in a closure class
similar to:</P>

<PRE>
    class F {
        int&amp; i;
    public:
        F(&amp;&amp; other):
            i(std::move(other.i)) { }
        // etc.
    };
</PRE>

<P>This constructor is ill-formed because it attempts to initialize
an lvalue reference to non-const int with the rvalue returned by
<TT>std::move</TT>.</P>

<P>It is not clear whether this should be handled by:</P>

<OL>

<LI><P>Not generating the move constructor.</P></LI>

<LI><P>Generating the declaration of the move constructor but only
defining it (and giving the corresponding error) if the move
constructor would be used, similar to the handling of other
implicitly-defined special member functions.</P></LI>

<P><LI>Generating the move constructor but copy-constructing any
reference members.</LI></P>

</OL>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="772"></A><H4>772.
  
<I>capture-default</I> in lambdas in local default arguments
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>10 February, 2009<BR>


<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>

<P>Assuming that it is permitted to use a lambda as a default argument
in a block-scope function declaration (see
<A HREF="
     cwg_defects.html#754">issue 754</A>), it is presumably ill-formed for
such a lambda expression to refer to a local automatic variable
(8.3.6 [dcl.fct.default] paragraph 7).  What does this mean for
<I>capture-default</I>s?  For example,</P>

<PRE>
    void f() {
      int i = 1;
      void f(int = ([i]() { return i; })());  // Definitely an error
      void g(int = ([i]() { return 0; })());  // Probably an error
      void h(int = ([=]() { return i; })());  // Definitely an error
      void o(int = ([=]() { return 0; })());  // Okay?
      void p(int = ([]() { return sizeof i; })());  // Presumably okay
    }
</PRE>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="774"></A><H4>774.
  
Can a closure class be a POD?
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>11 February, 2009<BR>


<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>

<P>The current wording does not state under what conditions, if ever,
a closure class is a POD.  It should either be explicitly unspecified
or definitively stated that a closure class is never a POD, to allow
implementations freedom to determine the contents of closure classes.</P>

<P><B>Notes from the March, 2009 meeting:</B></P>

<P>A closure class is neither standard-layout nor trivial.</P>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="775"></A><H4>775.
  
Capturing references to functions
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>12 February, 2009<BR>


<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>

<P>According to 5.1.2 [expr.prim.lambda] paragraph 8, the &#8220;object
type&#8221; of a captured function is the type to which the reference
refers.  That's clearly wrong when the captured reference is a
reference to a function, because the resulting data member of the
closure class will have a function type:</P>

<PRE>
    void f() { }
    void g() {
      void (&amp;fr)() = f;
      [fr]{};   // Oops...
    }
</PRE>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="779"></A><H4>779.
  
Rvalue reference members of closure objects?
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>26 February, 2009<BR>


<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>

<P>5.1.2 [expr.prim.lambda] paragraph 8, bullet 2, says of members
of a closure class,</P>

<BLOCKQUOTE>

if the element is of the form <TT>&amp; N</TT>, the data member has
the name <TT>N</TT> and type &#8220;reference to object type of
<TT>N</TT>&#8221;

</BLOCKQUOTE>

<P>Is an implementation free to use an rvalue reference as the type
of this member, as only a &#8220;reference&#8221; is specified?
(See <A HREF="
     cwg_defects.html#771">issue 771</A>; the move constructor would
be well-formed if the reference member were an rvalue reference.)</P>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="782"></A><H4>782.
  
Lambda expressions and argument-dependent lookup
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>1 March, 2009<BR>


<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>

<P>Functions and function objects behave differently with respect to
argument-dependent lookup.  In particular, the associated namespaces
of a function's parameters and return types, but not the namespace
in which the function is declared, are associated namespaces of the
function; the exact opposite is true of a function object.  The
Committee should consider rectifying that disparity; however, in
the absence of such action, an explicit decision should be made as
to whether lambdas are more function-like or object-like with respect
to argument-dependent lookup.  For example:</P>

<PRE>
    namespace M {
      struct S { };
    }
    namespace N {
      void func(M::S);
      struct {
        void operator()(M::S);
      } fn_obj;
      const auto&amp; lambda = [](M::S){};
    }
    void g() {
      f(N::func);    // assoc NS == M, not N
      f(N::fn_obj);  // assoc NS == N, not M
      f(N::lambda);  // assoc NS == ??
    }
</PRE>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="796"></A><H4>796.
  
Lifetime of a closure object with members captured by reference
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>UK
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK40">N2800 comment
  UK&#160;40<BR></A>

<P>5.1.2 [expr.prim.lambda] paragraph 13 ties the effective lifetime
of a closure object with members captured by reference to the innermost
block scope in which the lambda appears, rather than to the lifetime of
the objects to which the references are bound.  This seems too
restrictive.</P>

<P><B>Notes from the March, 2009 meeting:</B></P>

<P>Making the suggested change would be problematic for an
implementation in which the &#8220;reference members&#8221; were
actually implemented using offsets from a captured stack pointer and
in which nested blocks were pushed onto the stack (to optimize space
for large local objects, for example).</P>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="797"></A><H4>797.
  
Converting a no-capture lambda to a function type
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>UK
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK42">N2800 comment
  UK&#160;42<BR></A>

<P>[Voted into WP at March, 2010 meeting as document N3052.]</P>

<P>A lambda with an empty capture list has
identical semantics to a regular function type. By
requiring this mapping we get an efficient lambda type with
a known API that is also compatible with existing operating
system and C library functions.</P>

<P><B>Notes from the July, 2009 meeting:</B></P>

<P>This functionality is part of the &#8220;unified function syntax&#8221;
proposal and will be considered in that context.</P>

<BR><BR><HR><A NAME="904"></A><H4>904.
  
Parameter packs in <I>lambda-capture</I>s
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Faisal Vali
 &#160;&#160;&#160;

 <B>Date: </B>23 May, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>The following is not allowed by the current syntax of
<I>lambda-capture</I> but would be useful:</P>

<PRE>
    template &lt;typename ...Args&gt; void f(Args... args) {
      auto l = [&amp;, args...] { return g(args...); };
    }
</PRE>

<P><B>Proposed resolution (October, 2009):</B></P>

<OL><LI><P>Change the grammar in 5.1.2 [expr.prim.lambda] paragraph
1 as follows:</P></LI>

<UL><I>capture-list:</I>
<UL><I>capture</I> <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>...</TT><I><SUB>opt</SUB></I></SPAN><BR>
<I>capture-list</I> <TT>,</TT> <I>capture</I> <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>...</TT><I><SUB>opt</SUB></I></SPAN>
</UL>
</UL>

<LI><P>Add a new paragraph at the end of 5.1.2 [expr.prim.lambda]:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">A <I>capture</I> followed by an ellipsis is a pack expansion
(14.5.3 [temp.variadic]). [<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">    template&lt;typename ...Args&gt;
    void f(Args... args) {
      auto l = [&amp;, args...] { return g(args...); };
      l();
    }
</SPAN></PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

<LI><P>Add a new bullet to the list in 14.5.3 [temp.variadic]
paragraph 4:</P></LI>

<UL><LI><SPAN style="font-weight:bold;background-color:#A0FFA0">In a <I>capture-list</I> (5.1.2 [expr.prim.lambda]);
the pattern is a <I>capture</I>.</SPAN></LI></UL>

<P><I>[Editorial note: the editor may wish to consider sorting the
bullets in this list in order of section reference.]</I></P>

</OL>

<BR><BR><HR><A NAME="955"></A><H4>955.
  
Can a closure type's <TT>operator()</TT> be virtual?
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>19 August, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>The specification of the members of a closure type does not rule out
the possibility that its <TT>operator()</TT> might be virtual.  It would
be better to make it clear that it cannot.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 5.1.2 [expr.prim.lambda] paragraph 5 as follows:</P>

<BLOCKQUOTE>

... followed by <TT>mutable</TT>. It is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">not</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">neither
virtual nor</SPAN> declared <TT>volatile</TT>. Default arguments...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="863"></A><H4>863.
  
Rvalue reference cast to incomplete type
</H4><B>Section: </B>5.2&#160; [expr.post]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>7 April, 2009<BR>


<P>[Voted into WP at March, 2010 meeting as document N3055.]</P>

<P>A cast to an rvalue reference type produces an rvalue, and rvalues
must have complete types (3.10 [basic.lval] paragraph 9).
However, none of the sections dealing with cast operators in
5.2 [expr.post] require that the referred-to type must be
complete in an rvalue reference cast.</P>

(Note that the approach described for <A HREF="
     cwg_defects.html#690">issue 690</A>,
in which an rvalue reference type would be essentially an lvalue instead
of an rvalue, would address this issue as well, since lvalues can have
incomplete types.)

<P><B>Proposed resolution (February, 2010):</B></P>

<P>See paper N3030.</P>

<BR><BR><HR><A NAME="722"></A><H4>722.
  
Can <TT>nullptr</TT> be passed to an ellipsis?
</H4><B>Section: </B>5.2.2&#160; [expr.call]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>25 September, 2008<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>The current wording of 5.2.2 [expr.call] paragraph 7 is:</P>

<BLOCKQUOTE>

After these conversions, if the argument does not have
arithmetic, enumeration, pointer, pointer to member, or effective
class type, the program is ill-formed.

</BLOCKQUOTE>

<P>It's not clear whether this is intended to exclude anything other
than <TT>void</TT>, but the effect is to disallow passing
<TT>nullptr</TT> to ellipsis.  That seems unnecessary.</P>

<P><B>Notes from the October, 2009 meeting:</B></P>

<P>The CWG agreed that this should be supported and the effect
should be like passing <TT>(void*)nullptr</TT>.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 5.2.2 [expr.call] paragraph 7 as follows:</P>

<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 <TT>va_arg</TT> (18.10 [support.runtime]). [<I>Note:</I> 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. &#8212;<I>end note</I>] The lvalue-to-rvalue
(4.1 [conv.lval]), array-to-pointer (4.2 [conv.array]), and function-to-pointer (4.3 [conv.func])
standard conversions are performed on the argument expression.
<SPAN style="font-weight:bold;background-color:#A0FFA0">An argument that has (possibly cv-qualified) type
<TT>std::nullptr_t</TT> is converted to type <TT>void*</TT>
(4.10 [conv.ptr]).</SPAN> After these conversions...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="731"></A><H4>731.
  
Omitted reference qualification of member function type
</H4><B>Section: </B>5.2.5&#160; [expr.ref]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>6 October, 2008<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#DE5">N2800 comment
  DE&#160;5<BR></A>
<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#DE10">N2800 comment
  DE&#160;10<BR></A>
<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#DE12">N2800 comment
  DE&#160;12<BR></A>

<P>[Voted into WP at October, 2009 meeting.]</P>



<P>There are several places in the Standard that were overlooked when
reference qualification of member functions was added.  For example,
5.2.5 [expr.ref] paragraph 4, bullet 3, sub-bullet 2 says,</P>

<BLOCKQUOTE>

...if <TT>E1.E2</TT> refers to a non-static member function, and the
type of <TT>E2</TT> is &#8220;function of parameter-type-list
<I>cv</I> returning <TT>T</TT>&#8221;, then...

</BLOCKQUOTE>

<P>This wording incorrectly excludes member functions declared with a
<I>ref-qualifier</I>.</P>

<P>Another place that should consider reference qualification is
5.5 [expr.mptr.oper]; it should not be possible to invoke an
&amp;-qualified member function with an rvalue object expression.</P>

<P>A third place is 7.3.3 [namespace.udecl] paragraph 15, which
does not mention reference qualification in connection with the
hiding/overriding of member functions brought in from a base class
via a <I>using-declaration</I>.</P>

<P><B>Proposed resolution (September, 2009):</B></P>

<OL><LI><P>Change 5.2.5 [expr.ref] paragraph 4, bullet 3,
sub-bullet 2 as follows:</P></LI>

<UL><LI><P>...</P></LI>

<UL><LI><P>...</P></LI>

<LI><P>Otherwise, if <TT>E1.E2</TT> refers to a non-static member
function and the type of <TT>E2</TT> is &#8220;function of
parameter-type-list <I>cv</I>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>ref-qualifier<SUB>opt</SUB></I></SPAN> returning
<TT>T</TT>&#8221;, then <TT>E1.E2</TT> is an rvalue.  The expression
designates a non-static member function...</P></LI>

</UL>

</UL>

<LI><P>Change 5.5 [expr.mptr.oper] paragraph 6 as follows:</P></LI>

<BLOCKQUOTE>

...&#8212;<I>end example</I>] <SPAN style="font-weight:bold;background-color:#A0FFA0">In a <TT>.*</TT> expression whose object
expression is an rvalue, if the second operand is a pointer to member
function with <I>ref-qualifier</I> <TT>&amp;</TT>, the program is
ill-formed. In a <TT>-&gt;*</TT> expression, or in a <TT>.*</TT>
expression whose object expression is an lvalue, if the second operand
is a pointer to member function with <I>ref-qualifier</I>
<TT>&amp;&amp;</TT>, the program is ill-formed.</SPAN>  The result of a
<TT>.*</TT> expression is an lvalue only if its first operand is an
lvalue and...

</BLOCKQUOTE>

<LI><P>Change 7.3.3 [namespace.udecl] paragraph 15 as follows:</P></LI>

<BLOCKQUOTE>

When a <I>using-declaration</I> brings names from a base class into a
derived class scope, member functions and member function templates in
the derived class override and/or hide member functions and member
function templates with the same name, parameter-type-list
(8.3.5 [dcl.fct]), <SPAN style="text-decoration:line-through;background-color:#FFA0A0">and</SPAN> cv-qualification<SPAN style="font-weight:bold;background-color:#A0FFA0">, and
<I>ref-qualifier</I> (if any)</SPAN> in a base class (rather than
conflicting). [<I>Note:</I>...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="665"></A><H4>665.
  
Problems in the specification of <TT>dynamic_cast</TT>
</H4><B>Section: </B>5.2.7&#160; [expr.dynamic.cast]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>1 December 2007<BR>


<P>[Voted into the WP at the March, 2009 meeting.]</P>

<P>At least one implementation accepts the following example as
well-formed (returning a null pointer at runtime), although others
reject it at compile time:</P>

<PRE>
    struct A { virtual ~A(); };
    struct B: private A { } b;
    A* pa = dynamic_cast&lt;A*&gt;(&amp;b);
</PRE>

<P>Presumably the intent of 5.2.7 [expr.dynamic.cast] paragraph 5
is that all up-casts (converting from derived to base) are to be
handled at compile time, regardless of whether the class involved is
polymorphic or not:</P>

<BLOCKQUOTE>

If <TT>T</TT> is &#8220;pointer to <I>cv1</I> <TT>B</TT>&#8221;
and <TT>v</TT> has type &#8220;pointer to <I>cv2</I> <TT>D</TT>&#8221;
such that <TT>B</TT> is a base class of <TT>D</TT>, the result is a
pointer to the unique <TT>B</TT> subobject of the <TT>D</TT> object
pointed to by <TT>v</TT>. Similarly, if <TT>T</TT> is &#8220;reference
to <I>cv1</I> <TT>B</TT>&#8221; and <TT>v</TT> has
type <I>cv2</I> <TT>D</TT> such that <TT>B</TT> is a base class
of <TT>D</TT>, the result is the unique <TT>B</TT> subobject of
the <TT>D</TT> object referred to by <TT>v</TT>... In both the pointer
and reference cases, <I>cv1</I> shall be the same cv-qualification as,
or greater cv-qualification than, <I>cv2</I>, and <TT>B</TT> shall be
an accessible unambiguous base class of <TT>D</TT>.

</BLOCKQUOTE>

<P>One explanation for the implementation that accepts the example at
compile time is that the final sentence is interpreted as part of the
condition for the applicability of this paragraph, so that this case
falls through into the description of runtime checking that follows.
This (mis-)interpretation is buttressed by the example in paragraph 9,
which reads in significant part:</P>

<PRE>
    class A { virtual void f(); };
    class B { virtual void g(); };
    class D : public virtual A, private B {};
    void g() {
        D d;
        B* bp;
        bp = dynamic_cast&lt;B*&gt;(&amp;d); //<SPAN style="font-family:Times;font-style:italic"> fails</SPAN>
    }
</PRE>

<P>The &#8220;fails&#8221; comment is identical to the commentary on
the lines in the example where the run-time check fails.  If the
interpretation that paragraph 5 is supposed to apply to all up-casts,
presumably this comment should change to &#8220;ill-formed,&#8221; or
the line should be removed from the example altogether.</P>

<P>It should be noted that this interpretation (that the example is
ill-formed and the runtime check applies only to down-casts and
cross-casts) rejects some programs that could plausibly be accepted
and actually work at runtime.  For example,</P>

<PRE>
    struct B { virtual ~B(); };
    struct D: private virtual B { };

    void test(D* pd) {
        B* pb = dynamic_cast&lt;B*&gt;(pd); // #1
    }

    struct D2: virtual B, virtual D {};

    void demo() {
        D2 d2;
        B* pb = dynamic_cast&lt;B*&gt;(&amp;d2); // #2
        test(&amp;d2); // #3
    }
</PRE>

<P>According to the interpretation that paragraph 5 applies,
line #1 is ill-formed.  However, converting from <TT>D2</TT> to
<TT>B</TT> (line #2) is well-formed; if the alternate interpretation
were applied, the conversion in line #1 could succeed when applied
to <TT>d2</TT> (line #3).</P>

<P>One final note: the wording in 5.2.7 [expr.dynamic.cast]
paragraph 8 is incorrect:</P>

<BLOCKQUOTE>

<P>The run-time check logically executes as follows:</P>

<UL>
<LI><P>If, in the most derived object pointed (referred) to
by <TT>v</TT>, <TT>v</TT> points (refers) to a <TT>public</TT> base
class subobject of a <TT>T</TT> object, and if only one object of
type <TT>T</TT> is derived from the subobject pointed (referred) to by
<TT>v</TT> the result is a pointer (an lvalue referring) to
that <TT>T</TT> object.</P></LI>

<LI><P>Otherwise, if <TT>v</TT> points (refers) to a <TT>public</TT>
base class subobject of the most derived object, and the type of the
most derived object has a base class, of type <TT>T</TT>, that is
unambiguous and <TT>public</TT>, the result is a pointer (an lvalue
referring) to the <TT>T</TT> subobject of the most derived
object.</P></LI>

<LI><P>Otherwise, the run-time check fails.</P></LI>
</UL>

</BLOCKQUOTE>

<P>All uses of <TT>T</TT> in this paragraph treat it as if it were
a class type; in fact, <TT>T</TT> is the type to which the expression
is being cast and thus is either a pointer type or a reference type,
not a class type.</P>

<P><B>Proposed resolution (June, 2008):</B></P>

<OL><LI><P>Change 5.2.7 [expr.dynamic.cast] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

...In both the pointer and reference cases, <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>cv1</I> shall be the
same cv-qualification as, or greater cv-qualification than,
<I>cv2</I>, and <TT>B</TT> shall be an accessible unambiguous base
class of <TT>D</TT></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">the program is ill-formed if <I>cv2</I> is
greater cv-qualification than <I>cv1</I> or if <TT>B</TT> is an
inaccessible or ambiguous base class of <TT>D</TT></SPAN>.

</BLOCKQUOTE>

<LI><P>Change the comment in the example in 5.2.7 [expr.dynamic.cast]
paragraph 9 as follows:</P></LI>

<PRE>
    bp = dynamic_cast&lt;B*&gt;(&amp;d);     //<SPAN style="font-family:Times;font-style:italic"> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">fails</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">ill-formed (not a run-time check)</SPAN></SPAN>
</PRE>

<LI><P>Change 5.2.7 [expr.dynamic.cast] paragraph 8 as follows:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">The</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">If <TT>C</TT> is the class type to which <TT>T</TT>
points or refers, the</SPAN> run-time check logically executes as
follows:</P>

<UL><LI><P>If, in the most derived object pointed (referred) to by
<TT>v</TT>, <TT>v</TT> points (refers) to a public base class
subobject of a <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>T</TT></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>C</TT></SPAN> object, and if only
one object of type <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>T</TT></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>C</TT></SPAN> is derived from
the subobject pointed (referred) to by <TT>v</TT> the result is a
pointer (an lvalue referring) to that <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>T</TT></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>C</TT></SPAN> object.</P></LI>

<LI><P>Otherwise, if <TT>v</TT> 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 <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>T</TT></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>C</TT></SPAN>,
that is unambiguous and public, the result is a pointer (an lvalue
referring) to the <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>T</TT></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>C</TT></SPAN> subobject of the
most derived object.</P></LI>

<LI><P>Otherwise, the run-time check fails.</P></LI>

</UL>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="833"></A><H4>833.
  
Explicit conversion of a scoped enumeration value to a floating type
</H4><B>Section: </B>5.2.9&#160; [expr.static.cast]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>6 March, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>The current wording of 5.2.9 [expr.static.cast] paragraph 9 does
not permit conversion of a value of a scoped enumeration type to a
floating point type.  This was presumably an oversight during the
specification of scoped enumerations and should be rectified.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 5.2.9 [expr.static.cast] paragraph 9 as follows:</P>

<BLOCKQUOTE>

A value of a scoped enumeration type (7.2 [dcl.enum]) can be
explicitly converted to an integral type.  The value is unchanged if
the original value can be represented by the specified type.
Otherwise, the resulting value is unspecified. <SPAN style="font-weight:bold;background-color:#A0FFA0">A value of a
scoped enumeration type can also be explicitly converted to a floating
point type; the result is the same as that of converting from the
original value to the floating point type.</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="658"></A><H4>658.
  
Defining <TT>reinterpret_cast</TT> for pointer types
</H4><B>Section: </B>5.2.10&#160; [expr.reinterpret.cast]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Dave Abrahams
 &#160;&#160;&#160;

 <B>Date: </B>4 November 2007<BR>


<P>[Voted into the WP at the March, 2009 meeting.]</P>

<P>For years I've noticed that people will write code like this to get
the address of an object's bytes:</P>

<PRE>
  void foo(long* p) {
      char* q = reinterpret_cast&lt;char*&gt;(p);  // #1
      // do something with the bytes of *p by using q
  }
</PRE>

<P>When in fact the only portable way to do it according to the standard
is:</P>

<PRE>
  void foo(long* p) {
      char* q = static_cast&lt;char*&gt;(static_cast&lt;void*&gt;(p));  // #2
      // do something with the bytes of *p by using q
  }
</PRE>

<P>I thought <TT>reinterpret_cast</TT> existed so that vendors could
provide some weird platform-specific things.  However, recently Peter
Dimov pointed out to me that if we substitute a class type
for <TT>long</TT> above, <TT>reinterpret_cast</TT> is required to work as
expected by 9.2 [class.mem] paragraph 18:</P>

<BLOCKQUOTE>

A pointer to a standard-layout struct object, suitably converted using
a <TT>reinterpret_cast</TT>, points to its initial member (or if that
member is a bit-field, then to the unit in which it resides) and vice
versa.

</BLOCKQUOTE>

<P>So there isn't a whole lot of flexibility to do something different
and useful on non-class types.  Are there any implementations for
which #1 actually fails?  If not, I think it would be a good idea to
nail <TT>reinterpret_cast</TT> down so that the standard says it does
what people (correctly) think it does in practice.</P>

<P><B>Proposed resolution (March, 2008):</B></P>

<P>Change 5.2.10 [expr.reinterpret.cast] paragraph 7 as indicated:</P>

<BLOCKQUOTE>

A pointer to an object can be explicitly converted to a pointer to an
object of different type. <SPAN style="font-weight:bold;background-color:#A0FFA0">When an rvalue <TT>v</TT> of type
&#8220;pointer to <TT>T1</TT>&#8221; is converted to the type
&#8220;pointer to <I>cv</I> <TT>T2</TT>,&#8221; the result is
<TT>static_cast&lt;</TT><I>cv</I> <TT>T2*&gt;(static_cast&lt;</TT><I>cv</I> <TT>void*&gt;(v))</TT>
if both <TT>T1</TT> and <TT>T2</TT> are standard-layout types
(3.9 [basic.types]) and the alignment requirements of
<TT>T2</TT> are no stricter than those of <TT>T1</TT>.</SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Except that c</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">C</SPAN>onverting an rvalue of type
&#8220;pointer to <TT>T1</TT>&#8221; to the type &#8220;pointer
to <TT>T2</TT>&#8221; (where <TT>T1</TT> and <TT>T2</TT> are object
types and where the alignment requirements of <TT>T2</TT> are no
stricter than those of <TT>T1</TT>) and back to its original type
yields the original pointer value<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, t</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">. T</SPAN>he result of
<SPAN style="font-weight:bold;background-color:#A0FFA0">any other</SPAN> such <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a</SPAN> pointer conversion is unspecified.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="734"></A><H4>734.
  
Are unique addresses required for namespace-scope variables?
</H4><B>Section: </B>5.2.10&#160; [expr.reinterpret.cast]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>15 October, 2008<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>Consider the following example:</P>

<PRE>
    static const char test1 = 'x';
    static const char test2 = 'x';
    bool f() {
        return &amp;test1 != &amp;test2;
    }
</PRE>

<P>Is <TT>f()</TT> allowed to return <TT>false</TT>?  Can a smart
optimizer alias these two variables, taking advantage of the fact that
they are <TT>const</TT>, initialized to the same value, and thus can
never be different in a well-defined program?</P>

<P>The C++ Standard doesn't explicitly specify address allocation of
objects except as members of arrays and classes, so the answer would
appear to be that such an implementation would be conforming.</P>

<P>This situation appears to have been the inadvertent result of
the resolution of <A HREF="
     cwg_defects.html#73">issue 73</A>. Prior to that
change, 5.10 [expr.eq] said,</P>

<BLOCKQUOTE>

Two pointers of the same type compare equal if and only if they...
both point to the same object...

</BLOCKQUOTE>

<P>That resolution introduced the current wording,</P>

<BLOCKQUOTE>

Two pointers of the same type compare equal if and only if... both
represent the same address.

</BLOCKQUOTE>

<P><B>Notes from the March, 2009 meeting:</B></P>

<P>The CWG agreed that this aliasing should not be permitted in
a conforming implementation.</P>

<P><B>Proposed resolution (November, 2009):</B></P>

<OL><LI><P>Add the following as a new paragraph after 1.8 [intro.object] paragraph 5:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">Unless an object is a bit-field or a base class subobject
of zero size, the address of that object is the address of the
first byte it occupies. Two distinct objects that are neither
bit-fields nor base class subobjects of zero size shall have
distinct addresses [<I>Footnote:</I> Under the &#8220;as-if&#8221;
rule an implementation is allowed to store two objects at the
same machine address or not store an object at all if the program
cannot observe the difference (1.9 [intro.execution]). &#8212;<I>end footnote</I>].
[<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  static const char test1 = 'x';
  static const char test2 = 'x';
  const bool b = &amp;test1 != &amp;test2;   //<SPAN style="font-family:Times;font-style:italic"> always true</SPAN></SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

<LI><P>Change 5.3.1 [expr.unary.op] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

The result of the unary <TT>&amp;</TT> operator is a pointer to
its operand. The operand shall be an lvalue or a
<I>qualified-id</I>. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">In the first case, if the type of the
expression is &#8220;<TT>T</TT>,&#8221; the type of the result is
&#8220;pointer to <TT>T</TT>.&#8221; In particular, the address
of an object of type &#8220;<I>cv</I> <TT>T</TT>&#8221; is
&#8220;pointer to <I>cv</I> <TT>T</TT>,&#8221; with the same
cv-qualifiers. For a <I>qualified-id</I>, if the member is a
static member of type &#8220;<TT>T</TT>&#8221;, the type of the
result is plain &#8220;pointer to <TT>T</TT>.&#8221; If the
member is a non-static member of class <TT>C</TT> of type
<TT>T</TT>, the type of the result is &#8220;pointer to member of
class <TT>C</TT> of type <TT>T</TT>.&#8221;</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">If the
operand is a <I>qualified-id</I> naming a non-static member
<TT>m</TT> of some class <TT>C</TT> with type <TT>T</TT>, the
result has type &#8220;pointer to member of class <TT>C</TT> of
type <TT>T</TT>&#8221; and is an rvalue designating
<TT>C::m</TT>.  Otherwise, if the type of the expression is
<TT>T</TT>, the result has type &#8220;pointer to
<TT>T</TT>&#8221; and is an rvalue that is the address of the
designated object (1.7 [intro.memory]) or a pointer to the
designated function. [<I>Note:</I> In particular, the address of
an object of type &#8220;<I>cv</I> <TT>T</TT>&#8221; is
&#8220;pointer to <I>cv</I> <TT>T</TT>,&#8221; with the same
cv-qualification. &#8212;<I>end note</I>]</SPAN> [<I>Example:</I>...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="799"></A><H4>799.
  
Can <TT>reinterpret_cast</TT> be used to cast an operand to its own type?
</H4><B>Section: </B>5.2.10&#160; [expr.reinterpret.cast]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>UK
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK55">N2800 comment
  UK&#160;55<BR></A>

<P>[Voted into WP at March, 2010 meeting.]</P>

<P>The note in 5.2.10 [expr.reinterpret.cast] paragraph 2 says,</P>

<BLOCKQUOTE>

Subject to the restrictions in this section, an expression may be cast
to its own type using a <TT>reinterpret_cast</TT> operator.

</BLOCKQUOTE>

<P>However, there is nothing in the normative text that permits this
conversion, and paragraph 1 forbids any conversion not explicitly
permitted.</P>

<P>(See also <A HREF="
     cwg_active.html#944">issue 944</A>.)</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<OL><LI><P>Change 5.2.10 [expr.reinterpret.cast] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

The <TT>reinterpret_cast</TT> operator shall not cast away constness
(5.2.11 [expr.const.cast]).  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">[<I>Note:</I> Subject to the
restrictions in this section, an expression may be cast to its own
type using a <TT>reinterpret_cast</TT> operator. &#8212;<I>end
note</I>]</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">An expression of integral, enumeration, pointer,
or pointer-to-member type can be explictly converted to its own type;
such a cast yields the value of its operand.</SPAN>

</BLOCKQUOTE>

<LI><P>Change 5.2.10 [expr.reinterpret.cast] paragraph 10 as follows:</P></LI>

<BLOCKQUOTE>

An rvalue of type &#8220;pointer to member of <TT>X</TT> of type
<TT>T1</TT>&#8221; can be explicitly converted to an rvalue of <SPAN style="font-weight:bold;background-color:#A0FFA0">a
different</SPAN> type &#8220;pointer to member of <TT>Y</TT> of type
<TT>T2</TT>&#8221; if <TT>T1</TT> and <TT>T2</TT> are both function
types or both object types...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="842"></A><H4>842.
  
Casting to rvalue reference type
</H4><B>Section: </B>5.2.10&#160; [expr.reinterpret.cast]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>20 March, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>Both <TT>const_cast</TT> (5.2.11 [expr.const.cast] paragraph 1) and
<TT>reinterpret_cast</TT> (5.2.10 [expr.reinterpret.cast] paragraph 1) say,</P>

<BLOCKQUOTE>

If <TT>T</TT> is an lvalue reference type, the result is an lvalue;
otherwise, the result is an rvalue and the lvalue-to-rvalue
(4.1 [conv.lval]), array-to-pointer (4.2 [conv.array]), and function-to-pointer (4.3 [conv.func])
standard conversions are performed on the expression <TT>v</TT>.

</BLOCKQUOTE>

<P>This introduces a contradiction in the text.  According to
5.2.11 [expr.const.cast] paragraph 4,</P>

<BLOCKQUOTE>

The result of a reference <TT>const_cast</TT> refers to the original
object.

</BLOCKQUOTE>

<P>However, the lvalue-to-rvalue conversion applied to the operand
when the target is an rvalue reference type creates a temporary if
the operand has class type (4.1 [conv.lval] paragraph 2),
meaning that the result will <B>not</B> refer to the original
object but to the temporary.</P>

<P>A similar problem exists for <TT>reinterpret_cast</TT>: according
to 5.2.10 [expr.reinterpret.cast] paragraph 11,</P>

<BLOCKQUOTE>

a reference cast <TT>reinterpret_cast&lt;T&amp;&gt;(x)</TT> has the
same effect as the conversion
<TT>*reinterpret_cast&lt;T*&gt;(&amp;x)</TT> with the built-in
<TT>&amp;</TT> and <TT>*</TT> operators (and similarly for
<TT>reinterpret_cast&lt;T&amp;&amp;&gt;(x)</TT>).  The result refers
to the same object as the source lvalue, but with a different type.

</BLOCKQUOTE>

<P>Here the issue is that the unary <TT>&amp;</TT> operator used
in the description requires an lvalue, but the lvalue-to-rvalue
conversion is applied to the operand when the target is an
rvalue reference type.</P>

<P>It would seem that the lvalue-to-rvalue conversion should not
be applied when the target of the cast is an rvalue reference type.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<OL><LI><P>Change 5.2.10 [expr.reinterpret.cast] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

The result of the expression <TT>reinterpret_cast&lt;T&gt;(v)</TT> is
the result of converting the expression <TT>v</TT> to type
<TT>T</TT>. If <TT>T</TT> is an lvalue reference type, the result is
an lvalue; <SPAN style="font-weight:bold;background-color:#A0FFA0">if <TT>T</TT> is an rvalue reference type, the result
is an rvalue;</SPAN> otherwise, the result is an rvalue and the
lvalue-to-rvalue (4.1 [conv.lval]), array-to-pointer
(4.2 [conv.array]), and function-to-pointer (4.3 [conv.func]) standard conversions are performed on the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the</SPAN>
expression <TT>v</TT>.  Conversions that can be performed explicitly
using <TT>reinterpret_cast</TT> are listed below.  No other conversion
can be performed explicitly using <TT>reinterpret_cast</TT>.

</BLOCKQUOTE>

<LI><P>Change 5.2.11 [expr.const.cast] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

The result of the expression <TT>const_cast&lt;T&gt;(v)</TT> is of
type <TT>T</TT>. If <TT>T</TT> is an lvalue reference type, the result
is an lvalue; <SPAN style="font-weight:bold;background-color:#A0FFA0">if <TT>T</TT> is an rvalue reference type, the
result is an rvalue;</SPAN> otherwise, the result is an rvalue and the
lvalue-to-rvalue (4.1 [conv.lval]), array-to-pointer
(4.2 [conv.array]), and function-to-pointer (4.3 [conv.func]) standard conversions are performed on the expression
<TT>v</TT>.  Conversions that can be performed explicitly using
<TT>const_cast</TT> are listed below.  No other conversion shall be
performed explicitly using <TT>const_cast</TT>.

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="801"></A><H4>801.
  
Casting away constness in a cast to rvalue reference type
</H4><B>Section: </B>5.2.11&#160; [expr.const.cast]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>UK
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK58">N2800 comment
  UK&#160;58<BR></A>

<P>[Voted into WP at October, 2009 meeting.]</P>

<P>The rules in 5.2.11 [expr.const.cast] paragraphs 8 and following,
defining &#8220;casting away constness,&#8221; do not cover a cast to
an rvalue reference type.</P>

<P><B>Proposed resolution (September, 2009):</B></P>

<P>Change 5.2.11 [expr.const.cast] paragraph 9 as follows:</P>

<BLOCKQUOTE>

Casting from an lvalue of type <TT>T1</TT> to an lvalue of type
<TT>T2</TT> using <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an lvalue</SPAN> reference
cast<SPAN style="font-weight:bold;background-color:#A0FFA0">, or casting from an expression of type <TT>T1</TT> to an
rvalue of type <TT>T2</TT> using an rvalue reference cast,</SPAN> casts
away constness if a cast from an rvalue of type &#8220;pointer to
<TT>T1</TT>&#8221; to the type &#8220;pointer to <TT>T2</TT>&#8221;
casts away constness.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="891"></A><H4>891.
  
<TT>const_cast</TT> to rvalue reference from objectless rvalue
</H4><B>Section: </B>5.2.11&#160; [expr.const.cast]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>8 May, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>5.2.11 [expr.const.cast] paragraph 4 says,</P>

<BLOCKQUOTE>

...Similarly, for two effective object types <TT>T1</TT> and
<TT>T2</TT>, an expression of type <TT>T1</TT> can be explicitly
converted to an rvalue of type <TT>T2</TT> using the cast
<TT>const_cast&lt;T2&amp;&amp;&gt;</TT> if a pointer to <TT>T1</TT> can be
explicitly converted to the type &#8220;pointer to <TT>T2</TT>&#8221;
using a <TT>const_cast</TT>. The result of a reference
<TT>const_cast</TT> refers to the original object.

</BLOCKQUOTE>

<P>However, in some rvalue-reference <TT>const_cast</TT>s there is
no &#8220;original object,&#8221; e.g.,</P>

<PRE>
    const_cast&lt;int&amp;&amp;&gt;(2)
</PRE>

<P><B>Notes from the July, 2009 meeting:</B></P>

<P>The coresponding cast to an lvalue reference to const is ill-formed:
in such cases, the operand must be an lvalue.  The consensus of the
CWG was that a cast to an rvalue reference should only accept an rvalue
that is an rvalue reference (i.e., an object).</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 5.2.11 [expr.const.cast] paragraph 4 as follows:</P>

<BLOCKQUOTE>

An lvalue of type <TT>T1</TT> can be explicitly converted to an
lvalue of type <TT>T2</TT> using the cast
<TT>const_cast&lt;T2&amp;&gt;</TT> (where <TT>T1</TT> and
<TT>T2</TT> are object types) if a pointer to <TT>T1</TT> can be
explicitly converted to the type &#8220;pointer to
<TT>T2</TT>&#8221; using a <TT>const_cast</TT>.  Similarly, for
two object types <TT>T1</TT> and <TT>T2</TT>, an
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">expression</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">lvalue</SPAN> of type <TT>T1</TT>
<SPAN style="font-weight:bold;background-color:#A0FFA0">or, if <TT>T1</TT> is a class type, an expression of type
<TT>T1</TT>,</SPAN> can be explicitly converted to an rvalue of
type <TT>T2</TT> using the cast
<TT>const_cast&lt;T2&amp;&amp;&gt;</TT> if a pointer to
<TT>T1</TT> can be explicitly converted to the type
&#8220;pointer to <TT>T2</TT>&#8221; using a <TT>const_cast</TT>.
The result of a reference <TT>const_cast</TT> refers to the
original object.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="983"></A><H4>983.
  
Ambiguous pointer-to-member constant
</H4><B>Section: </B>5.3.1&#160; [expr.unary.op]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>19 October, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>The resolution of issue 39 changed the diagnosis of ambiguity
because of multiple subobjects from being a lookup error to being
diagnosed where the result of the lookup is used.  The formation of a
pointer to member is one such context but was overlooked in the
changes.  5.3.1 [expr.unary.op] paragraph 3 should have language
similar to 5.2.5 [expr.ref] paragraph 5 and should be
mentioned in the note in 10.2 [class.member.lookup] paragraph 13.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<OL><LI><P>Change 5.3.1 [expr.unary.op] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

...For a <I>qualified-id</I>, if the member is a static member of type
&#8220;<TT>T</TT>&#8221;, the type of the result is plain
&#8220;pointer to <TT>T</TT>.&#8221; If the member is a non-static
member of class <TT>C</TT> of type <TT>T</TT>, the type of the result
is &#8220;pointer to member of class <TT>C</TT> of type
<TT>T</TT><SPAN style="text-decoration:line-through;background-color:#FFA0A0">.</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">,</SPAN>&#8221; <SPAN style="font-weight:bold;background-color:#A0FFA0">and the program is
ill-formed if <TT>C</TT> is an ambiguous base (10.2 [class.member.lookup]) of the class designated by the
<I>nested-name-specifier</I> of the <I>qualified-id</I>.</SPAN>...

</BLOCKQUOTE>

<LI><P>Change 10.2 [class.member.lookup] paragraph 13 as follows:</P></LI>

<BLOCKQUOTE>

[<I>Note:</I> Even if the result of name lookup is unambiguous, use of
a name found in multiple subobjects might still be ambiguous
(4.11 [conv.mem], 5.2.5 [expr.ref],
<SPAN style="font-weight:bold;background-color:#A0FFA0">5.3.1 [expr.unary.op],</SPAN> 11.2 [class.access.base]). &#8212;<I>end note</I>] [<I>Example:</I>...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="803"></A><H4>803.
  
<TT>sizeof</TT> an enumeration type with a fixed underlying type
</H4><B>Section: </B>5.3.3&#160; [expr.sizeof]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>UK
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK70">N2800 comment
  UK&#160;70<BR></A>

<P>[Voted into WP at October, 2009 meeting.]</P>

<P>There is no reason for the prohibition of using <TT>sizeof</TT>
on &#8220;an enumeration type before all its enumerators have been
declared&#8221; (5.3.3 [expr.sizeof] paragraph 1) if the
underlying type of the enumeration is fixed.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 5.3.3 [expr.sizeof] paragraph 1 as follows:</P>

<BLOCKQUOTE>

...The <TT>sizeof</TT> operator shall not be applied to an expression
that has function or incomplete type, or to an enumeration type
<SPAN style="font-weight:bold;background-color:#A0FFA0">whose underlying type is not fixed</SPAN> before all its
enumerators have been declared, or to the parenthesized name of such
types, or to an lvalue that designates a bit-field...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="672"></A><H4>672.
  
Sequencing of initialization in <I>new-expression</I>s
</H4><B>Section: </B>5.3.4&#160; [expr.new]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Clark Nelson
 &#160;&#160;&#160;

 <B>Date: </B>11 January, 2008<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>Consider the following code, which uses double-checked locking
(DCL):</P>

<PRE>
    Widget* Widget::Instance() {
      if (pInstance == 0) {           //<SPAN style="font-family:Times;font-style:italic"> 1: first check</SPAN>
        lock&lt;mutex&gt; hold(mutW);       //<SPAN style="font-family:Times;font-style:italic"> 2: acquire lock</SPAN>
        if (pInstance == 0) {         //<SPAN style="font-family:Times;font-style:italic"> 3: second check</SPAN>
          pInstance = new Widget();   //<SPAN style="font-family:Times;font-style:italic"> 4: create and assign</SPAN>
        }
      }                               //<SPAN style="font-family:Times;font-style:italic"> 5: release lock</SPAN>
    }
</PRE>

<P>We want this to be fully correct when <TT>pInstance</TT> is an
atomic pointer to <TT>Widget</TT>. To get that result, we have to
disallow any assignment to <TT>pInstance</TT> until after the new
object is fully constructed. In other words, we want this to be an
invalid transformation of line 4:</P>

<PRE>
    pInstance = operator new(sizeof(Widget));
    new (pInstance) Widget;
</PRE>

<P>I don't think it would be surprising if this were disallowed. For
example, if the constructor were to throw an exception, I think many
people would expect the variable not to be modified. I think the
question is whether it's sufficiently clearly disallowed.</P>

<P>This could be clarified by stating (somewhere appropriate &#8212;
probably either in 5.3.4 [expr.new] paragraph 16 or
paragraph 22) that the initialization of the allocated object is
sequenced before the value computation of the <I>new-expression</I>.
Then by 5.17 [expr.ass] paragraph 1 (&#8220;In all cases,
the assignment is sequenced after the value computation of the right
and left operands, and before the value computation of the assignment
expression.&#8221;), the initialization would have to be sequenced
before the assignment.</P>

<P>This is probably not a problem for <TT>atomic&lt;Widget*&gt;</TT>
because its <TT>operator=</TT> is a function, and function calls
provide the necessary guarantees.  But for the plain pointer
assignment case, there's still a question about whether the sequencing
of side effects is constrained as tightly as it should be. In fact,
you don't even have to throw an exception from the constructor for
there to be a question.</P>

<PRE>
    struct X {
        static X* p;
        X();
    };

    X* X::p = new X;
</PRE>

<P>When the constructor for <TT>X</TT> is invoked by this
<I>new-expression</I>, would it be valid for <TT>X::p</TT> to be
non-null? If the answer is supposed to be &#8220;no,&#8221; then I
think the Standard should express that intent more clearly.</P>

<P><B>Proposed resolution (March, 2008):</B></P>

<P>Change 5.3.4 [expr.new] paragraph 22 as indicated:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Whether</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Initialization of the allocated object is sequenced
before the value computation of the <I>new-expression</I>.  It is
unspecified whether</SPAN> the allocation function is called before
evaluating the constructor arguments or after evaluating the
constructor arguments but before entering the constructor<SPAN style="text-decoration:line-through;background-color:#FFA0A0"> is
unspecified</SPAN>. It is also unspecified whether the arguments to a
constructor are evaluated if the allocation function returns the null
pointer or exits using an exception.

</BLOCKQUOTE>

<P><I>[Drafting note: The editor may wish to move paragraph 22 up to
immediately follow paragraph 16 or 17.  The paragraphs numbered 18-21
deal with the case where deallocation is done because initialization
terminates with an exception, whereas paragraph 22 applies more to the
initialization itself, described in paragraph 16.]</I></P>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>The proposed wording does not (but should) allow the call to
the allocation function to occur in the middle of evaluating
arguments for the constructor call.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 5.3.4 [expr.new] paragraph 21 as follows:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Whether the allocation function is called before evaluating the
constructor arguments or after evaluating the constructor arguments
but before entering the constructor is unspecified.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">The
invocation of the allocation function is indeterminately sequenced
with respect to the evaluations of expressions in the
<I>new-initializer</I>. Initialization of the allocated object is
sequenced before the value computation of the
<I>new-expression</I>.</SPAN> It is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">also</SPAN> unspecified whether
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">the arguments to a constructor</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">expressions in the
<I>new-initializer</I></SPAN> are evaluated if the allocation function
returns the null pointer or exits using an exception.

</BLOCKQUOTE>

<P><I>[Drafting note: the editor may wish to consider moving this
paragraph to follow paragraph 15 or 16.  Paragraphs 17-19 deal with
the case where deallocation is done because initialization terminates
with an exception, whereas this paragraph applies more to the
initialization itself (described in paragraph 15).]</I></P>

<BR><BR><HR><A NAME="804"></A><H4>804.
  
Deducing the type in <TT>new auto(x)</TT>
</H4><B>Section: </B>5.3.4&#160; [expr.new]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>UK
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK71">N2800 comment
  UK&#160;71<BR></A>

<P>[Voted into WP at October, 2009 meeting.]</P>

<P>
The type of an allocated object wih the
type specifier <TT>auto</TT> is determined by the rules of copy
initialization, but the initialization applied will be
direct initialization. This would affect classes which
declare their copy constructor explicit, for instance. For
consistency, use the same form of initiailization for the
deduction as the new expression.
</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 5.3.4 [expr.new] paragraph 2 as follows:</P>

<BLOCKQUOTE>

<P>If the <TT>auto</TT> <I>type-specifier</I> appears in the
<I>type-specifier-seq</I> of a <I>new-type-id</I> or <I>type-id</I> of a
<I>new-expression</I>, the <I>new-expression</I> shall contain a
<I>new-initializer</I> of the form</P>

<UL><TT>(</TT> <I>assignment-expression</I> <TT>)</TT></UL>

<P>The allocated type is deduced from the <I>new-initializer</I> as
follows: Let <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>(e)</TT> be</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>e</TT> be the
<I>assignment-expression</I> in</SPAN> the <I>new-initializer</I> and
<TT>T</TT> be the <I>new-type-id</I> or <I>type-id</I> of the
<I>new-expression</I>, then the allocated type is the type deduced for
the variable <TT>x</TT> in the invented declaration (7.1.6.4 [dcl.spec.auto]):</P>

<UL><TT>T <SPAN style="text-decoration:line-through;background-color:#FFA0A0">x = e</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">x(e)</SPAN>;</TT></UL>

<P>[<I>Example:</I>...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="805"></A><H4>805.
  
Which exception to throw for overflow in array size calculation
</H4><B>Section: </B>5.3.4&#160; [expr.new]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>UK
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK72">N2800 comment
  UK&#160;72<BR></A>
<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK192">N2800 comment
  UK&#160;192<BR></A>

<P>[Voted into WP at July, 2009 meeting as part of N2932.]</P>

<P>Throwing <TT>std::length_error</TT> (5.3.4 [expr.new]
paragraph 7) for an attempt to allocate a too-large array brings in
too much of the Standard library. A simpler exception, like
<TT>std::bad_alloc</TT>, should be thrown instead.</P>

<P><B>Notes from the March, 2009 meeting:</B></P>

<P>The CWG was in favor of throwing an exception derived from
<TT>std::bad_alloc</TT>.  This would be upwardly compatible; it
would be harmless for programs that currently catch
<TT>std::bad_alloc</TT>, but would allow programs to treat the
calculation overflow case separately if they wish.</P>

<BR><BR><HR><A NAME="599"></A><H4>599.
  
Deleting a null function pointer
</H4><B>Section: </B>5.3.5&#160; [expr.delete]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Martin Sebor
 &#160;&#160;&#160;

 <B>Date: </B>3 October 2006<BR>


<P>[Voted into WP at July, 2009 meeting.]</P>

<P>The requirements for the operand of the <TT>delete</TT> operators are
given in 5.3.5 [expr.delete] paragraph 2:</P>

<BLOCKQUOTE>

In either alternative, the value of the operand of <TT>delete</TT> may
be a null pointer value. If it is not a null pointer value, in the
first alternative (<I>delete object</I>), the value of the operand
of <TT>delete</TT> shall be a pointer to a non-array object or a
pointer to a subobject (1.8 [intro.object]) representing a
base class of such an object (clause 10 [class.derived]). If not,
the behavior is undefined. In the second alternative (<I>delete
array</I>), the value of the operand of <TT>delete</TT> shall be the
pointer value which resulted from a previous
array <I>new-expression</I>. If not, the behavior is undefined.

</BLOCKQUOTE>

<P>There are no restrictions on the type of a null pointer, only on
a pointer that is not null.  That seems wrong.</P>

<P><B>Proposed resolution (June, 2008):</B></P>

<P>Change 5.3.5 [expr.delete] paragraph 1 as follows:</P>

<BLOCKQUOTE>

...The operand shall have a pointer <SPAN style="font-weight:bold;background-color:#A0FFA0">to object</SPAN> type, or a
class type having a single non-explicit conversion function
(12.3.2 [class.conv.fct]) to a pointer
<SPAN style="font-weight:bold;background-color:#A0FFA0">to object</SPAN> type...

</BLOCKQUOTE>

<P><B>Proposed resolution (September, 2008):</B></P>

<OL><LI><P>Change 5.3.5 [expr.delete] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...The operand shall have a pointer <SPAN style="font-weight:bold;background-color:#A0FFA0">to object</SPAN> type, or a
class type having a single non-explicit conversion function
(12.3.2) to a pointer <SPAN style="font-weight:bold;background-color:#A0FFA0">to object</SPAN> type. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Footnote:</I>
This implies that an object cannot be deleted using a pointer of
type <TT>void*</TT> because <TT>void</TT> is not an object type.
&#8212;<I>end footnote</I>]</SPAN> ...

</BLOCKQUOTE>

<LI><P>Delete the footnote at the end of 5.3.5 [expr.delete]
paragraph 3:</P></LI>

<BLOCKQUOTE>

...if the dynamic type of the object to be deleted differs from
its static type, the behavior is undefined. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">[<I>Footnote:</I>
This implies that an object cannot be deleted using a pointer of
type <TT>void*</TT> because there are no objects of type
<TT>void</TT>. &#8212;<I>end footnote</I>]</SPAN>

</BLOCKQUOTE>
</OL>

<BR><BR><HR><A NAME="930"></A><H4>930.
  
<TT>alignof</TT> with incomplete array type
</H4><B>Section: </B>5.3.6&#160; [expr.alignof]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>6 July, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>5.3.6 [expr.alignof] paragraph 1 currently says regarding
<TT>alignof</TT>,</P>

<BLOCKQUOTE>

The operand shall be a <I>type-id</I> representing a complete
effective object type or a reference to a complete effective object
type.

</BLOCKQUOTE>

<P>This prohibits taking the alignment of an array type with an
unknown bound.  There doesn't appear to be any reason for this
restriction.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 5.3.6 [expr.alignof] paragraph 1 as follows:</P>

<BLOCKQUOTE>

The operand shall be a type-id representing a complete effective
object type <SPAN style="font-weight:bold;background-color:#A0FFA0">or an array thereof</SPAN> or a reference to a
complete effective object type.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="854"></A><H4>854.
  
Left shift and unsigned extended types
</H4><B>Section: </B>5.8&#160; [expr.shift]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>5 April, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>According to 5.8 [expr.shift] paragraph 2,</P>

<BLOCKQUOTE>

The value of <TT>E1 &lt;&lt; E2</TT> is <TT>E1</TT> (interpreted as a
bit pattern) left-shifted <TT>E2</TT> bit positions; vacated bits are
zero-filled.  If <TT>E1</TT> has an unsigned type, the value of the
result is <TT>E1</TT> multiplied by the quantity 2 raised to the power
<TT>E2</TT>, reduced modulo <TT>ULLONG_MAX+1</TT> if <TT>E1</TT> has
type <TT>unsigned long long int</TT>, <TT>ULONG_MAX+1</TT> if
<TT>E1</TT> has type <TT>unsigned long int</TT>, <TT>UINT_MAX+1</TT>
otherwise.

</BLOCKQUOTE>

<P>This specification does not allow for extended types with rank
greater than <TT>long long</TT>; in particular, it says that the
value of a shifted unsigned extended type is truncated as if it were
the same width as an <TT>unsigned int</TT>.</P>

<P>It's unclear that the second sentence has any normative value; it
might be better to relegate it to a note or omit it than to correct
it.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 5.8 [expr.shift] paragraphs 2-3 as follows:</P>

<BLOCKQUOTE>

<P>The value of <TT>E1 &lt;&lt; E2</TT> is <TT>E1</TT>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">(interpreted as a bit pattern)</SPAN> left-shifted <TT>E2</TT> bit
positions; vacated bits are zero-filled.  If <TT>E1</TT> has an
unsigned type, the value of the result is <TT>E1</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">multiplied
by the quantity 2 raised to the power <TT>E2</TT></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">&#215;
2<SUP><TT>E2</TT></SUP></SPAN>, reduced modulo
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>ULLONG_MAX+1</TT> if <TT>E1</TT> has type <TT>unsigned long
long int</TT>, <TT>ULONG_MAX+1</TT> if <TT>E1</TT> has type
<TT>unsigned long int</TT>, <TT>UINT_MAX+1</TT> otherwise.
[<I>Note:</I> the constants <TT>ULLONG_MAX</TT>, <TT>ULONG_MAX</TT>,
and <TT>UINT_MAX</TT> are defined in the header
<TT>&lt;climits&gt;</TT>. &#8212;<I>end note</I>]</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">one more
than the maximum value representable in the result type.  Otherwise,
if <TT>E1</TT> has a signed type and nonnegative value, and
<TT>E1</TT> &#215; 2<SUP><TT>E2</TT></SUP> is representable in the
result type, then that is the resulting value; otherwise, the behavior
is undefined.</SPAN></P>

<P>The value of <TT>E1 &gt;&gt; E2</TT> is <TT>E1</TT> right-shifted
<TT>E2</TT> bit positions. If <TT>E1</TT> has an unsigned type or if
<TT>E1</TT> has a signed type and a nonnegative value, the value of
the result is the integral part of the quotient of <TT>E1</TT>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">divided by the quantity 2 raised to the power <TT>E2</TT></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">/ 2<SUP><TT>E2</TT></SUP></SPAN>.  If <TT>E1</TT> has a signed
type and a negative value, the resulting value is
implementation-defined.</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="963"></A><H4>963.
  
Comparing <TT>nullptr</TT> with 0
</H4><B>Section: </B>5.9&#160; [expr.rel]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>8 September, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>The current wording of the draft does not indicate what is supposed
to happen when an rvalue of type <TT>std::nullptr_t</TT> is compared
with an integral null pointer constant.  (This could occur, for example,
in template code like</P>

<PRE>
    template&lt;typename T&gt; void f(T t) {
        if (t == 0) // ...
    }
</PRE>

<P>in a call like <TT>f(nullptr)</TT> -- presumably the body of the
template was written before <TT>nullptr</TT> became available and
thus used an integral null pointer constant.)  Because an
integral null pointer constant can be converted to <TT>std::nullptr_t</TT>
(4.10 [conv.ptr] paragraph 1), one might expect that 0
would be converted to <TT>std::nullptr_t</TT> and the two operands
would compare equal, but 5.9 [expr.rel] paragraph 2 does
not handle this case at all, leaving it as undefined behavior.</P>

<P>The current situation is more well-defined (but perhaps not
better) with respect to the conditional operator.
5.16 [expr.cond] paragraphs 3-6 make it ill-formed to
have <TT>std::nullptr_t</TT> and 0 as the second and third
operands.  Again, it's not too hard to imagine a legacy function
template like</P>

<PRE>
    template&lt;typename T&gt; void f(T t, bool b) {
        T t = b ? t : 0;
    }
</PRE>

<P>which would be ill-formed under the current wording of
5.16 [expr.cond].</P>

<P>Either 5.9 [expr.rel] and 5.10 [expr.eq]
should be changed to make this combination of operands ill-formed,
or those two sections should be changed to give the comparison
defined semantics and 5.16 [expr.cond] should be changed
to make those operands well-formed.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<OL><LI><P>Change 5.9 [expr.rel] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

The usual arithmetic conversions are performed on operands of
arithmetic or enumeration type.  Pointer conversions (4.10 [conv.ptr]) and qualification conversions (4.4 [conv.qual])
are performed on pointer operands (or on a pointer operand and a null
pointer constant<SPAN style="font-weight:bold;background-color:#A0FFA0">, or on two null pointer constants, at least one
of which is non-integral</SPAN>) to bring them to their composite
pointer type.  If one operand is a null pointer constant, the
composite pointer type is <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>std::nullptr_t</TT> if the other
operand is also a null pointer constant or, if the other operand is a
pointer,</SPAN> the type of the other operand. Otherwise...

</BLOCKQUOTE>

<LI><P>Change 5.16 [expr.cond] paragraph 6 bullet 3 as
follows:</P></LI>

<UL><LI>The second and third operands have pointer type, or one has
pointer type and the other is a null pointer constant<SPAN style="font-weight:bold;background-color:#A0FFA0">, or both
are null pointer constants, at least one of which is
non-integral</SPAN>; pointer conversions (4.10 [conv.ptr])
and qualification conversions (4.4 [conv.qual]) are performed
to bring them to their composite pointer type (5.9 [expr.rel]). The result is of the composite pointer type.</LI>

</UL>

</OL>

<BR><BR><HR><A NAME="587"></A><H4>587.
  
Lvalue operands of a conditional expression differing only in cv-qualification
</H4><B>Section: </B>5.16&#160; [expr.cond]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Howard Hinnant
 &#160;&#160;&#160;

 <B>Date: </B>20 June 2006<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>Consider the following example:</P>

<PRE>
    template &lt;typename T&gt;
    const T* f(bool b) {
        static T t1 = T();
        static const T t2 = T();
        return &amp;(b ? t1 : t2);  // error?
    }
</PRE>

<P>According to 5.16 [expr.cond], this function is
well-formed if <TT>T</TT> is a class type and ill-formed
otherwise.  If the second and third operands of a conditional
expression are lvalues of the same class type except for
cv-qualification, the result of the conditional expression is
an lvalue; if they are lvalues of the same non-class type
except for cv-qualification, the result is an rvalue.</P>

<P>This difference seems gratuitous and should be removed.</P>

<P><B>Proposed resolution (June, 2009):</B></P>

<P>Change 5.16 [expr.cond] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<P>Otherwise, if the second and third operand have different types,
and either has (possibly cv-qualified) class type, <SPAN style="font-weight:bold;background-color:#A0FFA0">or if both are
lvalues of the same type except for cv-qualification,</SPAN> an attempt
is made to convert each of those operands to the type of the other.
The process for determining whether an operand expression <TT>E1</TT>
of type <TT>T1</TT> can be converted to match an operand expression
<TT>E2</TT> of type <TT>T2</TT> is defined as follows:</P>

<UL><LI><P>If <TT>E2</TT> is an lvalue: <TT>E1</TT> can be converted
to match <TT>E2</TT> if <TT>E1</TT> can be implicitly converted
(Clause 4 [conv]) to the type &#8220;lvalue reference to
<TT>T2</TT>&#8221;, subject to the constraint that in the conversion
the reference must bind directly (8.5.3 [dcl.init.ref]) to
<TT>E1</TT>.</P></LI>

<LI><P>If <TT>E2</TT> is an rvalue, or if the conversion above cannot
be done <SPAN style="font-weight:bold;background-color:#A0FFA0">and at least one of the operands has (possibly
cv-qualified) class type</SPAN>:</P></LI>

<UL><LI><P>...</P></LI></UL>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="556"></A><H4>556.
  
Conflicting requirements for acceptable aliasing
</H4><B>Section: </B>5.17&#160; [expr.ass]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>30 January 2006<BR>


<P>[Voted into the WP at the March, 2009 meeting.]</P>

<P>There appear to be two different specifications for when aliasing
is permitted.  One is in 3.10 [basic.lval] paragraph 15:</P>

<BLOCKQUOTE>

<P>If a program attempts to access the stored value of an object through
an lvalue of other than one of the following types the behavior is
undefined</P>

<UL>
<LI><P>the dynamic type of the object,</P></LI>

<LI><P>a cv-qualified version of the dynamic type of the
object,</P></LI>

<LI><P>a type similar (as defined in 4.4 [conv.qual]) to
the dynamic type of the object,</P></LI>

<LI><P>a type that is the signed or unsigned type corresponding to the
dynamic type of the object,</P></LI>

<LI><P>a type that is the signed or unsigned type corresponding to a
cv-qualified version of the dynamic type of the object,</P></LI>

<LI><P>an aggregate or union type that includes one of the
aforementioned types among its members (including, recursively, a
member of a subaggregate or contained union),</P></LI>

<LI><P>a type that is a (possibly cv-qualified) base class type of the
dynamic type of the object,</P></LI>

<LI><P>a <TT>char</TT> or <TT>unsigned char</TT> type.</P></LI>

</UL>

</BLOCKQUOTE>

<P>There is also a much more restrictive specification in
5.17 [expr.ass] paragraph 8:</P>

<BLOCKQUOTE>

If the value being stored in an object is accessed from another object
that overlaps in any way the storage of the first object, then the
overlap shall be exact and the two objects shall have the same type,
otherwise the behavior is undefined.

</BLOCKQUOTE>

<P>This affects, for example, the definedness of operations
on union members: when may a value be stored into one union
member and accessed via another.</P>

<P>It should be noted that this conflict existed in C90 and is
unchanged in C99 (see, for example, section 6.5 paragraph 7 and
section 6.5.16.1 paragraph 3 of ISO/IEC 9899:1999, which directly
parallel the sections cited above).</P>

<P><B>Notes from the October, 2006 meeting:</B></P>

<P>This issue is based on a misunderstanding of the intent of the
wording in 5.17 [expr.ass] paragraph 8.  Instead of
being a general statement about aliasing, it's describing the
situation in which the source of the value being assigned is storage
that overlaps the storage of the target object.  The proposed
resolution should make that clearer rather than changing the
specification.</P>

<P><B>Proposed resolution (June, 2008):</B></P>

<P>Add the following note at the end of 5.17 [expr.ass]
paragraph 8:</P>

<BLOCKQUOTE>

If the value being stored in an object is accessed from another object
that overlaps in any way the storage of the first object, then the
overlap shall be exact and the two objects shall have the same type,
otherwise the behavior is undefined. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> This restriction
applies to the relationship between the left and right sides of the
assignment operation; it is not a statement about how the target of
the assignment may be aliased in general. See 3.10 [basic.lval]. &#8212;<I>end note</I>]</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="855"></A><H4>855.
  
Incorrect comments in <I>braced-init-list</I> assignment example
</H4><B>Section: </B>5.17&#160; [expr.ass]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>5 April, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P><section_re ref="5.17">5.17 [expr.ass]</section_re> paragraph 9 has the following example:</P>

<PRE>
    complex&lt;double&gt; z;
    z = { 1,2 };      //<SPAN style="font-family:Times;font-style:italic"> meaning </SPAN>z.operator=(1,2)
    z += { 1, 2 };    //<SPAN style="font-family:Times;font-style:italic"> meaning </SPAN>z.operator+=(1,2)
</PRE>

<P>These comments make it look as if the assignment operator takes two
arguments, which is obviously not the case.  It would be better if the
comments read something like</P>

<PRE>
     //<SPAN style="font-family:Times;font-style:italic"> meaning </SPAN>z.operator=(complex&lt;double&gt;(1,2))
</PRE>

<P>or even</P>

<PRE>
    //<SPAN style="font-family:Times;font-style:italic"> meaning </SPAN>z.operator=({1,2})<SPAN style="font-family:Times;font-style:italic">, resolves to</SPAN>
    //<SPAN style="font-family:Times;font-style:italic"> </SPAN>z.operator=(complex&lt;double&gt;(1,2)
</PRE>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change the example in 5.17 [expr.ass] paragraph 9 as
follows:</P>

<BLOCKQUOTE>

<P>[<I>Example:</I></P>

<PRE>
  complex&lt;double&gt; z;
  z = { 1,2 };        //<SPAN style="font-family:Times;font-style:italic"> meaning </SPAN>z.operator=(<SPAN style="font-weight:bold;background-color:#A0FFA0">{</SPAN>1,2<SPAN style="font-weight:bold;background-color:#A0FFA0">}</SPAN>)
  z += { 1, 2 };      //<SPAN style="font-family:Times;font-style:italic"> meaning </SPAN>z.operator+=(<SPAN style="font-weight:bold;background-color:#A0FFA0">{</SPAN>1,2<SPAN style="font-weight:bold;background-color:#A0FFA0">}</SPAN>)
<SPAN style="font-weight:bold;background-color:#A0FFA0">  int a, b;</SPAN>
  a = b = { 1 };      //<SPAN style="font-family:Times;font-style:italic"> meaning </SPAN>a=b=1;
  a = { 1 } = b;      //<SPAN style="font-family:Times;font-style:italic"> syntax error</SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="652"></A><H4>652.
  
Compile-time evaluation of floating-point expressions
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Jens Maurer
 &#160;&#160;&#160;

 <B>Date: </B>3 October 2007<BR>


<P>[Voted into the WP at the March, 2009 meeting.]</P>



<P>It was the intention of the constexpr proposal that implementations
be required to evaluate floating-point expressions at compile time.
This intention is not reflected in the actual wording of
5.19 [expr.const] paragraph 2, bullet 5:</P>

<UL><LI>

a type conversion from a floating-point type to an integral type
(4.9 [conv.fpint]) unless the conversion is directly applied
to a floating-point literal;

</LI></UL>

<P>This restriction has the effect of forbidding the use of
floating-point expressions in integral constant expressions.</P>

<P><B>Proposed resolution (June, 2008):</B></P>

<P>Delete bullet 6 of 5.19 [expr.const] paragraph 2:</P>

<UL><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><LI>a type conversion from a floating-point type to an integral
type (4.9 [conv.fpint]) unless the conversion is directly
applied to a floating-point literal;</LI></SPAN></UL>

<P><B>Notes from the June, 2008 meeting:</B></P>

<P>The CWG agreed with the intent of this issue, that floating-point
calculations should be permitted in constant expressions, but acknowledged
that this opens the possibility of differing results between compile
time and run time. Such issues should be addressed non-normatively,
e.g., via a &#8220;recommended practice&#8221; note like that of C99's
6.4.4.2 or in a technical report.</P>

<P><B>Proposed resolution (August, 2008):</B></P>

<OL>
<LI><P>Delete bullet 6 of 5.19 [expr.const] paragraph 2:</P></LI>

<UL><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><LI>a type conversion from a floating-point type to an integral
type (4.9 [conv.fpint]) unless the conversion is directly
applied to a floating-point literal;</LI></SPAN></UL>

<LI><P>Add a new paragraph after 5.19 [expr.const]
paragraph 3:</P></LI>

<BLOCKQUOTE>

<P>[<I>Note:</I> Although in some contexts constant expressions must be
evaluated during program translation, others may be evaluated during
program execution.  Since this International Standard imposes no
restrictions on the accuracy of floating-point operations, it is
unspecified whether the evaluation of a floating-point expression
during translation yields the same result as the evaluation of the
same expression (or the same operations on the same values) during
program execution. [<I>Footnote:</I> Nonetheless, implementations are
encouraged to provide consistent results, irrespective of whether the
evaluation was actually performed during translation or during program
execution. &#8212;<I>end footnote</I>] [<I>Example:</I></P>

<PRE>
  bool f() {
    char array[1 + int(1 + 0.2 - 0.1 - 0.1)];  //<SPAN style="font-family:Times;font-style:italic"> Must be evaluated during translation</SPAN>
    int size = 1 + int(1 + 0.2 - 0.1 - 0.1);   //<SPAN style="font-family:Times;font-style:italic"> May be evaluated at runtime</SPAN>
    return sizeof(array) == size;
  }
</PRE>

<P>It is unspecified whether the value of <TT>f()</TT> will be
<TT>true</TT> or <TT>false</TT>. &#8212;<I>end example</I>]
&#8212;<I>end note</I>]</P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="715"></A><H4>715.
  
Class member access constant expressions
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>17 September, 2008<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>Bullet 12 of paragraph 2 of 5.19 [expr.const] says,</P>

<UL><LI><P>a class member access (5.2.5 [expr.ref])
unless its <I>postfix-expression</I> is of effective literal type
or of pointer to effective literal type;</P></LI></UL>

<P>This wording needs to be clearer that the &#8220;effective
literal type&#8221; provision applies only to the <TT>.</TT>
form of member access and the &#8220;pointer to effective
literal type&#8221; applies only to the <TT>-&gt;</TT> form.</P>

<P><B>Proposed resolution (March, 2009):</B></P>

<P>Delete 5.19 [expr.const] paragraph 2 bullet 11:</P>

<UL><LI><SPAN style="text-decoration:line-through;background-color:#FFA0A0">a class member access (5.2.5 [expr.ref]) unless
its postfix-expression is of effective literal type or of pointer to
effective literal type;</SPAN></LI></UL>

<BR><BR><HR><A NAME="721"></A><H4>721.
  
Where must a variable be initialized to be used in a constant expression?
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>James Kanze
 &#160;&#160;&#160;

 <B>Date: </B>22 September, 2008<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>5.19 [expr.const] paragraph 2 allows an
lvalue-to-rvalue conversion in a constant expression if it is
applied to &#8220;an lvalue of effective integral type that
refers to a non-volatile const variable or static data member
initialized with constant expressions.&#8221;  However, this
does not require, as it presumably should, that the
initialization occur in the same translation unit and precede
the constant expression, nor that the static data member be
initialized within the <I>member-specification</I> of its
class.</P>

<P><B>Proposed resolution (March, 2009):</B></P>

<P>Change <secton_ref ref="5.19">5.19 [expr.const]</secton_ref> paragraph 2, bullet 4,
sub-bullet 1 as follows:</P>

<UL><LI><P>an lvalue of effective integral type that refers to a
non-volatile const variable <SPAN style="font-weight:bold;background-color:#A0FFA0">with a preceding
initialization</SPAN> or <SPAN style="font-weight:bold;background-color:#A0FFA0">to a non-volatile const</SPAN> static data
member <SPAN style="font-weight:bold;background-color:#A0FFA0">with an initialization in the class definition
(9.4.2 [class.static.data]), in either case</SPAN> initialized with
constant expressions, or</P></LI></UL>

<P><B>Additional note, June, 2009:</B></P>

<P>It has been suggested that the requirement that a static
data member be initialized in the class definition is not actually
needed but that static data members should be treated like other
variable declarations -- a preceding definition with initialization
should be sufficient.  That is, given</P>

<PRE>
    extern const int i;
    const int i = 5;
    struct S {
      static const int j;
    };
    const int S::j = 5;
    int a1[i];
    int a2[S::j];
</PRE>

<P>there doesn't appear to be a good rationale for making <TT>a1</TT>
well-formed and <TT>a2</TT> ill-formed.  Some major implementations
accept the declaration of <TT>a2</TT> without error.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 5.19 [expr.const] paragraph 2, bullet 4,
sub-bullet 1 as follows:</P>

<UL><LI>an lvalue of effective integral type that refers to a
non-volatile const variable <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or static data member</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">with
a preceding initialization,</SPAN> initialized with <SPAN style="font-weight:bold;background-color:#A0FFA0">a</SPAN>
constant expression<SPAN style="text-decoration:line-through;background-color:#FFA0A0">s</SPAN>, or</LI></UL>

<BR><BR><HR><A NAME="806"></A><H4>806.
  
Enumeration types in integral constant expressions
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>UK
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK50">N2800 comment
  UK&#160;50<BR></A>

<P>[Voted into WP at October, 2009 meeting.]</P>

<P>According to 5.19 [expr.const] paragraph 2, bullet 4,
sub-bullet 1, a non-volatile const variable or static data member
initialized with constant expressions can be used in an integral
constant expression only if it is &#8220;of effective integral
type.&#8221; Unscoped enumeration types should also be accepted in
such contexts.</P>

<P><B>Proposed resolution (September, 2009):</B></P>

<P>Change 5.19 [expr.const] paragraph 2, bullet 4, sub-bullet 1
as indicated:</P>

<UL><LI><P>an lvalue-to-rvalue conversion (4.1 [conv.lval])
unless it is applied to</P></LI>

<UL><LI><P>an lvalue of effective integral <SPAN style="font-weight:bold;background-color:#A0FFA0">or enumeration</SPAN>
type that refers to a non-volatile const variable or static data
member initialized with constant expressions, or</P></LI>

<LI><P>...</P></LI>

</UL>

</UL>

<BR><BR><HR><A NAME="1010"></A><H4>1010.
  
Address of object with dynamic storage duration in constant expression
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>2009-12-02<BR>


<P>[Voted into WP at March, 2010 meeting as part of document N3078.]</P>

<P>5.19 [expr.const] paragraph 2 prohibits the unary <TT>&amp;</TT>
operator and an array-to-pointer conversion on operands with automatic
and thread storage duration, but operands with dynamic storage duration
are apparently allowed.  Both these operations should be allowed only
on operands with static storage duration.</P>

<BR><BR><HR><A NAME="569"></A><H4>569.
  
Spurious semicolons at namespace scope should be allowed
</H4><B>Section: </B>7&#160; [dcl.dcl]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Matt Austern
 &#160;&#160;&#160;

 <B>Date: </B>20 March 2006<BR>


<P>[Voted into the WP at the March, 2009 meeting.]</P>

<P>The grammar in 7 [dcl.dcl] paragraph 1 says that a
<I>declaration-seq</I> is either <I>declaration</I>
or <I>declaration-seq declaration</I>. Some declarations end with
semicolons and others (e.g. function definitions and namespace
declarations) don't. This means that users who put a semicolon after
every declaration are technically writing ill-formed code. The trouble
is that in this respect the standard is out of sync with reality. It's
convenient to allow semicolons after every declaration, and there's no
implementation difficulty in doing so. All existing compilers accept
this, except in extra-pedantic mode. When all implementations disagree
with the standard, it's time for the standard to change.</P>

<P>Suggested resolution:</P>

<P>In the grammar in 7 [dcl.dcl] paragraph 11, change the
second line in the definition of <I>declaration-seq</I> to</P>

<UL><I>declaration-seq</I> <TT>;</TT><I><SUB>opt</SUB> declaration</I></UL>

<P><B>Proposed resolution (October, 2006):</B></P>

<OL>
<LI><P>Add the indicated lines to the grammar definitions in
7 [dcl.dcl] paragraph 1:</P></LI>

<BLOCKQUOTE>

<I>declaration:</I><BR>
<UL>
...<BR>
<I>namespace-definition</I><BR>
<I><SPAN style="font-weight:bold;background-color:#A0FFA0">empty-declaration</SPAN></I>
</UL>
<BR>
...
<BR><BR>
<I>static_assert-declaration:</I><BR>
<UL>
<TT>static_assert ( </TT><I>constant-expression</I><TT> , </TT>
<I>string-literal</I><TT> ) ;</TT>
</UL>
<BR><BR>
<SPAN style="font-weight:bold;background-color:#A0FFA0">
<I>empty-declaration:</I><BR>
<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>;</TT></SPAN></UL>
</SPAN>

</BLOCKQUOTE>

<LI><P>Add the following as a new paragraph after 7 [dcl.dcl]
paragraph 4:</P></LI>

<BLOCKQUOTE>

An <I>empty-declaration</I> has no effect.

</BLOCKQUOTE>
</OL>

<BR><BR><HR><A NAME="808"></A><H4>808.
  
Non-type <I>decl-specifier</I>s versus max-munch
</H4><B>Section: </B>7.1&#160; [dcl.spec]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>UK
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK83">N2800 comment
  UK&#160;83<BR></A>

<P>[Voted into WP at March, 2010 meeting.]</P>

<P>According to 7.1 [dcl.spec] paragraph 2,</P>

<BLOCKQUOTE>

The longest sequence of <I>decl-specifier</I>s that could
possibly be a type name is taken as the
<I>decl-specifier-seq</I> of a <I>declaration</I>.

</BLOCKQUOTE>

<P>However, there are many <I>decl-specifier</I>s that cannot appear
in a type name that are, nonetheless, part of a <I>declaration</I>'s
<I>decl-specifier-seq</I>, such as <TT>typedef</TT>, <TT>friend</TT>,
<TT>static</TT>, etc.</P>

<P><B>Proposed resolution (November, 2009):</B></P>

<P>Change 7.1 [dcl.spec] paragraph 2 as follows:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The longest sequence of <I>decl-specifier</I>s that could
possibly be a type name is taken as the <I>decl-specifier-seq</I> of a
<I>declaration</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">If a <I>type-name</I> is encountered while
parsing a <I>decl-specifier-seq</I>, it is interpreted as part of the
<I>decl-specifier-seq</I> if and only if there is no previous
<I>type-specifier</I> other than a <I>cv-qualifier</I> in the
<I>decl-specifier-seq</I>.</SPAN>. The sequence shall be
self-consistent as described below. [<I>Example:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="717"></A><H4>717.
  
Unintentional restrictions on the use of <TT>thread_local</TT>
</H4><B>Section: </B>7.1.1&#160; [dcl.stc]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Clark Nelson
 &#160;&#160;&#160;

 <B>Date: </B>17 September, 2008<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#US36">N2800 comment
  US&#160;36<BR></A>

<P>[Voted into WP at October, 2009 meeting.]</P>

<P>The current wording unintentionally restricts the use of the
<TT>thread_local</TT> specifier in two contexts: block-scope
extern variable declarations and static data members.  These
restrictions are in conflict with 7.1.1 [dcl.stc]
paragraph 1.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 7.1.1 [dcl.stc] paragraph 4 as follows:</P>

<BLOCKQUOTE>

 The <TT>thread_local</TT> specifier shall be applied only to the
names of objects or references of namespace scope<SPAN style="text-decoration:line-through;background-color:#FFA0A0">
and</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">,</SPAN> to the names of objects or references of block
scope that also specify <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>extern</TT> or</SPAN>
<TT>static</TT><SPAN style="font-weight:bold;background-color:#A0FFA0">, and to the names of static data
members</SPAN>. It specifies that the named object or reference has
thread storage duration (3.7.2 [basic.stc.thread]).

</BLOCKQUOTE>

<BR><BR><HR><A NAME="809"></A><H4>809.
  
Deprecation of the <TT>register</TT> keyword
</H4><B>Section: </B>7.1.1&#160; [dcl.stc]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>UK
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK86">N2800 comment
  UK&#160;86<BR></A>

<P>[Voted into WP at October, 2009 meeting.]</P>

<P>
The <TT>register</TT>
keyword serves very little function, offering no more than
a hint that a note says is typically ignored. It should be
deprecated in this version of the standard, freeing the
reserved name up for use in a future standard, much like
<TT>auto</TT> has been re-used this time around for being similarly
useless.
</P>

<P><B>Notes from the March, 2009 meeting:</B></P>

<P>The consensus of the CWG was in favor of deprecating
<TT>register</TT>.</P>

<P><B>Proposed resolution (September, 2009):</B></P>

<OL><LI><P>Change 7.1.1 [dcl.stc] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

A <TT>register</TT> specifier is a hint to the implementation that the
object so declared will be heavily used. [<I>Note:</I> the hint can be
ignored and in most implementations it will be ignored if the address
of the object is taken. <SPAN style="font-weight:bold;background-color:#A0FFA0">This use is deprecated (see
[depr.register]).</SPAN> &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Add a new section following _N3000_.D.4 [depr.string]:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">register keyword  [depr.register]</SPAN></P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">The use of the <TT>register</TT> keyword as a
<I>storage-class-specifier</I> is deprecated (see 7.1.1 [dcl.stc]).</SPAN></P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="810"></A><H4>810.
  
Block-scope <TT>thread_local</TT> variables should be implicitly <TT>static</TT>
</H4><B>Section: </B>7.1.1&#160; [dcl.stc]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>UK
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK87">N2800 comment
  UK&#160;87<BR></A>

<P>[Voted into WP at March, 2010 meeting.]</P>

<P>According to 7.1.1 [dcl.stc] paragraph 4,</P>

<BLOCKQUOTE>

The <TT>thread_local</TT> specifier shall be applied only to the names
of objects or references of namespace scope and to the names of
objects or references of block scope that also specify
<TT>static</TT>.

</BLOCKQUOTE>

<P>
Why require two keywords, where one on its own becomes ill-formed?
<TT>thread_local</TT> should imply <TT>static</TT> in this case, and
the combination of keywords should be banned rather than
required. This would also eliminate the one of two exceptions
documented in paragraph 1.
</P>

<P><B>Notes from the July, 2009 meeting:</B></P>

<P>The consensus of the CWG was that <TT>thread_local</TT> should
imply <TT>static</TT>, as suggested, but that the combination should
still be allowed (it is needed, for example, for thread-local static
data members).</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 7.1.1 [dcl.stc] paragraph 4 as follows:</P>

<BLOCKQUOTE>

The <TT>thread_local</TT> specifier <SPAN style="font-weight:bold;background-color:#A0FFA0">indicates that the named
entity has thread storage duration (3.7.2 [basic.stc.thread]).
It</SPAN> shall be applied only to the names of objects or references
of namespace <SPAN style="text-decoration:line-through;background-color:#FFA0A0">scope, to the names of objects or references
of</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">or</SPAN> block scope <SPAN style="text-decoration:line-through;background-color:#FFA0A0">that also specify
<TT>extern</TT> or <TT>static</TT>,</SPAN> and to the names of static
data members. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">It specifies that the named object or reference has
thread storage duration (3.7.2 [basic.stc.thread]).</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">When
<TT>thread_local</TT> is applied to a variable of block scope the
<I>storage-class-specifier</I> <TT>static</TT> is implied if it does
not appear explicitly.</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="940"></A><H4>940.
  
Global anonymous unions
</H4><B>Section: </B>7.1.1&#160; [dcl.stc]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>UK
 &#160;&#160;&#160;

 <B>Date: </B>14 July, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK85">N2800 comment
  UK&#160;85<BR></A>

<P>[Voted into WP at October, 2009 meeting.]</P>

<P>7.1.1 [dcl.stc] paragraph 1 refers to &#8220;global
anonymous unions.&#8221; This reference should include anonymous unions
declared in a named namespace, not just in global scope (cf
9.5 [class.union] paragraph 3).</P>

<P><B>Proposed resolution (September, 2009):</B></P>

<P>Change 7.1.1 [dcl.stc] paragraph 1 as follows:</P>

<BLOCKQUOTE>

If a <I>storage-class-specifier</I> appears in a

<I>decl-specifier-seq</I>, there can be no <TT>typedef</TT> specifier
in the same <I>decl-specifier-seq</I> and the
<I>init-declarator-list</I> of the declaration shall not be empty
(except for <SPAN style="text-decoration:line-through;background-color:#FFA0A0">global</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an</SPAN> anonymous
union<SPAN style="text-decoration:line-through;background-color:#FFA0A0">s</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">declared in a named namespace or in the global
namespace</SPAN>, which shall be declared <TT>static</TT> (9.5))...


</BLOCKQUOTE>

<BR><BR><HR><A NAME="765"></A><H4>765.
  
Local types in inline functions with external linkage
</H4><B>Section: </B>7.1.2&#160; [dcl.fct.spec]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>6 February, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>7.1.2 [dcl.fct.spec] paragraph 4 specifies that local static
variables and string literals appearing in the body of an inline
function with external linkage must be the same entities in every
translation unit in the program.  Nothing is said, however, about
whether local types are likewise required to be the same.</P>

<P>Although a conforming program could always have determined this
by use of <TT>typeid</TT>, recent changes to C++ (allowing local types
as template type arguments, lambda expression closure classes) make this
question more pressing.
</P>

<P><B>Notes from the July, 2009 meeting:</B></P>

<P>The types are intended to be the same.</P>

<P><B>Proposed resolution (November, 2009):</B></P>

<P>Change 7.1.2 [dcl.fct.spec] paragraph 4 as follows:</P>

<BLOCKQUOTE>

...A <TT>static</TT> local variable in an <TT>extern inline</TT>
function always refers to the same object.  A string literal in the
body of an <TT>extern inline</TT> function is the same object in
different translation units.  [<I>Note:</I> A string literal
appearing in a default argument expression is not in the body of an
inline function merely because the expression is used in a function
call from that inline function. &#8212;<I>end note</I>] <SPAN style="font-weight:bold;background-color:#A0FFA0">A type
defined within the body of an <TT>extern inline</TT> function is the
same type in every translation unit.</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="576"></A><H4>576.
  
Typedefs in function definitions
</H4><B>Section: </B>7.1.3&#160; [dcl.typedef]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Jon Caves
 &#160;&#160;&#160;

 <B>Date: </B>21 April 2006<BR>


<P>[Voted into the WP at the March, 2009 meeting.]</P>

<P>7.1.3 [dcl.typedef] paragraph 1 says,</P>

<BLOCKQUOTE>

The <TT>typedef</TT> specifier shall not be used in
a <I>function-definition</I> (8.4 [dcl.fct.def])...

</BLOCKQUOTE>

<P>Does this mean that the following is ill-formed?</P>

<PRE>
    void f() {
        typedef int INT;
    }
</PRE>

<P><B>Proposed resolution (March, 2008):</B></P>

<P>Change 7.1.3 [dcl.typedef] paragraph 1 as follows:</P>

<BLOCKQUOTE>

...The <TT>typedef</TT> specifier <SPAN style="text-decoration:line-through;background-color:#FFA0A0">shall not be used in a
<I>function-definition</I> (8.4 [dcl.fct.def]), and it</SPAN>
shall not be combined in a <I>decl-specifier-seq</I> with any
other kind of specifier except a <I>type-specifier</I><SPAN style="font-weight:bold;background-color:#A0FFA0">, and it
shall not be used in the declaration of a function parameter nor
in the <I>decl-specifier-seq</I> of a <I>function-definition</I>
(8.4 [dcl.fct.def])</SPAN>...

</BLOCKQUOTE>

<P><B>Proposed resolution (September, 2008):</B></P>

<P>Change 7.1.3 [dcl.typedef] paragraph 1 as follows:</P>

<BLOCKQUOTE>

...The <TT>typedef</TT> specifier <SPAN style="text-decoration:line-through;background-color:#FFA0A0">shall not be used in a
<I>function-definition</I> (8.4 [dcl.fct.def]), and it</SPAN>
shall not be combined in a <I>decl-specifier-seq</I> with any
other kind of specifier except a <I>type-specifier</I><SPAN style="font-weight:bold;background-color:#A0FFA0">,
and it shall be used neither in the <I>decl-specifier-seq</I> of a
<I>parameter-declaration</I> (8.3.5 [dcl.fct]) nor in the
<I>decl-specifier-seq</I> of a <I>function-definition</I>
(8.4 [dcl.fct.def])</SPAN>.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="699"></A><H4>699.
  
Must constexpr member functions be defined in the class <I>member-specification</I>?
</H4><B>Section: </B>7.1.5&#160; [dcl.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>26 June, 2008<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK49">N2800 comment
  UK&#160;49<BR></A>
<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#JP12">N2800 comment
  JP&#160;12<BR></A>
<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#DE23">N2800 comment
  DE&#160;23<BR></A>

<P>[Voted into WP at October, 2009 meeting.]</P>



<P>According to 7.1.5 [dcl.constexpr] paragraph 1,</P>

<BLOCKQUOTE>

The <TT>constexpr</TT> specifier shall be applied only to the
definition of an object, function, or function template, or to the
declaration of a static data member of a literal type (3.9 [basic.types]).

</BLOCKQUOTE>

<P>As a result, a constexpr member function cannot be simply declared
in the class <I>member-specification</I> and defined later; it must
be defined in its initial declaration.</P>

<P>This restriction was not part of the initial proposal but was added
during the CWG review.  However, the original intent is still visible
in some of the wording in 7.1.5 [dcl.constexpr].  For example,
paragraph 2 refers to applying the <TT>constexpr</TT> specifier to the
&#8220;declaration&#8221; and not the &#8220;definition&#8221; of a
function or constructor.  Although that is formally correct, as
definitions are also declarations, it could be confusing.  Also, the
example in paragraph 6 reads,</P>

<PRE>
    class debug_flag {
    public:
      explicit debug_flag(bool);
      constexpr bool is_on();    //<SPAN style="font-family:Times;font-style:italic"> error: </SPAN>debug_flag<SPAN style="font-family:Times;font-style:italic"> not literal type</SPAN>
      ...
</PRE>

<P>when the proximate error is that <TT>is_on</TT> is only declared,
not defined.  There are also many occurrences of the <TT>constexpr</TT>
specifier in the library clauses where the member function is only
declared, not defined.</P>

<P>It's not clear how much simplification is gained by this restriction.
There are reasons for defining ordinary inline functions outside the
class <I>member-specification</I> (reducing the size and complexity of
the class definition, separating interface from implementation, making
the editing task easier if program evolution results in an inline
function being made non-inline, etc.) that would presumably apply to
constexpr member functions as well.  It seems feasible to allow
separate declaration and definition of a constexpr function; it would
simply not be permitted to use it in a constant expression before the
definition is seen (although it could presumably still be used in
non-constant expressions in that region, like an ordinary inline
function).</P>

<P>If the prohibition were relaxed to allow separate declaration and
definition of constexpr member functions, some questions would need to
be answered, such as whether the <TT>constexpr</TT> specifier must
appear on both declaration and definition (the <TT>inline</TT>
specifier need not). If it can be omitted in one or the other, there's
a usability issue regarding the fact that <TT>constexpr</TT> implies
<TT>const</TT>; the <TT>const</TT> qualifier would need to be
specified explicitly in the declaration in which <TT>constexpr</TT>
was omitted.</P>

<P>If the current restriction is kept, the library clauses should
state in an introduction that a non-defining declaration of a
constexpr member function should be considered &#8220;for exposition
only&#8221; and not literal code.</P>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>In addition to the original issues described above, the
question has arisen whether recursive constexpr functions
are or should be permitted.  Although they were originally
desired by the proposers of the feature, they were prohibited
out of an abundance of caution.  However, the wording that
specified the prohibition was changed during the review
process, inadvertently permitting them.</P>

<P>The CWG felt that there are sufficient use cases for
recursion that it should not be forbidden (although a new
minimum for recursion depth should be added to Annex
B [implimits]).  If mutual recursion is to be
allowed, forward declaration of constexpr functions must
also be permitted (answering the original question in this
issue).  A call to an undefined constexpr function in the
body of a constexpr function should be diagnosed when the
outer constexpr function is invoked in a context requiring
a constant expression; in all other contexts, a call to
an undefined constexpr function should be treated as a
normal runtime function call, just as if it had been invoked
with non-constant arguments.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<OL><LI><P>Change 5 [expr] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

If during the evaluation of an expression, the result is not
mathematically defined or not in the range of representable values for
its type, the behavior is undefined<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, unless such an expression
appears where an integral constant expression is required
(5.19 [expr.const]), in which case the program is
ill-formed</SPAN>. [<I>Note:</I> most existing implementations of C++
ignore integer overflows.  Treatment of division by zero, forming a
remainder using a zero divisor, and all floating point exceptions vary
among machines, and is usually adjustable by a library
function. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Add the indicated text to 5.19 [expr.const] paragraph
2:</P></LI>

<UL><LI><P>...</P></LI>

<LI><P>an invocation of a function other than a constexpr function or a
constexpr constructor [<I>Note:</I> overload resolution (13.3 [over.match]) is applied as usual &#8212;<I>end note</I>];</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">a direct or indirect invocation of an undefined constexpr
function or an undefined constexpr constructor outside the definition
of a constexpr function or a constexpr constructor;</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">a result that is not mathematically defined or not in the
range of representable values for its type;</SPAN></P></LI>

<LI><P>...</P></LI>

</UL>

<LI><P>Change 7.1.5 [dcl.constexpr] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<P>The <TT>constexpr</TT> specifier shall be applied only to the
definition of an object, <SPAN style="font-weight:bold;background-color:#A0FFA0">the declaration of a</SPAN>
function<SPAN style="text-decoration:line-through;background-color:#FFA0A0">,</SPAN> or function template, or <SPAN style="text-decoration:line-through;background-color:#FFA0A0">to</SPAN> the
declaration of a static data member of an effective literal type
(3.9 [basic.types]). <SPAN style="font-weight:bold;background-color:#A0FFA0">If any declaration of a function or
function template has the <TT>constexpr</TT> specifier, then all its
declarations shall contain the <TT>constexpr</TT>
specifier. [<I>Note:</I> An explicit specialization can differ from
the template declaration with respect to the <TT>constexpr</TT>
specifier. &#8212;<I>end note</I>]</SPAN> [<I>Note:</I> function
parameters cannot be declared <TT>constexpr</TT>. &#8212;<I>end
note</I>] [<I>Example:</I></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  constexpr int square(int x);       //<SPAN style="font-family:Times;font-style:italic">OK, declaration</SPAN></SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">  constexpr int square(int x) {      //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
    return x * x;
  }</SPAN>
  constexpr int bufsz = 1024;        //<SPAN style="font-family:Times;font-style:italic"> OK<SPAN style="font-weight:bold;background-color:#A0FFA0">, definition</SPAN></SPAN>
  constexpr struct pixel {           //<SPAN style="font-family:Times;font-style:italic"> error: </SPAN>pixel<SPAN style="font-family:Times;font-style:italic"> is a type</SPAN>
    int x;
    int y;
<SPAN style="font-weight:bold;background-color:#A0FFA0">    constexpr pixel(int);            //<SPAN style="font-family:Times;font-style:italic"> OK, declaration</SPAN></SPAN>
  };
<SPAN style="font-weight:bold;background-color:#A0FFA0">  constexpr pixel::pixel(int a)
    : x(square(a)), y(square(a)) { } //<SPAN style="font-family:Times;font-style:italic">OK, definition</SPAN>
  constexpr pixel small(2);          //<SPAN style="font-family:Times;font-style:italic"> error: </SPAN>square<SPAN style="font-family:Times;font-style:italic"> not defined, so </SPAN>small(2)
                                     //<SPAN style="font-family:Times;font-style:italic"> not constant (5.19 [expr.const]), so </SPAN>constexpr<SPAN style="font-family:Times;font-style:italic"> not satisfied</SPAN>
  constexpr int square(int x) {      //<SPAN style="font-family:Times;font-style:italic"> OK, definition</SPAN>
    return x * x;
  }
  constexpr pixel large(4);          //<SPAN style="font-family:Times;font-style:italic"> OK, </SPAN>square<SPAN style="font-family:Times;font-style:italic"> defined</SPAN></SPAN>
  int next(constexpr int x) {        //<SPAN style="font-family:Times;font-style:italic"> error<SPAN style="font-weight:bold;background-color:#A0FFA0">, not for parameters</SPAN></SPAN>
    return x + 1;
  }
  extern constexpr int memsz;        //<SPAN style="font-family:Times;font-style:italic"> error: not a definition</SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<LI><P>Add a new section following 17.6.5.5 [member.functions]:</P></LI>

<BLOCKQUOTE>

<SPAN style="font-weight:bold;background-color:#A0FFA0">Implementations shall provide definitions for any non-defining
declarations of <TT>constexpr</TT> functions and constructors within the
associated header files.</SPAN>

</BLOCKQUOTE>

<LI><P>Add the following bullet to the list in B [implimits]
paragraph 2:</P></LI>

<UL><LI><PL>...</PL></LI>

<LI><P>Nested external specifications [1 024].</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">Recursive constexpr function invocations [512].</SPAN></P></LI>

<LI><P>...</P></LI>

</UL>

</OL>

<P>(This resolution also resolves <A HREF="
     cwg_defects.html#695">issue 695</A>.)</P>

<BR><BR><HR><A NAME="991"></A><H4>991.
  
Reference parameters of constexpr functions and constructors
</H4><B>Section: </B>7.1.5&#160; [dcl.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Gabriel dos Reis
 &#160;&#160;&#160;

 <B>Date: </B>20 October, 2009<BR>


<P>[Voted into WP at March, 2010 meeting as document N3078.]</P>

<P>It would be useful if constexpr functions and constructors could take
arguments via reference-to-const parameters. <commmittee_only>See message
<A href="
   http://accu.org/cgi-bin/wg21/message?wg=core&amp;msg=15357">15357</A>.</commmittee_only>
</P>

<BR><BR><HR><A NAME="811"></A><H4>811.
  
Unclear implications of const-qualification
</H4><B>Section: </B>7.1.6.1&#160; [dcl.type.cv]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>UK
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK89">N2800 comment
  UK&#160;89<BR></A>

<P>[Voted into WP at March, 2010 meeting.]</P>

<P>The normative text in 7.1.6.1 [dcl.type.cv] paragraph 2 reads,</P>

<BLOCKQUOTE>

An object declared in namespace scope with a const-qualified type has
internal linkage unless it is explicitly declared <TT>extern</TT> or
unless it was previously declared to have external linkage.  A
variable of non-volatile const-qualified integral or enumeration type
initialized by an integral constant expression can be used in integral
constant expressions (5.19 [expr.const]).

</BLOCKQUOTE>

<P>These two sentences parallel the specifications of
7.1.1 [dcl.stc] paragraph 7 and 5.19 [expr.const].
However, the passages are not identical, leading to questions about
whether the meanings are the same.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 7.1.6.1 [dcl.type.cv] paragraph 2 as follows:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">An object declared in namespace scope with a const-qualified type
has internal linkage unless it is explicitly declared <TT>extern</TT>
or unless it was previously declared to have external linkage.  A
variable of non-volatile const-qualified integral or enumeration type
initialized by an integral constant expression can be used in integral
constant expressions (5.19 [expr.const]).</SPAN> [<I>Note:</I>
<SPAN style="font-weight:bold;background-color:#A0FFA0">Declaring a variable <TT>const</TT> can affect its linkage
(7.1.1 [dcl.stc]) and its usability in constant expressions
(5.19 [expr.const]).  As</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">as</SPAN> described in
8.5 [dcl.init], the definition of an object or subobject of
const-qualified type must specify an initializer or be subject to
default-initialization. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<BR><BR><HR><A NAME="950"></A><H4>950.
  
Use of <TT>decltype</TT> as a <I>class-name</I>
</H4><B>Section: </B>7.1.6.2&#160; [dcl.type.simple]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>3 August, 2009<BR>


<P>[Voted into WP at March, 2010 meeting as document N3049.]</P>



<P>In the current specification, a <TT>decltype</TT> resulting in
a class type is not a <I>class-name</I>, meaning that it cannot be
used as a <I>base-specifier</I>.  There doesn't seem to be any reason
not to allow that, and it would be consistent with the proposed
outcome of <A HREF="
     cwg_defects.html#743">issue 743</A>.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>See paper PL22.16/10-0021 = WG21 N3031.</P>

<BR><BR><HR><A NAME="988"></A><H4>988.
  
Reference-to-reference collapsing with <TT>decltype</TT>
</H4><B>Section: </B>7.1.6.2&#160; [dcl.type.simple]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Michael Wong
 &#160;&#160;&#160;

 <B>Date: </B>19 October, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>References to references are ill-formed, but special provision is
made in cases where this occurs via typedefs or template type
parameters.  A similar provision is probably needed for types resulting
from <TT>decltype</TT>:</P>

<PRE>
    int x, *p = &amp;x;
    decltype(*p) &amp;y = *p;  // reference to reference is ill-formed
</PRE>

<P><B>Proposed resolution (October, 2009):</B></P>

<OL><LI><P>Delete 7.1.3 [dcl.typedef] paragraph 9:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">If a typedef <TT>TD</TT> names a type that is a reference to a
type <TT>T</TT>, an attempt to create the type &#8220;lvalue reference
to <I>cv</I> <TT>TD</TT>&#8221; creates the type &#8220;lvalue
reference to <TT>T</TT>,&#8221; while an attempt to create the type
&#8220;rvalue reference to <I>cv</I> <TT>TD</TT>&#8221; creates the type <TT>TD</TT>. [<I>Example:</I> ... &#8212;<I>end example</I>]</SPAN>

</BLOCKQUOTE>

<LI><P>Delete 14.3.1 [temp.arg.type] paragraph 4:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">If a <I>template-argument</I> for a <I>template-parameter</I>
<TT>T</TT> names a type that is a reference to a type <TT>A</TT>, an
attempt to create the type &#8220;lvalue reference to <I>cv</I>
<TT>T</TT>&#8221; creates the type &#8220;lvalue reference to
<TT>A</TT>,&#8221; while an attempt to create the type &#8220;rvalue
reference to <I>cv</I> <TT>T</TT>&#8221; creates the type <TT>T</TT>
[<I>Example:</I> ... &#8212;<I>end example</I>]</SPAN>

</BLOCKQUOTE>

<LI><P>Add the following as a new paragraph at the end of 8.3.2 [dcl.ref]:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">If a typedef (7.1.3 [dcl.typedef]), a type
<I>template-parameter</I> (14.3.1 [temp.arg.type]), or a
<I>decltype-specifier</I> (7.1.6.2 [dcl.type.simple]) denotes a
type <TT>TR</TT> that is a reference to a type <TT>T</TT>, an attempt
to create the type &#8220;lvalue reference to <I>cv</I>
<TT>TR</TT>&#8221; creates the type &#8220;lvalue reference to
<TT>T</TT>,&#8221; while an attempt to create the type &#8220;rvalue
reference to <I>cv</I> <TT>TR</TT>&#8221; creates the type <TT>TR</TT>. [<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">   int i;
   typedef int&amp; LRI;
   typedef int&amp;&amp; RRI;
   LRI&amp; r1 = i;                      // r1<SPAN style="font-family:Times;font-style:italic"> has the type </SPAN>int&amp;
   const LRI&amp; r2 = i;                // r2<SPAN style="font-family:Times;font-style:italic"> has the type </SPAN>int&amp;
   const LRI&amp;&amp; r3 = i;               // r3<SPAN style="font-family:Times;font-style:italic"> has the type </SPAN>int&amp;
   RRI&amp; r4 = i;                      // r4<SPAN style="font-family:Times;font-style:italic"> has the type </SPAN>int&amp;
   RRI&amp;&amp; r5 = i;                     // r5<SPAN style="font-family:Times;font-style:italic"> has the type </SPAN>int&amp;&amp;

   decltype(r2)&amp; r6 = i;             // r6<SPAN style="font-family:Times;font-style:italic"> has the type </SPAN>int&amp;
   decltype(r2)&amp;&amp; r7 = i;            // r7<SPAN style="font-family:Times;font-style:italic"> has the type </SPAN>int&amp;</SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="962"></A><H4>962.
  
Attributes appertaining to class and enum types
</H4><B>Section: </B>7.1.6.3&#160; [dcl.type.elab]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>2 September, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>There is a lack of symmetry in the specification of attributes
that apply to class and enum types.  For example:</P>

<PRE>
    class X [[attr]];               //<SPAN style="font-family:Times;font-style:italic"> #1</SPAN>
    typedef class Y [[attr]] YT;    //<SPAN style="font-family:Times;font-style:italic"> #2</SPAN>
</PRE>

<P>According to 7.1.6.3 [dcl.type.elab] paragraph 1, #1
associates the <TT>attr</TT> attribute with class <TT>X</TT>
for all subsequent references.  On the other hand,
8.3 [dcl.meaning] paragraph 5 says that #2 associates
the <TT>attr</TT> attribute with the type but not with class
<TT>Y</TT>.</P>

<P>Existing implementations (Microsoft, GNU, Sun) with attributes
place an attribute that is intended to be associated with a class
type between the <I>class-key</I> and the class name, and it
would be preferable to adopt such an approach instead of the
contextual approach in the current formulation.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<OL><LI><P>Change 3.3.2 [basic.scope.pdecl] paragraph 6 bullet 1 as
follows:</P></LI>

<UL><LI><P>for a declaration of the form</P></LI>

<UL><I>class-key <SPAN style="font-weight:bold;background-color:#A0FFA0">attribute-specifier<SUB>opt</SUB></SPAN> identifier <SPAN style="text-decoration:line-through;background-color:#FFA0A0">attribute-specifier<SUB>opt</SUB></SPAN></I> <TT>;</TT></UL>

<P>the <I>identifier</I> is declared...</P>

</UL>

<LI><P>Change 3.4.4 [basic.lookup.elab] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

<P>...unless the <I>elaborated-type-specifier</I> appears in a
declaration with the following form:</P>

<UL><I>class-key <SPAN style="font-weight:bold;background-color:#A0FFA0">attribute-specifier<SUB>opt</SUB></SPAN> identifier <SPAN style="text-decoration:line-through;background-color:#FFA0A0">attribute-specifier<SUB>opt</SUB></SPAN></I> <TT>;</TT></UL>

<P>the <I>identifier</I> is looked up... if the
<I>elaborated-type-specifier</I> appears in a declaration with the
form:</P>

<UL><I>class-key <SPAN style="font-weight:bold;background-color:#A0FFA0">attribute-specifier<SUB>opt</SUB></SPAN> identifier <SPAN style="text-decoration:line-through;background-color:#FFA0A0">attribute-specifier<SUB>opt</SUB></SPAN></I> <TT>;</TT></UL>

<P>the <I>elaborated-type-specifier</I> is a declaration...</P>

</BLOCKQUOTE>

<LI><P>In 7.1.6.3 [dcl.type.elab], change the grammar and paragraph
1 as follows:</P></LI>

<BLOCKQUOTE>

<UL><I>elaborated-type-specifier:</I>
<UL><I>class-key <SPAN style="font-weight:bold;background-color:#A0FFA0">attribute-specifier<SUB>opt</SUB></SPAN></I> <TT>::</TT><I><SUB>opr</SUB> nested-name-specifier<SUB>opt</SUB> identifier</I><BR>
...
</UL>
</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">An <I>attribute-specifier</I> shall not appear in an
<I>elaborated-type-specifier</I> unless the latter is the sole
constituent of a declaration.</SPAN> If an
<I>elaborated-type-specifier</I> is the sole constituent of a
declaration, the declaration is ill-formed unless it is an explicit
specialization (14.7.3 [temp.expl.spec]), an explicit
instantiation (14.7.2 [temp.explicit]) or it has one of the
following forms:</P>

<UL><I>class-key <SPAN style="font-weight:bold;background-color:#A0FFA0">attribute-specifier<SUB>opt</SUB></SPAN> identifier <SPAN style="text-decoration:line-through;background-color:#FFA0A0">attribute-specifier<SUB>opt</SUB></SPAN></I> <TT>;</TT><BR>
...
</UL>

</BLOCKQUOTE>

<LI><P>Change the grammar in 7.2 [dcl.enum] paragraph 1 as
follows:</P></LI>

<UL><I>enum-head:</I>
<UL><I>enum-key <SPAN style="font-weight:bold;background-color:#A0FFA0">attribute-specifier<SUB>opt</SUB></SPAN> identifier<SUB>opt</SUB> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">attribute-specifier<SUB>opt</SUB></SPAN> enum-base<SUB>opt</SUB> attribute-specifier<SUB>opt</SUB></I><BR>
<I>enum-key <SPAN style="font-weight:bold;background-color:#A0FFA0">attribute-specifier<SUB>opt</SUB></SPAN> nested-name-specifier identifier</I>
<UL><I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">attribute-specifier<SUB>opt</SUB></SPAN> enum-base<SUB>opt</SUB> attribute-specifier<SUB>opt</SUB></I></UL>
</UL><BR>
<I>opaque-enum-declaration:</I>
<UL><I>enum-key <SPAN style="font-weight:bold;background-color:#A0FFA0">attribute-specifier<SUB>opt</SUB></SPAN> identifier <SPAN style="text-decoration:line-through;background-color:#FFA0A0">attribute-specifier<SUB>opt</SUB></SPAN> enum-base<SUB>opt</SUB> attribute-specifier<SUB>opt</SUB></I></UL>
</UL>

<LI><P>Change the grammar in 9 [class] paragraph 1 as
follows:</P></LI>

<UL><I>class-head:</I>
<UL><I>class-key <SPAN style="font-weight:bold;background-color:#A0FFA0">attribute-specifier<SUB>opt</SUB></SPAN> identifier<SUB>opt</SUB> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">attribute-specifier<SUB>opt</SUB></SPAN> base-clause<SUB>opt</SUB></I><BR>
<I>class-key <SPAN style="font-weight:bold;background-color:#A0FFA0">attribute-specifier<SUB>opt</SUB></SPAN> nested-name-specifier identifier <SPAN style="text-decoration:line-through;background-color:#FFA0A0">attribute-specifier<SUB>opt</SUB></SPAN> base-clause<SUB>opt</SUB></I><BR>
<I>class-key <SPAN style="font-weight:bold;background-color:#A0FFA0">attribute-specifier<SUB>opt</SUB></SPAN> nested-name-specifier<SUB>opt</SUB> simple-template-id</I>
<UL><I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">attribute-specifier<SUB>opt</SUB></SPAN> base-clause<SUB>opt</SUB></I></UL>
</UL>
</UL>

</OL>

<BR><BR><HR><A NAME="625"></A><H4>625.
  
Use of <TT>auto</TT> as a <I>template-argument</I>
</H4><B>Section: </B>7.1.6.4&#160; [dcl.spec.auto]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>9 March 2007<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>The <TT>auto</TT> specifier can be used only in certain contexts,
as specified in 7.1.6.4 [dcl.spec.auto] paragraphs 2-3:</P>

<BLOCKQUOTE>

<P>Otherwise (<TT>auto</TT> appearing with no type specifiers other than
<I>cv-qualifier</I>s), the <TT>auto</TT> <I>type-specifier</I>
signifies that the type of an object being declared shall be deduced
from its initializer. The name of the object being declared shall not
appear in the initializer expression.</P>

<P>This use of <TT>auto</TT> is allowed when declaring objects in a
block (6.3 [stmt.block]), in namespace scope (3.3.6 [basic.scope.namespace]), and in a <I>for-init-statement</I> (6.5.3 [stmt.for]).  The <I>decl-specifier-seq</I> shall be followed by
one or more <I>init-declarator</I>s, each of which shall have a
non-empty <I>initializer</I> of either of the following forms:</P>

<UL>
<TT>=</TT> <I>assignment-expression</I><BR>
<TT>(</TT> <I>assignment-expression</I> <TT>)</TT>
</UL>

</BLOCKQUOTE>

<P>It was intended that <TT>auto</TT> could be used only at the
top level of a declaration, but it is not clear whether this wording
is sufficient to forbid usage like the following:</P>

<PRE>
    template &lt;class T&gt; struct A {};
    template &lt;class T&gt; void f(A&lt;T&gt; x) {}

    void g()
    {
        f(A&lt;short&gt;());

        A&lt;auto&gt; x = A&lt;short&gt;();
    }
</PRE>

<P><B>Notes from the February, 2008 meeting:</B></P>

<P>It was agreed that the example should be ill-formed.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 7.1.6.4 [dcl.spec.auto] paragraph 3 as follows:</P>

<BLOCKQUOTE>

...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>auto</TT> shall appear as one of the
<I>decl-specifier</I>s in the <I>decl-specifier-seq</I> and the</SPAN>
<I>decl-specifier-seq</I> shall be followed by one or more
<I>init-declarator</I>s, each of which shall have a non-empty
<I>initializer</I>.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="711"></A><H4>711.
  
<TT>auto</TT> with <I>braced-init-list</I>
</H4><B>Section: </B>7.1.6.4&#160; [dcl.spec.auto]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>27 August, 2008<BR>


<P>[Voted into WP at July, 2009 meeting.]</P>



<P>One effect of the initializer-list proposal is that now we
allow</P>

<PRE>
    auto x = { 1, 2, 3 };  //<SPAN style="font-family:Times;font-style:italic"> </SPAN>decltype(x)<SPAN style="font-family:Times;font-style:italic"> is </SPAN>std::initializer_list&lt;int&gt;
</PRE>

<P>but not</P>

<PRE>
    auto ar[3] = { 1, 2, 3 };  //<SPAN style="font-family:Times;font-style:italic"> ill-formed</SPAN>
</PRE>

<P>This seems unfortunate, as the code for the first could also
support the second.  Incidentally, I also failed to update the
text in 7.1.6.4 [dcl.spec.auto] paragraph 3 which forbids
the use of <TT>auto</TT> with <I>braced-init-list</I>s, so
technically the first form above is currently ill-formed but has
defined semantics.
</P>

<P><U>Bjarne Stroustrup</U>:</P>

<P>Is this the thin edge of a wedge? How about</P>

<PRE>
    vector&lt;auto&gt; v = { 1, 2, 3 };
</PRE>

<P>and</P>

<PRE>
    template&lt;class T&gt; void f(vector&lt;T&gt;&amp; v);
    f({1, 2, 3 });
</PRE>

<P>(See also <A HREF="
     cwg_defects.html#625">issue 625</A>.)</P>

<P><B>Proposed resolution (March, 2009):</B></P>

<P>Change 7.1.6.4 [dcl.spec.auto] paragraph 3 as follows:</P>

<BLOCKQUOTE>

...The <I>decl-specifier-seq</I> shall be followed by one or more
<I>init-declarator</I>s, each of which shall have a non-empty
<I>initializer</I><SPAN style="font-weight:bold;background-color:#A0FFA0">.</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">of either of the following forms:

<UL>
<TT>=</TT> <I>assignment-expression</I><BR>
<TT>(</TT> <I>assignment-expression</I> <TT>)</TT>
</UL></SPAN>

</BLOCKQUOTE>

<P><I>[Drafting note: This change does not address the original
issue of the inability to use <TT>auto</TT> with an array initializer,
only the secondary issue of permitted the braced-init-list.  The
CWG explicitly decided not to support the array case.]</I></P>

<BR><BR><HR><A NAME="746"></A><H4>746.
  
Use of <TT>auto</TT> in <I>new-expression</I>s
</H4><B>Section: </B>7.1.6.4&#160; [dcl.spec.auto]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>18 November, 2008<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK95">N2800 comment
  UK&#160;95<BR></A>

<P>[Voted into WP at July, 2009 meeting.]</P>



<P>In listing the acceptable contexts in which the <TT>auto</TT>
specifier may appear, 7.1.6.4 [dcl.spec.auto]) paragraph 4
mentions &#8220;the <I>type-specifier-seq</I> in a <I>new-type-id</I>&#8221;
but not the <I>type-id</I> in the parenthesized form; that is,
<TT>new auto (42)</TT> is well-formed but <TT>new (auto) (42)</TT> is
not.  This seems an unnecessary restriction, as well as contradicting
5.3.4 [expr.new] paragraph 2:</P>

<BLOCKQUOTE>

If the <TT>auto</TT> <I>type-specifier</I> appears in the
<I>type-specifier-seq</I> of a <I>new-type-id</I> or <I>type-id</I> of
a <I>new-expression</I>...

</BLOCKQUOTE>

<P><B>Proposed resolution (March, 2009):</B></P>

<P>Change 7.1.6.4 [dcl.spec.auto] paragraph 4 as follows:</P>

<BLOCKQUOTE>

The <TT>auto</TT> <I>type-specifier</I> can also be used in declaring
an object in the <I>condition</I> of a selection statement
(6.4 [stmt.select]) or an iteration statement (6.5 [stmt.iter]), in the <I>type-specifier-seq</I> in <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">the</SPAN>
<I>new-type-id</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">or <I>type-id</I> of a <I>new-expression</I></SPAN>
(5.3.4 [expr.new]), in a <I>for-range-declaration</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="984"></A><H4>984.
  
&#8220;Deduced type&#8221; is unclear in <TT>auto</TT> type deduction
</H4><B>Section: </B>7.1.6.4&#160; [dcl.spec.auto]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Michael Wong
 &#160;&#160;&#160;

 <B>Date: </B>19 October, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>7.1.6.4 [dcl.spec.auto] paragraph 6 says,</P>

<BLOCKQUOTE>

Once the type of a <I>declarator-id</I> has been determined according
to 8.3 [dcl.meaning], the type of the declared variable using
the <I>declarator-id</I> is determined from the type of its
initializer using the rules for template argument deduction.  Let
<TT>T</TT> be the type that has been determined for a variable
identifier <TT>d</TT>.  Obtain <TT>P</TT> from <TT>T</TT> by replacing
the occurrences of <TT>auto</TT> with either a new invented type
template parameter <TT>U</TT> or, if the initializer is a
<I>braced-init-list</I> (8.5.4 [dcl.init.list]), with
<TT>std::initializer_list&lt;U&gt;</TT>.  The type deduced for the
variable <TT>d</TT> is then the deduced type determined using the
rules of template argument deduction from a function call
(14.8.2.1 [temp.deduct.call]), where <TT>P</TT> is a function
template parameter type and the initializer for <TT>d</TT> is the
corresponding argument.

</BLOCKQUOTE>

<P>The reference to &#8220;the deduced type&#8221; is unclear; it
could be taken as referring either to the template parameter or to the
function parameter type.  14.8.2.1 [temp.deduct.call] uses the term
&#8220;deduced <TT>A</TT>,&#8221; and that usage should be repeated
here.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 7.1.6.4 [dcl.spec.auto] paragraph 6 as follows:</P>

<BLOCKQUOTE>

...The type deduced for the variable <TT>d</TT> is then the deduced
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">type</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>A</TT></SPAN> determined using the rules of
template argument deduction...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="628"></A><H4>628.
  
The values of an enumeration with no enumerator
</H4><B>Section: </B>7.2&#160; [dcl.enum]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Gennaro Prota
 &#160;&#160;&#160;

 <B>Date: </B>15 March 2007<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK96">N2800 comment
  UK&#160;96<BR></A>

<P>[Voted into the WP at the March, 2009 meeting.]</P>

<P>According to 7.2 [dcl.enum] paragraph 6, the underlying
type of an enumeration with an empty <I>enumeration-list</I> is
determined as if the <I>enumeration-list</I> contained a single
enumerator with value 0.  Paragraph 7, which specifies the values of
an enumeration and the minimum size of bit-field needed represent
those values needs a similar provision for
empty <I>enumeration-list</I>s.</P>

<P><B>Proposed resolution (March, 2008):</B></P>

<P>Add the indicated sentence to the end of 7.2 [dcl.enum]
paragraph 5:</P>

<BLOCKQUOTE>

...It is possible to define an enumeration that has values not defined
by any of its enumerators.  <SPAN style="font-weight:bold;background-color:#A0FFA0">If the <I>enumerator-list</I> is empty,
the values of the enumeration are as if the enumeration had a single
enumerator with value 0.</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="862"></A><H4>862.
  
Undefined behavior with enumerator value overflow
</H4><B>Section: </B>7.2&#160; [dcl.enum]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>7 April, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>The type of an enumerator that has no initializing value in an
enumeration whose underlying type is not fixed is given by the third
bullet of 7.2 [dcl.enum] paragraph 5:</P>

<BLOCKQUOTE>

the type of the initializing value is the same as the type of the
initializing value of the preceding enumerator unless the incremented
value is not representable in that type, in which case the type is an
unspecified integral type sufficient to contain the incremented value.

</BLOCKQUOTE>

<P>This does not address the case in which there is no such type,
meaning that it is apparently undefined behavior.  Other cases in
which an enumeration value is unrepresentable are made ill-formed (see
the preceding paragraph for an enumeration with a fixed underlying
type and the following paragraph for the case in which the minimum and
maximum values cannot be represented by a single type).  It would be
better if this case were ill-formed as well, instead of causing
undefined behavior.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 7.2 [dcl.enum] paragraph 5, bullet 3 as follows:</P>

<UL><LI>Otherwise the type of the initializing value is the same as
the type of the initializing value of the preceding enumerator unless
the incremented value is not representable in that type, in which case
the type is an unspecified integral type suficient to contain the
incremented value. <SPAN style="font-weight:bold;background-color:#A0FFA0">If no such type exists, the program is
ill-formed.</SPAN></LI></UL>

<BR><BR><HR><A NAME="812"></A><H4>812.
  
Duplicate names in inline namespaces
</H4><B>Section: </B>7.3.1&#160; [namespace.def]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>JP
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#JP14">N2800 comment
  JP&#160;14<BR></A>

<P>[Voted into WP at March, 2010 meeting.]</P>

<P>It is not clear from the specification in 7.3.1 [namespace.def]
paragraph 8 how a declaration in an inline namespace should be handled if
the name is the same as one in the containing namespace or in an parallel
inline namespace.  For example:</P>

<PRE>
  namespace Q {
    inline namespace V1 {
      int i;
      int j;
    }
    inline namespace V2 {
      int j;
    }
    int i;
  }
  int Q::i = 1;   // Q::i or Q::V1::i?
  int Q::j = 2;   // Q::V1::j or Q::V2::j?
</PRE>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>This issue is resolved by the resolution of <A HREF="
     cwg_defects.html#861">issue 861</A>.</P>
<BR><BR><HR><A NAME="919"></A><H4>919.
  
Contradictions regarding inline namespaces
</H4><B>Section: </B>7.3.1&#160; [namespace.def]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Michael Wong
 &#160;&#160;&#160;

 <B>Date: </B>19 June, 2009<BR>


<P>[Voted into WP at March, 2010 meeting as part of document N3079.]</P>

<P>According to 7.3.1 [namespace.def] paragraph 8,</P>

<BLOCKQUOTE>

Members of an inline namespace can be used in most respects as though
they were members of the enclosing namespace... Furthermore, each
member of the inline namespace can subsequently be explicitly
instantiated (14.7.2 [temp.explicit]) or explicitly specialized
(14.7.3 [temp.expl.spec]) as though it were a member of the
enclosing namespace.

</BLOCKQUOTE>

<P>However, that assertion is contradicted for class template
specializations by 9 [class] paragraph 11:</P>

<BLOCKQUOTE>

If a <I>class-head</I> contains a <I>nested-name-specifier</I>,
the <I>class-specifier</I> shall refer to a class that was
previously declared directly in the class or namespace to which the
<I>nested-name-specifier</I> refers...

</BLOCKQUOTE>

<P>It is also contradicted for function template specializations by
3.4.3.2 [namespace.qual] paragraph 6:</P>

<BLOCKQUOTE>

In a declaration for a namespace member in which the
<I>declarator-id</I> is a <I>qualified-id</I>, given that
the <I>qualified-id</I> for the namespace member has the
form

<UL><I>nested-name-specifier unqualified-id</I></UL>

the <I>unqualified-id</I> shall name a member of the namespace
designated by the <I>nested-name-specifier</I>.

</BLOCKQUOTE>

<P><B>Proposed resolution (November, 2009):</B></P>

<OL><LI><P>Change 9 [class] paragraph 11 as follows:</P></LI>

<BLOCKQUOTE>

If a <I>class-head</I> contains a <I>nested-name-specifier</I>,
the <I>class-specifier</I> shall refer to a class that was
previously declared directly in the class or namespace to which the
<I>nested-name-specifier</I> refers<SPAN style="font-weight:bold;background-color:#A0FFA0">, or in an element of the
inline namespace set (7.3.1 [namespace.def]) of that
namespace</SPAN> (i.e., <SPAN style="text-decoration:line-through;background-color:#FFA0A0">neither</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">not merely</SPAN>
inherited <SPAN style="text-decoration:line-through;background-color:#FFA0A0">nor</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">or</SPAN> introduced by a
<I>using-declaration</I>), and the <I>class-specifier</I> shall appear
in a namespace enclosing the previous declaration.

</BLOCKQUOTE>

<LI><P>Change 3.4.3.2 [namespace.qual] paragraph 6 as follows:</P></LI>

<BLOCKQUOTE>

<P>In a declaration for a namespace member in which the
<I>declarator-id</I> is a <I>qualified-id</I>, given that the
<I>qualified-id</I> for the namespace member has the form</P>

<UL><I>nested-name-specifier unqualified-id</I></UL>

<P>the <I>unqualified-id</I> shall name a member of the namespace
designated by the <I>nested-name-specifier</I><SPAN style="font-weight:bold;background-color:#A0FFA0">, or of an
element of the inline namespace (7.3.1 [namespace.def]) of that
namespace</SPAN>. [<I>Example:</I>...</P>

</BLOCKQUOTE>

</OL>

<P>(Note: this resolution depends on the resolution for
<A HREF="
     cwg_defects.html#861">issue 861</A>.)</P>

<BR><BR><HR><A NAME="921"></A><H4>921.
  
Unclear specification of inline namespaces
</H4><B>Section: </B>7.3.1&#160; [namespace.def]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Michael Wong
 &#160;&#160;&#160;

 <B>Date: </B>19 June, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>According to 7.3.1 [namespace.def] paragraph 8,</P>

<BLOCKQUOTE>

Specifically, the inline namespace and its enclosing namespace are
considered to be associated namespaces (3.4.2 [basic.lookup.argdep]) of
one another, and a <I>using-directive</I> (7.3.4 [namespace.udir])
that names the inline namespace is implicitly inserted into the
enclosing namespace.

</BLOCKQUOTE>

<P>There are two problems with this sentence.  First, the concept
of namespaces being associated with each other is undefined;
3.4.2 [basic.lookup.argdep] describes how namespaces are associated
with types, not with other namespaces.  Second, unlike unnamed
namespaces, the location of the implicit <I>using-directive</I> is
not specified.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 7.3.1 [namespace.def] paragraph 8 as follows:</P>

<BLOCKQUOTE>

...Specifically, the inline namespace and its enclosing namespace are
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">considered to be associated namespaces (3.4.2 [basic.lookup.argdep]) of one another</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">both added to the set of
associated namespaces used in argument-dependent lookup (3.4.2 [basic.lookup.argdep]) whenever one of them is</SPAN>, and a
<I>using-directive</I> (7.3.4 [namespace.udir]) that names the
inline namespace is implicitly inserted into the enclosing namespace
<SPAN style="font-weight:bold;background-color:#A0FFA0">as for an unnamed namespace (7.3.1.1 [namespace.unnamed])</SPAN>. Furthermore...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="926"></A><H4>926.
  
Inline unnamed namespaces
</H4><B>Section: </B>7.3.1.1&#160; [namespace.unnamed]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Michael Wong
 &#160;&#160;&#160;

 <B>Date: </B>29 June, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>In 7.3.1 [namespace.def] paragraph 1, an
<I>unnamed-namespace-definition</I> is defined as</P>

<UL><TT>inline</TT><I><SUB>opt</SUB></I><TT> namespace { </TT><I>namespace-body</I><TT> }</TT></UL>

<P>However, there is no provision for the <TT>inline</TT> keyword in
the expansion of unnamed namespaces in 7.3.1.1 [namespace.unnamed]
paragraph 1. Strictly interpreted, that would mean that the
<TT>inline</TT> qualifier is ignored for unnamed namespaces.</P>

<P><B>Proposed resolution (September, 2009):</B></P>

<P>Change 7.3.1.1 [namespace.unnamed] paragraph 1 as follows:</P>

<BLOCKQUOTE>

<P>An <I>unnamed-namespace-definition</I> behaves as if it were
replaced by</P>

<PRE>
    <SPAN style="font-weight:bold;background-color:#A0FFA0">inline<I CLASS="cmnt"><SUB>opt</SUB></I></SPAN> namespace <I CLASS="cmnt"><B>unique</B></I> { /* empty body */ }
    using namespace <I CLASS="cmnt"><B>unique</B></I> ;
    namespace <I CLASS="cmnt"><B>unique</B></I> { <I CLASS="cmnt">namespace-body</I> }

</PRE>

<P>where <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>inline</TT> appears if and only if it appears in the
<I>unnamed-namespace-definition</I>, </SPAN> all occurrences of
<I><B>unique</B></I> in a translation unit are replaced by the same
identifier<SPAN style="font-weight:bold;background-color:#A0FFA0">,</SPAN> and this identifier differs from all other
identifiers in the entire program.<SUP>87</SUP>

[<I>Example:</I>...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="986"></A><H4>986.
  
Transitivity of <I>using-directive</I>s versus qualified lookup
</H4><B>Section: </B>7.3.4&#160; [namespace.udir]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Michael Wong
 &#160;&#160;&#160;

 <B>Date: </B>19 October, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>According to 7.3.4 [namespace.udir] paragraph 4,</P>

<BLOCKQUOTE>

The <I>using-directive</I> is transitive: if a scope contains a
<I>using-directive</I> that nominates a second namespace that
itself contains <I>using-directive</I>s, the effect is as if the
<I>using-directive</I>s from the second namespace also appeared in
the first.

</BLOCKQUOTE>

<P>This is true only for unqualified lookup; the algorithm in
3.4.3.2 [namespace.qual] paragraph 2 gives different results (the
transitive closure terminates when a declaration of the name being
looked up is found).</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 7.3.4 [namespace.udir] paragraph 4 as follows:</P>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">For unqualified lookup (3.4.1 [basic.lookup.unqual]), the</SPAN> <I>using-directive</I> is transitive: if a
scope contains a <I>using-directive</I> that nominates a second
namespace that itself contains <I>using-directive</I>s, the effect is
as if the <I>using-directive</I>s from the second namespace also
appeared in the first. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> For qualified lookup, see
3.4.3.2 [namespace.qual]. &#8212;<I>end note</I>]</SPAN>
[<I>Example:</I>...

<BR><BR><HR><A NAME="564"></A><H4>564.
  
Agreement of language linkage or <I>linkage-specification</I>s?
</H4><B>Section: </B>7.5&#160; [dcl.link]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>8 March 2006<BR>


<P>[Voted into the WP at the March, 2009 meeting.]</P>

<P>The wording of 7.5 [dcl.link] paragraph 5 is suspect:</P>

<BLOCKQUOTE>

If two declarations of the same function or object specify different
<I>linkage-specification</I>s (that is,
the <I>linkage-specification</I>s of these declarations specify
different <I>string-literal</I>s), the program is ill-formed if the
declarations appear in the same translation unit, and the one
definition rule (3.2) applies if the declarations appear in different
translation units.

</BLOCKQUOTE>

<P>But what if only one of the declarations has a
<I>linkage-specification</I>, while the other is left with the
default C++ linkage?  Shouldn't this restriction be phrased in terms
of the functions&#8217; or objects&#8217; language linkage rather than
<I>linkage-specification</I>s?</P>

<P>(<I>Additional note [wmm]:</I> Is the ODR the proper vehicle for
enforcing this requirement?  This is dealing with declarations, not
necessarily definitions.  Shouldn't this say &#8220;ill-formed, no
diagnostic required&#8221; instead of some vague reference to the ODR?)</P>

<P><B>Proposed resolution (June, 2008):</B></P>

<P>Change 7.5 [dcl.link] paragraph 5 as follows:</P>

<BLOCKQUOTE>

If two declarations <SPAN style="text-decoration:line-through;background-color:#FFA0A0">of the same function or object</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">declare
functions with the same name and parameter-type-list (8.3.5 [dcl.fct]) to be members of the same namespace or declare objects
with the same name to be members of the same namespace</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">specify
different <I>linkage-specification</I>s (that is, the
<I>linkage-specification</I>s of these declarations specify different
<I>string-literal</I>s)</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">and the declarations give the names
different language linkages</SPAN>, the program is ill-formed<SPAN style="text-decoration:line-through;background-color:#FFA0A0"> if the
declarations appear in the same translation unit, and the one
definition rule (3.2 [basic.def.odr]) applies</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">; no
diagnostic is required</SPAN> if the declarations appear in different
translation units.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="814"></A><H4>814.
  
Attribute to indicate that a function throws nothing
</H4><B>Section: </B>7.6&#160; [dcl.attr]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#US40">N2800 comment
  US&#160;40<BR></A>

<P>[Voted into WP at March, 2010 meeting as paper N3050.]</P>

<P>A function with an <I>exception-specification</I> of
<TT>throw()</TT> must be given a <TT>catch(...)</TT> clause to enforce
its contract, i.e., to call <TT>std::unexpected()</TT> if it exits
with an exception.  It would be useful to have an attribute indicating
that the function really does throw nothing and thus that the
<TT>catch(...)</TT> clause need not be generated.</P>

<P>(See also <A HREF="
     cwg_defects.html#830">issue 830</A>.)</P>

<P><B>Proposed resolution (September, 2009):</B></P>

<P>See paper PL22.16/09-0162 = WG21 N2972.</P>

<BR><BR><HR><A NAME="951"></A><H4>951.
  
Problems with <I>attribute-specifier</I>s
</H4><B>Section: </B>7.6&#160; [dcl.attr]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Sean Hunt
 &#160;&#160;&#160;

 <B>Date: </B>5 August, 2009<BR>


<P>[Voted into WP at March, 2010 meeting as document N3067.]</P>



<P>There are a number of problems with the treatment of attributes
in the current draft.  One issue is the failure to permit attributes
to appear at various points in the grammar at which one might plausibly
expect them:</P>

<UL><LI><P>In a <I>new-type-id</I> (5.3.4 [expr.new])</P></LI>

<LI><P>Preceding the <I>type-specifier-seq</I> in a <I>condition</I>
(6.4 [stmt.select])</P></LI>

<LI><P>In a <I>for-init-statement</I> that is an <I>expression-statement</I>
(6.5 [stmt.iter])</P></LI>

<LI><P>Preceding the <I>type-specifier-seq</I> in a
<I>for-range-declaration</I> (6.5 [stmt.iter])</P></LI>

<LI><P>In a reference <I>ptr-operator</I> (8 [dcl.decl])</P></LI>

<LI><P>Preceding the <I>type-specifier-seq</I> in a <I>type-id</I>
(8.1 [dcl.name])</P></LI>

<LI><P>Preceding the <I>decl-specifier-seq</I> in a
<I>parameter-declaration</I> (8.3.5 [dcl.fct])</P></LI>

<LI><P>In a <I>function-definition</I> (8.4 [dcl.fct.def]) at
any of the three locations where they might be expected:</P>

<UL><LI><P>preceding the <I>decl-specifier-seq</I></P></LI>

<LI><P>following the parameter list (paragraph 2 repeats the syntax
from 8.3.5 [dcl.fct] with the conspicuous omission of the
<I>attribute-specifier</I>)</P></LI>

<LI><P>preceding the <I>compound-statement</I> of the
<I>function-body</I> (this would introduce an ambiguity with the
<I>attribute-specifier</I> following the parameter list that would
need to be addressed)</P></LI>

</UL>

</LI>

<LI><P>Preceding the <I>decl-specifier-seq</I> of a
<I>member-declaration</I> (9.2 [class.mem])</P></LI>

<LI><P>Preceding the <I>compound-statement</I> of a <I>try-block</I>
or <I>handler</I> (15 [except])</P></LI>

<LI><P>Preceding the <I>type-specifier-seq</I> of an
<I>exception-declaration</I> (15 [except])</P></LI>

</UL>

<P>Another group of problems is the failure to specify to what
a given <I>attribute-specifier</I> appertains:</P>

<UL><LI><P>In a <I>condition</I> (6.4 [stmt.select])</P></LI>

<LI><P>In a <I>for-range-declaration</I> (6.5.4 [stmt.ranged])</P></LI>

<LI><P>In a <I>parameter-declaration</I> (8.3.5 [dcl.fct])</P></LI>

<LI><P>In a <I>conversion-type-id</I> (12.3.2 [class.conv.fct])</P></LI>

</UL>

<P>There is also a problem in the specification of the interpretation of
an initial <I>attribute-specifier</I>.  8.3 [dcl.meaning]
paragraph 5 says,</P>

<BLOCKQUOTE>

In a declaration <I>attribute-specifier<SUB>opt</SUB></I> <TT>T</TT>
<I>attribute-specifier<SUB>opt</SUB></I> <TT>D</TT> where <TT>D</TT> is
an unadorned identifier the type of this identifier is
&#8220;<TT>T</TT>&#8221;. The first optional
<I>attribute-specifier</I> appertains to the entity being declared.

</BLOCKQUOTE>

<P>This wording only covers the case where the declarator is a
simple identifier.  It leaves unspecified the meaning of the initial
<I>attribute-specifier</I> with more complex declarators for pointers,
references, functions, and arrays.</P>

<P>Finally, something needs to be said about the case where
<I>attribute-specifier</I>s occur in both the initial position and
following the <I>declarator-id</I>: is this permitted, and if so,
under what constraints?</P>

<P>(See also <A HREF="
     cwg_defects.html#968">issue 968</A>.)</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>See paper PL22.16/10-0023 = WG21 N3033.</P>

<BR><BR><HR><A NAME="970"></A><H4>970.
  
Consistent use of &#8220;appertain&#8221; and &#8220;apply&#8221;
</H4><B>Section: </B>7.6&#160; [dcl.attr]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>28 September, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>The terms &#8220;appertain&#8221; and &#8220;apply&#8221; are used
in different ways in different subsections of 7.6 [dcl.attr].
A thorough editorial sweep of the entire section is needed to regularize
their usage.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<OL><LI><P>Change 7.6.1 [dcl.attr.grammar] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

...If an <I>attribute-specifier</I> that appertains to some entity or
statement contains an <I>attribute</I> that <SPAN style="text-decoration:line-through;background-color:#FFA0A0">does not</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">is not allowed to</SPAN> apply to that entity or statement, the
program is ill-formed...

</BLOCKQUOTE>

<LI><P>Change 7.6.2 [dcl.align] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...The attribute <SPAN style="text-decoration:line-through;background-color:#FFA0A0">can</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">may</SPAN> be applied to a variable...

</BLOCKQUOTE>

<LI><P>Change 7.6.3 [dcl.attr.noreturn] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...The attribute <SPAN style="text-decoration:line-through;background-color:#FFA0A0">applies</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">may be applied</SPAN> to the
<I>declarator-id</I> in a function declaration...

</BLOCKQUOTE>

<LI><P>Change _N3225_.7.6.4 [dcl.attr.final] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...The attribute <SPAN style="text-decoration:line-through;background-color:#FFA0A0">applies</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">may be applied</SPAN> to class
definitions...

</BLOCKQUOTE>

<LI><P>Change _N3225_.7.6.5 [dcl.attr.override] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...The attribute <SPAN style="text-decoration:line-through;background-color:#FFA0A0">applies</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">may be applied</SPAN> to
virtual member functions...

</BLOCKQUOTE>

<LI><P>Change _N3225_.7.6.5 [dcl.attr.override] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

...The attribute <SPAN style="text-decoration:line-through;background-color:#FFA0A0">applies</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">may be applied</SPAN> to class
members...

</BLOCKQUOTE>

<LI><P>Change _N3225_.7.6.5 [dcl.attr.override] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

...The attribute <SPAN style="text-decoration:line-through;background-color:#FFA0A0">applies</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">may be applied</SPAN> to a
class definition.

</BLOCKQUOTE>

<LI><P>Change 7.6.4 [dcl.attr.depend] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...The attribute <SPAN style="text-decoration:line-through;background-color:#FFA0A0">applies</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">may be applied</SPAN> to the
<I>declarator-id</I> of a <I>parameter-declaration</I>... The
attribute <SPAN style="font-weight:bold;background-color:#A0FFA0">may</SPAN> also <SPAN style="text-decoration:line-through;background-color:#FFA0A0">applies</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">be applied</SPAN>
to the declarator-id of a function declaration...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="815"></A><H4>815.
  
Parameter pack expansion inside attributes
</H4><B>Section: </B>7.6.1&#160; [dcl.attr.grammar]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>UK
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK103">N2800 comment
  UK&#160;103<BR></A>

<P>[Voted into WP at July, 2009 meeting as N2933.]</P>

<P>Parameter packs should be expanded inside attributes.  For example,
it would be useful to specify the alignment of each element in a pack
expansion using a parallel pack expansion.</P>

<BR><BR><HR><A NAME="957"></A><H4>957.
  
Alternative tokens and <I>attribute-token</I>s
</H4><B>Section: </B>7.6.1&#160; [dcl.attr.grammar]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>26 August, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#FR12">N2800 comment
  FR&#160;12<BR></A>

<P>[Voted into WP at March, 2010 meeting.]</P>



<P>7.6.1 [dcl.attr.grammar] paragraph 3 specifies that keywords can
be used as <I>attribute-token</I>s.  However, the alternative tokens
in 2.6 [lex.digraph], such as <TT>bitor</TT> and <TT>compl</TT>,
are not keywords.  The text should be changed to make the alternative
tokens acceptable as <I>attribute-token</I>s as well.</P>

<P><B>Proposed resolution, October, 2009:</B></P>

<P>Change 7.6.1 [dcl.attr.grammar] paragraph 3 as follows:</P>

<BLOCKQUOTE>

...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">If a</SPAN> keyword (2.12 [lex.key])
<SPAN style="font-weight:bold;background-color:#A0FFA0">or an alternative token (2.6 [lex.digraph]) that satisfies
the syntactic requirements of an <I>identifier</I> (2.11 [lex.name]) is</SPAN> contained in an <I>attribute-token</I><SPAN style="font-weight:bold;background-color:#A0FFA0">,
it</SPAN> is considered an identifier...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="968"></A><H4>968.
  
Syntactic ambiguity of the attribute notation
</H4><B>Section: </B>7.6.1&#160; [dcl.attr.grammar]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>23 September, 2009<BR>


<P>[Voted into WP at March, 2010 meeting as document N3063.]</P>

<P>The <TT>[[ ... ]]</TT> notation for attributes was thought to be
completely unambiguous.  However, it turns out that two <TT>[</TT>
characters can be adjacent and not be an attribute-introducer: the
first could be the beginning of an array bound or subscript operator
and the second could be the beginning of a <I>lambda-introducer</I>.
This needs to be explored and addressed.</P>

<P>(See also <A HREF="
     cwg_defects.html#951">issue 951</A>.)</P>

<P><B>Proposed resolution (November, 2009):</B></P>

<P>Add the following paragraph at the end of 8.2 [dcl.ambig.res]:</P>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">Two consecutive left square bracket tokens shall appear
only when introducing an <I>attribute-specifier</I>.
[<I>Note:</I> If two consecutive left square brackets appear
where an <I>attribute-specifier</I> is not allowed, the program is
ill-formed even if the brackets match an alternative grammar
production. &#8212;<I>end note</I>] [<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  int p[10];
  void f() {
    int x = 42;
    int(p[[x]{return x;}()]);  //<SPAN style="font-family:Times;font-style:italic"> Error: malformed attribute on a nested</SPAN>
                               //<SPAN style="font-family:Times;font-style:italic"> declarator-id and not a function-style cast of</SPAN>
                               //<SPAN style="font-family:Times;font-style:italic"> an element of </SPAN>p.
    new int[[]{return x;}()];  //<SPAN style="font-family:Times;font-style:italic"> Error even though attributes are not allowed</SPAN>
  }                            //<SPAN style="font-family:Times;font-style:italic"> in this context.</SPAN></SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="959"></A><H4>959.
  
Alignment attribute for class and enumeration types
</H4><B>Section: </B>7.6.2&#160; [dcl.align]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>31 August, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>According to 7.6.2 [dcl.align] paragraph 1, an alignment
attribute can be specified only for a variable or a class data member.
The corresponding Microsoft and GNU attributes can be also specified
for a class type, and this usage seems to be widespread.  It should be
permitted with the standard attribute and there seems no good reason
not to do so for enumeration types, as well.</P>

<P><B>Notes from the October, 2009 meeting:</B></P>

<P>Although there was initial concern for how to integrate the suggested
change into the type system, it was observed that current practice is to
have the attribute affect only the layout, not the type.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<OL><LI><P>Change 7.6.2 [dcl.align] paragraphs 1-2 as
follows:</P></LI>

<BLOCKQUOTE>

<P>...The attribute can be applied to a variable that is neither a
function parameter nor declared with the register storage class
specifier and to a class data member that is not a bit-field.
<SPAN style="font-weight:bold;background-color:#A0FFA0">The attribute can also be applied to the declaration of a
class or enumeration type.</SPAN></P>

<P>When the alignment attribute is of the form
<TT>align(</TT><I>assignment-expression</I><TT>)</TT>:</P>

<UL><LI><P>...</P></LI>

<LI><P>if the constant expression evaluates to a fundamental
alignment, the alignment requirement of the declared
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">object</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">entity</SPAN> shall be the specified
fundamental alignment</P></LI>

<LI><P>if the constant expression evaluates to an extended
alignment and the implementation supports that alignment in the
context of the declaration, the alignment of the declared
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">object</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">entity</SPAN> shall be that
alignment</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 7.6.2 [dcl.align] paragraphs 4-6 as follows:</P></LI>

<BLOCKQUOTE>

<P>When multiple alignment attributes are specified for an
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">object</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">entity</SPAN>, the alignment requirement
shall be set to the strictest specified alignment.</P>

<P>The combined effect of all alignment attributes in a
declaration shall not specify an alignment that is less strict
than the alignment that would otherwise be required for the
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">object</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">entity</SPAN> being declared.</P>

<P>If the defining declaration of an <SPAN style="text-decoration:line-through;background-color:#FFA0A0">object</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">entity</SPAN> has an alignment attribute, any non-defining
declaration of that <SPAN style="text-decoration:line-through;background-color:#FFA0A0">object</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">entity</SPAN> shall
either specify equivalent alignment or have no alignment
attribute. <SPAN style="font-weight:bold;background-color:#A0FFA0">Conversely, if any declaration of an entity has
an alignment attribute, every defining declaration of that entity
shall specify an equivalent alignment.</SPAN> No diagnostic is
required if declarations of an <SPAN style="text-decoration:line-through;background-color:#FFA0A0">object</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">entity</SPAN> have different alignment attributes in
different translation units.</P>

</BLOCKQUOTE>

<LI><P>Insert the following as a new paragraph after
7.6.2 [dcl.align] paragraph 6:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  //<SPAN style="font-family:Times;font-style:italic"> Translation unit #1:</SPAN>
  struct S { int x; } s, p = &amp;s;

  //<SPAN style="font-family:Times;font-style:italic"> Translation unit #2:</SPAN>
  struct [[align(16)]] S;   //<SPAN style="font-family:Times;font-style:italic"> error: definition of </SPAN>S<SPAN style="font-family:Times;font-style:italic"> lacks alignment; no</SPAN>
  extern S* p;              //<SPAN style="font-family:Times;font-style:italic">            diagnostic required</SPAN></SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

<LI><P>Delete 7.6.2 [dcl.align] paragraph 8:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">[<I>Note:</I> the alignment of a union type can be
strengthened by applying the alignment attribute to any
non-static data member of the union. &#8212;<I>end
note</I>]</SPAN>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="965"></A><H4>965.
  
Limiting the applicability of the <TT>carries_dependency</TT> attribute
</H4><B>Section: </B>7.6.4&#160; [dcl.attr.depend]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>15 September, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>The current wording for the <TT>carries_dependency</TT> attribute
does not limit it to value-returning functions (when applied to the
<I>declarator-id</I>, indicating that the return value is affected),
nor does it prohibit use in the declaration of a typedef or function
pointer.  Arguably these meaningless declarations should be
prohibited.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 7.6.4 [dcl.attr.depend] paragraph 1 as follows:</P>

<BLOCKQUOTE>

...The attribute applies to the <I>declarator-id</I> of a
<I>parameter-declaration</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">in a function declaration or
lambda</SPAN>, in which case it specifies that the initialization of
the parameter carries a dependency to (1.10 [intro.multithread]) each
lvalue-to-rvalue conversion (4.1 [conv.lval]) of that
object. The attribute also applies to the
<I>declarator-id</I> of a function declaration, in which case it
specifies that the return value<SPAN style="font-weight:bold;background-color:#A0FFA0">, if any,</SPAN> carries a
dependency to the evaluation of the function call expression.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="770"></A><H4>770.
  
Ambiguity in late-specified return type
</H4><B>Section: </B>8&#160; [dcl.decl]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>9 February, 2009<BR>


<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>

<P>It is currently unspecified whether a declaration like</P>

<PRE>
    f() -&gt; struct S { };
</PRE>

<P>should be parsed as a declaration of <TT>f</TT> whose return type
is a class definition (which will be ill-formed according to
7.1.6 [dcl.type] paragraph 3) or as a definition of
<TT>f</TT> whose return type is an
<I>elaborated-type-specifier</I>.</P>

<P><B>Proposed resolution (June, 2009):</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="979"></A><H4>979.
  
Position of <I>attribute-specifier</I> in declarator syntax
</H4><B>Section: </B>8&#160; [dcl.decl]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>8 October, 2009<BR>




<P>In function, pointer, and pointer-to-member declarators, the
<I>attribute-specifier</I> appertains to the type being
declared, but the syntax has the
<I>attribute-specifier<SUB>opt</SUB></I> appearing before
the full type is seen &#8212; i.e., before the
<I>cv-qualifier-seq<SUB>opt</SUB></I> and, for the function case,
before the <I>ref-qualifier<SUB>opt</SUB></I>.  GNU attributes
appear after these elements (and, for the function case, after the
<I>exception-specification<SUB>opt</SUB></I> as well).  It would be
better, both logically and for consistency with existing practice,
to move the <I>attribute-specifier<SUB>opt</SUB></I> accordingly.</P>

<BR><BR><HR><A NAME="374"></A><H4>374.
  
Can explicit specialization outside namespace use qualified name?
</H4><B>Section: </B>8.3&#160; [dcl.meaning]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>23 August 2002<BR>


<P>[Voted into WP at March, 2010 meeting as document N3064.]</P>

<P>This case is nonstandard by 8.3 [dcl.meaning] paragraph 1
(there is a requirement that the specialization first be declared within
the namespace before being defined outside of the namespace),
but probably should be allowed:</P>
<PRE>
  namespace NS1 {
    template&lt;class T&gt;
    class CDoor {
    public:
      int mtd() { return 1; }
    };
  }
  template&lt;&gt; int NS1::CDoor&lt;char&gt;::mtd()
  {
    return 0;
  }
</PRE>

<P><B>Notes from October 2002 meeting:</B></P>

<P>There was agreement that we wanted to allow this.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<OL><LI><P>Change 8.3 [dcl.meaning] as follows:</P></LI>

<BLOCKQUOTE>

...A <I>declarator-id</I> shall not be qualified except for the
definition of a member function (9.3 [class.mfct]) or
static data member (9.4 [class.static]) outside of its
class, the definition or explicit instantiation of a function or
variable member of a namespace outside of its namespace, or the
definition of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a previously declared</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an</SPAN>
explicit specialization outside of its namespace, or the
declaration of a friend function that is a member of another
class or namespace (11.3 [class.friend]). When the
<I>declarator-id</I> is qualified, the declaration shall refer to
a previously declared member of the class or namespace to which
the qualifier refers (or of an inline namespace within that scope
(7.3.1 [namespace.def])) <SPAN style="font-weight:bold;background-color:#A0FFA0">or to a specialization
thereof</SPAN>, and the member shall not have been introduced by a
<I>using-declaration</I> in the scope of the class or namespace
nominated by the <I>nested-name-specifier</I> of the
<I>declarator-id</I>.  [<I>Note:</I>...

</BLOCKQUOTE>

<LI><P>Change 14.7.3 [temp.expl.spec] paragraphs 2-4 as follows:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">An explicit specialization shall appear in namespace
scope.</SPAN> An explicit specialization <SPAN style="font-weight:bold;background-color:#A0FFA0">whose
<I>declarator-id</I> is not qualified</SPAN> shall be declared in
the nearest enclosing namespace of the template, or, if the
namespace is inline (7.3.1 [namespace.def]), any namespace
from its enclosing namespace set.  Such a declaration may also be
a definition. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">If the declaration is not a definition, the
specialization may be defined later (7.3.1.2 [namespace.memdef]).</SPAN></P>

<P>A declaration of a function template or class template being
explicitly specialized shall <SPAN style="text-decoration:line-through;background-color:#FFA0A0">be in scope at the point
of</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">precede the</SPAN> declaration of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">an</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">the</SPAN> explicit specialization. [<I>Note:</I> a
declaration, but not a definition of the template is required.
&#8212;<I>end note</I>] The definition of a class or class
template shall <SPAN style="text-decoration:line-through;background-color:#FFA0A0">be in scope at the point of</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">precede the</SPAN> declaration of an explicit specialization
for a member template of the class or class
template. [<I>Example:</I> ... &#8212;<I>end example</I>]</P>

<P>A member function, a member class or a static data member of a
class template may be explicitly specialized for a class
specialization that is implicitly instantiated; in this case, the
definition of the class template shall <SPAN style="text-decoration:line-through;background-color:#FFA0A0">be in scope at the
point of declaration of</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">preced</SPAN> the explicit
specialization for the member of the class template.  If such an
explicit specialization for the member of a class template names
an implicitly-declared special member function (Clause
12 [special]), the program is ill-formed.</P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="920"></A><H4>920.
  
Interaction of inline namespaces and <I>using-declaration</I>s
</H4><B>Section: </B>8.3&#160; [dcl.meaning]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Michael Wong
 &#160;&#160;&#160;

 <B>Date: </B>19 June, 2009<BR>


<P>[Voted into WP at March, 2010 meeting as part of document N3079.]</P>

<P>According to 8.3 [dcl.meaning] paragraph 1,</P>

<BLOCKQUOTE>

When the <I>declarator-id</I> is qualified, the declaration shall
refer to a previously declared member of the class or namespace to
which the qualifier refers (or of an inline namespace within that
scope (7.3.1 [namespace.def])), and the member shall not have
been introduced by a <I>using-declaration</I> in the scope of the
class or namespace nominated by the <I>nested-name-specifier</I> of
the <I>declarator-id</I>.

</BLOCKQUOTE>

<P>This would appear to make the following example ill-formed, even
though it would be well-formed if the <I>using-declaration</I> were
omitted:</P>

<PRE>
    namespace A {
      inline namespace B {
        template &lt;class T&gt; void foo() { }
     }
     using B::foo;
    }
    template void A::foo&lt;int&gt;();
</PRE>

<P>This seems strange.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 8.3 [dcl.meaning] paragraph 1 as follows:</P>

<BLOCKQUOTE>

...When the <I>declarator-id</I> is qualified, the declaration shall
refer to a previously declared member of the class or namespace to
which the qualifier refers (or<SPAN style="font-weight:bold;background-color:#A0FFA0">, in the case of a namespace,</SPAN>
of an <SPAN style="font-weight:bold;background-color:#A0FFA0">element of the</SPAN> inline namespace <SPAN style="text-decoration:line-through;background-color:#FFA0A0">within that
scope</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">set of that namespace</SPAN> (7.3.1 [namespace.def]))<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, and</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">;</SPAN> the member shall not
<SPAN style="font-weight:bold;background-color:#A0FFA0">merely</SPAN> have been introduced by a <I>using-declaration</I>
in the scope of the class or namespace nominated by the
<I>nested-name-specifier</I> of the <I>declarator-id</I>.
[<I>Note:</I>...

</BLOCKQUOTE>

<P>(Note: this resolution depends on the resolution of
<A HREF="
     cwg_defects.html#861">issue 861</A>.)</P>

<BR><BR><HR><A NAME="701"></A><H4>701.
  
When is the array-to-pointer conversion applied?
</H4><B>Section: </B>8.3.4&#160; [dcl.array]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Eelis van der Weegen
 &#160;&#160;&#160;

 <B>Date: </B>13 July, 2008<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>Paragraph 7 of 8.3.4 [dcl.array] says,</P>

<BLOCKQUOTE>

If <TT>E</TT> is an <I>n</I>-dimensional array of rank <I>i</I>
&#215; <I>j</I> &#215; ... &#215; <I>k</I>, then <TT>E</TT>
appearing in an expression is converted to a pointer to an (<I>n</I> -
1)-dimensional array with rank <I>j</I> &#215; ... &#215;
<I>k</I>.

</BLOCKQUOTE>

<P>This formulation does not allow for the existence of expressions
in which the array-to-pointer conversion does <I>not</I> occur
(as specified in clause 5 [expr] paragraph 9).  This
paragraph should be no more than a note, if it appears at all, and
the wording should be corrected.</P>

<P><B>Proposed resolution (November, 2009):</B></P>

<P>Change paragraphs 6-8 of 8.3.4 [dcl.array] into a
note and make the indicated changes:</P>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> </SPAN>Except where it has been declared for
a class (13.5.5 [over.sub]), the subscript operator
<TT>[]</TT> is interpreted in such a way that <TT>E1[E2]</TT> is
identical to <TT>*((E1)+(E2))</TT>. Because of the conversion
rules that apply to <TT>+</TT>, if <TT>E1</TT> is an array and
<TT>E2</TT> an integer, then <TT>E1[E2]</TT> refers to the
<TT>E2</TT>-th member of <TT>E1</TT>.  Therefore, despite its
asymmetric appearance, subscripting is a commutative
operation.</P>

<P>A consistent rule is followed for multidimensional arrays. If
<TT>E</TT> is an <I>n</I>-dimensional array of rank <I>i</I> &#215;
<I>j</I> &#215; .&#160;.&#160;. &#215; <I>k</I>, then
<TT>E</TT> appearing in an expression <SPAN style="font-weight:bold;background-color:#A0FFA0">that is subject to the
array-to-pointer conversion (4.2 [conv.array])</SPAN> is
converted to a pointer to an (<I>n</I>-1)-dimensional array with
rank <I>j</I> &#215; .&#160;.&#160;. &#215; <I>k</I>.  If the
<TT>*</TT> operator, either explicitly or implicitly as a result
of subscripting, is applied to this pointer, the result is the
pointed-to (<I>n</I>-1)-dimensional array, which itself is
immediately converted into a pointer.</P>

<P>[<I>Example:</I> consider</P>

<UL><TT>int x[3][5];</TT></UL>

<P>Here <TT>x</TT> is a 3 &#215; 5 array of integers.  When
<TT>x</TT> appears in an expression, it is converted to a pointer to
(the first of three) five-membered arrays of integers.  In the
expression <TT>x[i]</TT> which is equivalent to <TT>*(x+i)</TT>,
<TT>x</TT> is first converted to a pointer as described; then
<TT>x+i</TT> is converted to the type of <TT>x</TT>, which involves
multiplying <TT>i</TT> by the length of the object to which the
pointer points, namely five integer objects. The results are added and
indirection applied to yield an array (of five integers), which in
turn is converted to a pointer to the first of the integers. If there
is another subscript the same argument applies again; this time the
result is an integer.  &#8212;<I>end example</I>]<SPAN style="font-weight:bold;background-color:#A0FFA0"> &#8212;<I>end
note</I>]</SPAN></P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="713"></A><H4>713.
  
Unclear note about cv-qualified function types
</H4><B>Section: </B>8.3.5&#160; [dcl.fct]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Doug Gregor
 &#160;&#160;&#160;

 <B>Date: </B>11 September, 2008<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>4.4 [conv.qual] paragraph 3 consists of a note reading,</P>

<BLOCKQUOTE>

[<I>Note:</I> Function types (including those used in pointer to
member function types) are never cv-qualified (8.3.5 [dcl.fct]). &#8212;<I>end note</I>]

</BLOCKQUOTE>

<P>However, 8.3.5 [dcl.fct] paragraph 7 says,</P>

<BLOCKQUOTE>

A <I>cv-qualifier-seq</I> shall only be part of the function type...

</BLOCKQUOTE>

<P>This sounds like a contradiction, although formally it is not:
a &#8220;function type with a <I>cv-qualifier-seq</I>&#8221; is not a
&#8220;cv-qualified function type.&#8221;  It would be helpful to
make this distinction clearer.</P>

<P><B>Proposed resolution (March, 2009):</B></P>

<OL><LI><P>Change 8.3.5 [dcl.fct] paragraph 7 as
follows:</P></LI>

<BLOCKQUOTE>

A <I>cv-qualifier-seq</I> shall only be part of the function type
for a non-static member function, the function type to which a
pointer to member refers, or the top-level function type of a
function typedef declaration. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> A function type
that has a <I>cv-qualifier-seq</I> is not a cv-qualified type;
there are no cv-qualified function types. &#8212;<I>end
note</I>]</SPAN> The effect of a <I>cv-qualifier-seq</I> in a
function declarator...

</BLOCKQUOTE>

<LI><P>Change 3.9.3 [basic.type.qualifier] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

...See 8.3.5 [dcl.fct] and 9.3.2 [class.this]
regarding <SPAN style="text-decoration:line-through;background-color:#FFA0A0">cv-qualified</SPAN> function types <SPAN style="font-weight:bold;background-color:#A0FFA0">that have
<I>cv-qualifier</I>s</SPAN>.

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="818"></A><H4>818.
  
Function parameter packs in non-final positions
</H4><B>Section: </B>8.3.5&#160; [dcl.fct]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#US45">N2800 comment
  US&#160;45<BR></A>

<P>[Voted into WP at March, 2010 meeting as part of document N3079.]</P>

<P>8.3.5 [dcl.fct] paragraph 13 requires that a parameter pack,
if present, must appear at the end of the parameter list. This restriction
is not necessary when template argument deduction is not needed and is
inconsistent with the way pack expansions are handled.  It should be
removed.</P>

<P>(See also <A HREF="
     cwg_defects.html#692">issue 692</A>.)</P>

<BR><BR><HR><A NAME="956"></A><H4>956.
  
Function prototype scope with late-specified return types
</H4><B>Section: </B>8.3.5&#160; [dcl.fct]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>21 August, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>According to 3.3.4 [basic.scope.proto] paragraph 1,</P>

<BLOCKQUOTE>

In a function declaration, or in any function declarator except the
declarator of a function definition (8.4 [dcl.fct.def]), names of
parameters (if supplied) have function prototype scope, which
terminates at the end of the nearest enclosing function declarator.

</BLOCKQUOTE>

<P>Happily, this permits the use of parameter names with <TT>decltype</TT>
in a late-specified return type, because the return type is part of the
function's declarator.  However, the note in 8.3.5 [dcl.fct]
paragraph 11 is now inaccurate and should be updated:</P>

<BLOCKQUOTE>

[<I>Note:</I> ...If a parameter name is present in a function
declaration that is not a definition, it cannot be used outside of the
<I>parameter-declaration-clause</I> since it goes out of scope at the
end of the function declarator (3.3 [basic.scope]). &#8212;<I>end note</I>]

</BLOCKQUOTE>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change the note in 8.3.5 [dcl.fct] paragraph 10 as follows:</P>

<BLOCKQUOTE>

...[<I>Note:</I> in particular, parameter names are also optional in
function definitions and names used for a parameter in different
declarations and the definition of a function need not be the
same.  If a parameter name is present in a function declaration
that is not a definition, it cannot be used outside of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the
<I>parameter-declaration-clause</I> since it goes out of scope at
the end of the function declarator (3.3 [basic.scope])</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">its function declarator because that is
the extent of its potential scope (3.3.4 [basic.scope.proto])</SPAN>. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<BR><BR><HR><A NAME="777"></A><H4>777.
  
Default arguments and parameter packs
</H4><B>Section: </B>8.3.6&#160; [dcl.fct.default]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Michael Wong
 &#160;&#160;&#160;

 <B>Date: </B>13 February, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>8.3.6 [dcl.fct.default] paragraph 4 says,</P>

<BLOCKQUOTE>

In a given function declaration, all parameters subsequent to a
parameter with a default argument shall have default arguments
supplied in this or previous declarations.

</BLOCKQUOTE>

<P>It is not clear whether this applies to parameter packs or not.
For example, is the following well-formed?</P>

<PRE>
    template &lt;typename... T&gt; void f(int i = 0, T ...args) { }
</PRE>

<P>Note for comparison the corresponding wording in
14.1 [temp.param] paragraph 11 regarding template parameter
packs:</P>

<BLOCKQUOTE>

If a <I>template-parameter</I> of a class template has a default
<I>template-argument</I>, each subsequent <I>template-parameter</I>
shall either have a default <I>template-argument</I> supplied or be a
template parameter pack.

</BLOCKQUOTE>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 8.3.6 [dcl.fct.default] paragraph 4:</P>

<BLOCKQUOTE>

...In a given function declaration, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">all</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">each</SPAN>
parameter<SPAN style="text-decoration:line-through;background-color:#FFA0A0">s</SPAN> subsequent to a parameter with a default
argument shall have <SPAN style="font-weight:bold;background-color:#A0FFA0">a</SPAN> default argument<SPAN style="text-decoration:line-through;background-color:#FFA0A0">s</SPAN> supplied
in this or <SPAN style="font-weight:bold;background-color:#A0FFA0">a</SPAN> previous declaration<SPAN style="text-decoration:line-through;background-color:#FFA0A0">s</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">or shall
be a function parameter pack</SPAN>. A default argument...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="732"></A><H4>732.
  
Late-specified return types in function definitions
</H4><B>Section: </B>8.4&#160; [dcl.fct.def]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>7 October, 2008<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#DE13">N2800 comment
  DE&#160;13<BR></A>

<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>



<P>The grammar in 8.4 [dcl.fct.def] paragraph 2 incorrectly
excludes late-specified return types and should be corrected.</P>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="845"></A><H4>845.
  
What is the &#8220;first declaration&#8221; of an explicit specialization?
</H4><B>Section: </B>8.4&#160; [dcl.fct.def]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>20 March, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>According to 8.4 [dcl.fct.def] paragraph 10,</P>

<BLOCKQUOTE>

A deleted definition of a function shall be the first declaration of
the function.

</BLOCKQUOTE>

<P>The Standard is not currently clear about what the &#8220;first
declaration&#8221; of an explicit specialization of a function
template is.  For example,</P>

<PRE>
    template&lt;typename T&gt; void f() { }
    template&lt;&gt; void f&lt;int&gt;() = delete;  //<SPAN style="font-family:Times;font-style:italic"> First declaration?</SPAN>
</PRE>

<P><B>Proposed resolution (October, 2009):</B></P>

<BLOCKQUOTE>

A deleted definition of a function shall be the first declaration of
the function <SPAN style="font-weight:bold;background-color:#A0FFA0">or, for an explicit specialization of a function
template, the first declaration of that specialization</SPAN>.

</BLOCKQUOTE>

<P>(This resolution also resolves <A HREF="
     cwg_defects.html#915">issue 915</A>.)</P>

<P><B>Notes from the October, 2009 meeting:</B></P>

<P>It was observed that this specification is complicated by the fact
that the &#8220;first declaration&#8221; of a function might be in a
block-extern declaration.</P>

<BR><BR><HR><A NAME="906"></A><H4>906.
  
Which special member functions can be defaulted?
</H4><B>Section: </B>8.4&#160; [dcl.fct.def]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>27 May, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>The only restriction placed on the use of &#8220;<TT>=default</TT>&#8221;
in 8.4 [dcl.fct.def] paragraph 9 is that a defaulted function must
be a special member function.  However, there are many variations of
declarations of special member functions, and it's not clear which of
those should be able to be defaulted.  Among the possibilities:</P>

<UL><LI><P>default arguments</P></LI>

<LI><P>by-value parameter for a copy assignment operator</P></LI>

<LI><P>exception specifications</P></LI>

<LI><P>arbitrary return values for copy assignment operators</P></LI>

<LI><P>a <TT>const</TT> reference parameter when the implicit
function would have a non-const</P></LI>

</UL>

<P>Presumably, you should only be able to default a function if it
is declared compatibly with the implicit declaration that would have
been generated.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<OL><LI><P>Change 8.4 [dcl.fct.def] paragraph 9 as follows:</P></LI>

<BLOCKQUOTE>

<P>A function definition of the form:</P>

<UL><I>decl-specifier-seq<SUB>opt</SUB> attribute-specifier<SUB>opt</SUB> declarator</I> <TT>= default ;</TT></UL>

<P>is called an <I>explicitly-defaulted</I> definition. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">Only special
member functions may be explicitly defaulted, and the implementation
shall define them as if they had implicit definitions (12.1 [class.ctor], 12.4 [class.dtor], 12.8 [class.copy]).</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">A function that is explicitly defaulted shall</SPAN></P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">be a special member function,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">have the same declared function type (except for possibly-differing
<I>ref-qualifier</I>s and except that in the case of a copy constructor
or copy assignment operator, the parameter type may be
&#8220;reference to non-const <TT>T</TT>,&#8221; where <TT>T</TT> is
the name of the member function's class) as if it had been implicitly
declared,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">not have default arguments, and</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">not have an <I>exception-specification</I>.</SPAN></P></LI>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> This implies that parameter types, return type,
and cv-qualifiers must match the hypothetical implicit declaration.
&#8212;<I>end note</I>] An explicitly-defaulted function may be declared
constexpr only if it would have been implicitly declared as constexpr.
If it is explicitly defaulted on its first declaration,</SPAN></P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">it shall be public,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">it shall not be explicit,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">it shall not be virtual,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">it is implicitly considered to have the same
<I>exception-specification</I> as if it had been implicitly
declared (15.4 [except.spec]), and</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">in the case of a copy constructor or copy assignment
operator, it shall have the same parameter type as if it had been
implicitly declared.</SPAN></P></LI>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> Such a special member function may be trivial,
and thus its accessibility and explicitness should match the
hypothetical implicit definition; see below. &#8212;<I>end note</I>]
[<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  struct S {
    S(int a = 0) = default;              //<SPAN style="font-family:Times;font-style:italic"> ill-formed: default argument</SPAN>
    void operator=(const S&amp;) = default;  //<SPAN style="font-family:Times;font-style:italic"> ill-formed: non-matching return type</SPAN>
    ~S() throw() = default;              //<SPAN style="font-family:Times;font-style:italic"> ill-formed: exception-specification</SPAN>
  private:
    S(S&amp;);                               //<SPAN style="font-family:Times;font-style:italic"> OK: private copy constructor</SPAN>
  };
  S::S(S&amp;) = default;                    //<SPAN style="font-family:Times;font-style:italic"> OK: defines copy constructor</SPAN></SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>] Explicitly-defaulted functions and
implicitly-declared functions are collectively called <I>defaulted</I>
functions, and the implementation shall provide implicit definitions
for them (12.1 [class.ctor], 12.4 [class.dtor],
12.8 [class.copy]), which might mean defining them as
deleted.</SPAN>A special member function that would be implicitly
defined as deleted may be explicitly defaulted only on its first
declaration, in which case it is defined as deleted.  A special member
function is <I>user-provided</I> if it is user-declared and not
explicitly defaulted on its first declaration. A user-provided
explicitly-defaulted function is defined at the point where it is
explicitly defaulted. [<I>Note:</I>...</P>

</BLOCKQUOTE>

<P><I>[Editorial note: this change incorporates the overlapping portion
of the resolution of <A HREF="
     cwg_defects.html#667">issue 667</A>.]</I></P>

<LI><P>Change 12.1 [class.ctor] paragraph 6 as follows:</P></LI>

...[<I>Note:</I> ...An explicitly-defaulted definition <SPAN style="text-decoration:line-through;background-color:#FFA0A0">has
no</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">might have an</SPAN> implicit
<I>exception-specification</I><SPAN style="font-weight:bold;background-color:#A0FFA0">, see 8.4 [dcl.fct.def]</SPAN>. &#8212;<I>end note</I>]

</OL>

<P>This resolution also resolves <A HREF="
     cwg_defects.html#905">issue 905</A>.
See also <A HREF="
     cwg_defects.html#667">issue 667</A>.</P>

<BR><BR><HR><A NAME="908"></A><H4>908.
  
Deleted global allocation and deallocation functions
</H4><B>Section: </B>8.4&#160; [dcl.fct.def]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>2 June, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>According to 8.4 [dcl.fct.def] paragraph 10, a deleted
definition of a function must be its first declaration.  It is not
clear whether this requirement can be satisfied for the global
allocation and deallocation functions.  According to
3.7.4 [basic.stc.dynamic] paragraph 2, they are &#8220;implicitly
declared in global scope in each translation unit of a program.&#8221;
However, that does not specify where in the translation unit the
declaration is considered to take place.  This needs to be clarified.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 8.4 [dcl.fct.def] paragraph 10 as follows:</P>

<BLOCKQUOTE>

...A deleted definition of a function shall be the first declaration
of the function. <SPAN style="font-weight:bold;background-color:#A0FFA0">An implicitly declared allocation or
deallocation function (3.7.4 [basic.stc.dynamic]) shall not be
defined as deleted.</SPAN> [<I>Example:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="915"></A><H4>915.
  
Deleted specializations of member function templates
</H4><B>Section: </B>8.4&#160; [dcl.fct.def]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>12 June, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>It is not clear whether the following definition of an explicit
specialization of a member function template is permitted or not:</P>

<PRE>
    template &lt;typenanme T&gt; struct S {
      template &lt;typename U&gt; void f();
    };
    template &lt;&gt; template &lt;typename U&gt;
      void S&lt;int&gt;::f() = delete;
</PRE>

<P>Is the explicit specialization the &#8220;first declaration&#8221; of
the member function template?</P>

<P>(See also <A HREF="
     cwg_defects.html#845">issue 845</A>.)</P>

<P><B>Notes from the July, 2009 meeting:</B></P>

<P>The intent is that this usage should be supported.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>This issue is resolved by the resolution of <A HREF="
     cwg_defects.html#845">issue 845</A>.</P>

<BR><BR><HR><A NAME="928"></A><H4>928.
  
Defaulting a function that would be implicitly defined as deleted
</H4><B>Section: </B>8.4&#160; [dcl.fct.def]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>1 July, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>8.4 [dcl.fct.def] paragraph 9 says,</P>

<BLOCKQUOTE>

A special member function that would be implicitly defined as deleted
shall not be explicitly defaulted.

</BLOCKQUOTE>

<P>It would be more regular (and thus useful in generic programming) if
such a member function were itself simply defined as deleted rather than
being made ill-formed.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<OL><LI><P>Change 8.4 [dcl.fct.def] paragraph 9 as follows:</P></LI>

<BLOCKQUOTE>

Only special member functions may be explicitly defaulted, and the
implementation shall define them as if they had implicit definitions
(12.1 [class.ctor], 12.4 [class.dtor], 12.8 [class.copy]). <SPAN style="text-decoration:line-through;background-color:#FFA0A0">A special member function that would be implicitly
defined as deleted shall not be explicitly defaulted.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">A
special member function that would be implicitly defined as deleted
may be explicitly defaulted only on its first declaration, in which
case it is defined as deleted.</SPAN> A special member function is
user-provided if...

</BLOCKQUOTE>

<LI><P>Change 12.1 [class.ctor] paragraph 6 as follows:</P></LI>

<BLOCKQUOTE>

A non-user-provided default constructor for a class is implicitly
defined when it is used (3.2 [basic.def.odr]) to create an object
of its class type (1.8 [intro.object]).  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">If the
implicitly-defined default constructor is explicitly defaulted but the
corresponding implicit declaration would have been deleted, the
program is ill-formed.</SPAN> The implicitly-defined or
explicitly-defaulted default constructor...

</BLOCKQUOTE>

<LI><P>Change 12.4 [class.dtor] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

<P>A program is ill-formed if the class for which a destructor is
implicitly defined or explicitly defaulted has: <SPAN style="text-decoration:line-through;background-color:#FFA0A0">if the
implicitly-defined destructor is explicitly defaulted, but the
corresponding implicit declaration would have been deleted.</SPAN></P>

<UL>

<LI><P>a non-static data member of class type (or array thereof) with an inaccessible destructor, or</P></LI>

<LI><P>a base class with an inaccessible destructor.</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

...[<I>Note:</I> the copy constructor is implicitly defined even if
the implementation elided its use (12.2 [class.temporary]). &#8212;<I>end note</I>] <SPAN style="text-decoration:line-through;background-color:#FFA0A0">A program is ill-formed if
the implicitly-defined copy constructor is explicitly defaulted, but
the corresponding implicit declaration would have been deleted.</SPAN>

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraph 12 as follows:</P></LI>

<BLOCKQUOTE>

A non-user-provided copy assignment operator is <I>implicitly defined</I>
when an object of its class type is assigned a value of its class type
or a value of a class type derived from its class type. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">A program is
ill-formed if the implicitly-defined copy assignment operator is
explicitly defaulted, but the corresponding implicit declaration would
have been deleted.</SPAN>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="611"></A><H4>611.
  
Zero-initializing references
</H4><B>Section: </B>8.5&#160; [dcl.init]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>29 December 2006<BR>


<P>According to 8.5 [dcl.init] paragraph 5,</P>

<BLOCKQUOTE>

<P>To <I>zero-initialize</I> an object of type <TT>T</TT> means:</P>

<UL>

<LI><P>...</P></LI>

<LI><P>if <TT>T</TT> is a reference type, no initialization is
performed.</P></LI>
</UL>

</BLOCKQUOTE>

<P>However, a reference is not an object, so this makes no sense.</P>

<P><B>Proposed resolution (March, 2010):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#633">issue 633</A> in document N2993.</P>

<BR><BR><HR><A NAME="869"></A><H4>869.
  
Uninitialized <TT>thread_local</TT> objects
</H4><B>Section: </B>8.5&#160; [dcl.init]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>14 April, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>8.5 [dcl.init] paragraph 11 says,</P>

<BLOCKQUOTE>

If no initializer is specified for an object, the object is
default-initialized; if no initialization is performed, a non-static
object has indeterminate value.

</BLOCKQUOTE>

<P>This is inaccurate, because objects with thread storage duration
are zero-initialized (3.6.2 [basic.start.init] paragraph 2).</P>

<P><B>Proposed resolution (November, 2009):</B></P>

<P>Change 8.5 [dcl.init] paragraph 11 as follows:</P>

<BLOCKQUOTE>

If no initializer is specified for an object, the object is
default-initialized; if no initialization is performed, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a
non-static</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an</SPAN> object <SPAN style="font-weight:bold;background-color:#A0FFA0">with automatic or dynamic
storage duration</SPAN> has indeterminate value.  [<I>Note:</I> objects
with static <SPAN style="font-weight:bold;background-color:#A0FFA0">or thread</SPAN> storage duration are
zero-initialized, see 3.6.2 [basic.start.init]<SPAN style="font-weight:bold;background-color:#A0FFA0">.</SPAN> &#8212;<I>end
note</I>]<SPAN style="text-decoration:line-through;background-color:#FFA0A0">.</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="886"></A><H4>886.
  
Member initializers and aggregates
</H4><B>Section: </B>8.5.1&#160; [dcl.init.aggr]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>5 May, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>The current wording of 8.5.1 [dcl.init.aggr] paragraph 1
does not consider <I>brace-or-equal-initializer</I>s on members
as affecting whether a class type is an aggregate or not.
Because in-class member initializers are essentially syntactic
sugar for <I>mem-initializer</I>s, and the presence of a
user-provided constructor disqualifies a class from being an
aggregate, presumably the same should hold true of member
initializers.</P>

<P><B>Proposed resolution (November, 2009):</B></P>

<P>Change 8.5.1 [dcl.init.aggr] paragraph 1 as follows:</P>

<BLOCKQUOTE>

An <I>aggregate</I> is an array or a class (Clause 9 [class]) with no user-provided constructors (12.1 [class.ctor]), <SPAN style="font-weight:bold;background-color:#A0FFA0">no <I>brace-or-equal-initializer</I>s for
non-static data members (9.2 [class.mem]),</SPAN> no
private or protected non-static data members (Clause 11 [class.access]), no base classes (Clause 10 [class.derived]),
and no virtual functions (10.3 [class.virtual]).

</BLOCKQUOTE>

<BR><BR><HR><A NAME="737"></A><H4>737.
  
Uninitialized trailing characters in string initialization
</H4><B>Section: </B>8.5.2&#160; [dcl.init.string]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>James Kanze
 &#160;&#160;&#160;

 <B>Date: </B>26 October, 2008<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>The current specification of string initialization in 8.5.2 [dcl.init.string] leaves uninitialized all characters following the
terminating <TT>'\0'</TT> of a character array with automatic storage
duration.  This is different from C99, in which string initialization
is handled like aggregate initialization and all trailing characters
are zeroed (6.7.8 paragraph 21).</P>

<P>(See also <A HREF="
     cwg_defects.html#694">issue 694</A>, in which we
are considering following C99 in a somewhat similar case of
zero-initializing trailing data.)</P>

<P><B>Proposed resolution (September, 2009):</B></P>

<P>Add a new paragraph following 8.5.2 [dcl.init.string] paragraph 2:</P>

<BLOCKQUOTE>

<P>There shall not be more initializers than there are array elements. [<I>Example:</I></P>

<PRE>
  char cv[4] = "asdf";    //<SPAN style="font-family:Times;font-style:italic"> error</SPAN>
</PRE>

<P>is ill-formed since there is no space for the implied trailing '\0'.
&#8212;<I>end example</I>]</P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">If there are fewer initializers than there are array elements,
then each element not explicitly initialized shall be zero-initialized
(8.5 [dcl.init]).</SPAN></P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="936"></A><H4>936.
  
Array initialization with new string literals
</H4><B>Section: </B>8.5.2&#160; [dcl.init.string]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>11 July, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>8.5.2 [dcl.init.string] paragraph 1 says,</P>

<BLOCKQUOTE>

A <TT>char</TT> array (whether plain <TT>char</TT>, <TT>signed
char</TT>, or <TT>unsigned char</TT>), <TT>char16_t</TT> array,
<TT>char32_t</TT> array, or <TT>wchar_t</TT> array can be initialized
by a <I>string-literal</I> (optionally enclosed in braces) with no
prefix, with a <TT>u</TT> prefix, with a <TT>U</TT> prefix, or with an
<TT>L</TT> prefix, respectively...

</BLOCKQUOTE>

<P>This formulation does not allow for raw and UTF-8 literals.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 8.5.2 [dcl.init.string] paragraph 1 as follows:</P>

<BLOCKQUOTE>

A char array (whether plain <TT>char</TT>, <TT>signed char</TT>, or
<TT>unsigned char</TT>), <TT>char16_t</TT> array, <TT>char32_t</TT>
array, or <TT>wchar_t</TT> array can be initialized by a
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>string-literal</I> (optionally enclosed in braces) with no
prefix, with a <TT>u</TT> prefix, with a <TT>U</TT> prefix, or with an
<TT>L</TT> prefix</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">narrow character literal,
<TT>char16_t</TT> string literal, <TT>char32_t</TT> string literal, or
wide string literal</SPAN>, respectively<SPAN style="text-decoration:line-through;background-color:#FFA0A0">; successive</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">,
or by an appropriately-typed string literal enclosed in
braces. Successive</SPAN> characters of the
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>string-literal</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">value of the string
literal</SPAN> initialize the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">members</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">elements</SPAN>
of the array. [<I>Example:</I> ...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="589"></A><H4>589.
  
Direct binding of class and array rvalues in reference initialization
</H4><B>Section: </B>8.5.3&#160; [dcl.init.ref]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>26 July 2006<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>The resolutions of issues <A HREF="
     cwg_defects.html#391">391</A> and
<A HREF="
     cwg_defects.html#450">450</A> say that the reference is
&#8220;bound to&#8221; the class or array rvalue, but it does not
say that the reference &#8220;binds directly&#8221; to the
initializer, as it does for the cases that fall under the first
bullet in 8.5.3 [dcl.init.ref] paragraph 5.  However,
this phrasing is important in determining the implicit
conversion sequence for an argument passed to a parameter with
reference type (13.3.3.1.4 [over.ics.ref]), where
paragraph 2 says,</P>

<BLOCKQUOTE>

When a parameter of reference type is not bound directly to an
argument expression, the conversion sequence is the one required
to convert the argument expression to the underlying type of the
reference according to 13.3.3.1 [over.best.ics]. Conceptually, this conversion sequence
corresponds to copy-initializing a temporary of the underlying
type with the argument expression.

</BLOCKQUOTE>

<P>The above-mentioned issue resolutions stated that no copy
is to be made in such reference initializations, so the
determination of the conversion sequence does not reflect the
initialization semantics.</P>

<P>Simply using the &#8220;binds directly&#8221; terminology in
the new wording may not be the right approach, however, as there
are other places in the Standard that also give special treatment
to directly-bound references.  For example, the first bullet of
5.16 [expr.cond] paragraph 3 says,</P>

<BLOCKQUOTE>

If <TT>E2</TT> is an lvalue: <TT>E1</TT> can be converted to
match <TT>E2</TT> if <TT>E1</TT> can be implicitly converted
(clause 4 [conv]) to the type &#8220;reference to
<TT>T2</TT>,&#8221; subject to the constraint that in the
conversion the reference must bind directly (8.5.3 [dcl.init.ref]) to <TT>E1</TT>.

</BLOCKQUOTE>

<P>The effect of simply saying that a reference &#8220;binds
directly&#8221; to a class rvalue can be seen in this example:</P>

<PRE>
    struct B { };
    struct D: B { };
    D f();
    void g(bool x, const B&amp; br) {
        x ? f() : br;   //<SPAN style="font-family:Times;font-style:italic"> result would be lvalue</SPAN>
    }
</PRE>

<P>It is not clear that treating this conditional expression as an
lvalue is a desirable outcome, even if the result of <TT>f()</TT>
were to &#8220;bind directly&#8221; to the <TT>const B&amp;</TT>
reference.</P>

<P><B>Proposed resolution (June, 2009):</B></P>

<OL><LI><P>Change 8.5.3 [dcl.init.ref] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

<P>A reference to type &#8220;<I>cv1</I> <TT>T1</TT>&#8221; is
initialized by an expression of type &#8220;<I>cv2</I>
<TT>T2</TT>&#8221; as follows:</P>

<UL><LI><P>If the reference is an lvalue reference and the initializer
expression</P></LI>

<UL><LI><P>is an lvalue (but is not a bit-field), and
&#8220;<I>cv1</I> <TT>T1</TT>&#8221; is reference-compatible with
&#8220;<I>cv2</I> <TT>T2</TT>,&#8221; or</P></LI>

<LI><P>has a class type (i.e., <TT>T2</TT> is a class type), where
<TT>T1</TT> is not reference-related to <TT>T2</TT>, and can be
implicitly converted to an lvalue of type &#8220;<I>cv3</I>
<TT>T3</TT>,&#8221; where &#8220;<I>cv1</I> <TT>T1</TT>&#8221; is
reference-compatible with &#8220;<I>cv3</I> <TT>T3</TT>&#8221; (this
conversion is selected by enumerating the applicable conversion
functions (13.3.1.6 [over.match.ref]) and choosing the best one
through overload resolution (13.3 [over.match])),</P></LI>

</UL>

<P>then the reference is bound <SPAN style="text-decoration:line-through;background-color:#FFA0A0">directly</SPAN> to the initializer
expression lvalue in the first case<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, and the reference is bound</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">and</SPAN> to the lvalue result of the conversion in the second case.
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">In these cases the reference is said to <I>bind directly</I> to the
initializer expression.</SPAN> [<I>Note:</I> the usual lvalue-to-rvalue
(4.1 [conv.lval]), array-to-pointer (4.2 [conv.array]), and function-to-pointer (4.3 [conv.func])
standard conversions are not needed, and therefore are suppressed,
when such direct bindings to lvalues are done.  &#8212;<I>end
note</I>]</P>

<P>[<I>Example:</I> ... &#8212;<I>end example</I>]</P>

<LI><P>Otherwise, the reference shall be an lvalue reference to a
non-volatile const type (i.e., <I>cv1</I> shall be <TT>const</TT>), or
the reference shall be an rvalue reference and the initializer
expression shall be an rvalue.  [<I>Example:</I> ... &#8212;<I>end
example]</I></P></LI>

<UL><LI><P>If the initializer expression is an rvalue, with
<TT>T2</TT> a class type, and &#8220;<I>cv1</I> <TT>T1</TT>&#8221; is
reference-compatible with &#8220;<I>cv2</I> <TT>T2</TT>,&#8221; the
reference is bound to the object represented by the rvalue (see
3.10 [basic.lval]) or to a sub-object within that
object.</P>

<P>[<I>Example:</I> ... &#8212;<I>end example</I>]</P>

</LI>

<LI><P>If the initializer expression is an rvalue, with <TT>T2</TT> an
array type, and &#8220;<I>cv1</I> <TT>T1</TT>&#8221; is
reference-compatible with &#8220;<I>cv2</I> <TT>T2</TT>,&#8221; the
reference is bound to the object represented by the rvalue (see
3.10 [basic.lval]).</P></LI>

<LI><P>Otherwise, a temporary of type &#8220;<I>cv1</I>
<TT>T1</TT>&#8221; is created and initialized from the initializer
expression using the rules for a non-reference copy initialization
(8.5 [dcl.init]).  The reference is then bound to the
temporary.  If <TT>T1</TT> is reference-related to <TT>T2</TT>,
<I>cv1</I> must be the same cv-qualification as, or greater
cv-qualification than, <I>cv2</I>; otherwise, the program is
ill-formed. [<I>Example:</I> ... &#8212;<I>end example</I>]</P></LI>

</UL>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">In all cases except the last (i.e., creating and initializing
a temporary from the initializer expression), the reference is said
to <I>bind directly</I> to the initializer expression.</SPAN></P>

</BLOCKQUOTE>

<LI><P>Change 5.16 [expr.cond] paragraph 3 bullet 1 as
follows:</P></LI>

<UL><LI><P>If <TT>E2</TT> is an lvalue: <TT>E1</TT> can be converted
to match <TT>E2</TT> if <TT>E1</TT> can be implicitly converted
(Clause 4 [conv]) to the type &#8220;lvalue reference to
<TT>T2</TT>&#8221;, subject to the constraint that in the conversion
the reference must bind directly (8.5.3 [dcl.init.ref]) to
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>E1</TT></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an lvalue</SPAN>.</P></LI></UL>

</OL>

<BR><BR><HR><A NAME="656"></A><H4>656.
  
Direct binding to the result of a conversion operator
</H4><B>Section: </B>8.5.3&#160; [dcl.init.ref]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>23 October 2007<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>Consider the following example:</P>

<PRE>
    struct A { };
    struct B : public A { };
    struct X {
       operator B();
    };
    X x;

    int main() {
       const A&amp; r = x;
       return 0;
    }
</PRE>

<P>It seems like the resolution of <A HREF="
     cwg_defects.html#391">issue 391</A> doesn't actually cover this; <TT>X</TT> is not
reference-compatible with <TT>A</TT>, so we go past the modified
bullet (8.5.3 [dcl.init.ref] paragraph 5, bullet 2,
sub-bullet 1), which reads:</P>

<BLOCKQUOTE>

If the initializer expression is an rvalue, with <TT>T2</TT> a class
type, and &#8220;<I>cv1</I> <TT>T1</TT>&#8221; is reference-compatible
with &#8220;<I>cv2</I> <TT>T2</TT>,&#8221; the reference is bound to
the object represented by the rvalue (see 3.10 [basic.lval])
or to a sub-object within that object.

</BLOCKQUOTE>

<P>and hit</P>

<BLOCKQUOTE>

Otherwise, a temporary of type &#8220;<I>cv1</I> <TT>T1</TT>&#8221; is
created and initialized from the initializer expression using the
rules for a non-reference copy initialization (8.5 [dcl.init]). The reference is then bound to the temporary.

</BLOCKQUOTE>

<P>which seems to require that we create an <TT>A</TT> temporary
copied from the return value of <TT>X::operator B()</TT> rather than
bind directly to the <TT>A</TT> subobject.  I think that the
resolution of <A HREF="
     cwg_defects.html#391">issue 391</A> should cover this
situation as well, and the EDG compiler seems to agree with me.</P>

<P>(See also <A HREF="
     cwg_defects.html#896">issue 896</A>.)</P>

<P><B>Proposed resolution (September, 2009):</B></P>

<OL><LI><P>Change 8.5.3 [dcl.init.ref] paragraph 5 as
follows:</P></LI>

<UL><LI><P>If the reference is an lvalue reference...</P></LI>

<LI><P>Otherwise, the reference shall be an lvalue reference to a
non-volatile const type...</P></LI>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">If the initializer expression is an rvalue, with
<TT>T2</TT> a class type, and &#8220;<I>cv1</I> <TT>T1</TT>&#8221; is
reference-compatible with &#8220;<I>cv2</I> <TT>T2</TT>,&#8221; the
reference is bound to the object represented by the rvalue (see
3.10 [basic.lval]) or to a sub-object within that
object.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">If <TT>T1</TT> and <TT>T2</TT> are class types
and</SPAN></P></LI>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">the initializer expression is an rvalue, and &#8220;<I>cv1</I> <TT>T1</TT>&#8221; is reference-compatible with &#8220;<I>cv2</I> <TT>T2</TT>,&#8221; or</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>T1</TT> is not reference-related to <TT>T2</TT>, and
the initializer expression can be implicitly converted to an rvalue of
type &#8220;<I>cv3</I> <TT>T3</TT>,&#8221; where &#8220;<I>cv1</I>
<TT>T1</TT>&#8221; is reference-compatible with &#8220;<I>cv3</I>
<TT>T3</TT>&#8221; (this conversion is selected by enumerating the
applicable conversion functions (13.3.1.6 [over.match.ref]) and
choosing the best one through overload resolution (13.3 [over.match]) ),</SPAN></P></LI>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">then the reference is bound to the initializer expression
rvalue in the first case, and to the object that is the result of the
conversion in the second case (or, in either case, to the appropriate
base class subobject of the object).</SPAN> [<I>Example:</I></P>

<PRE>
  struct A { };
  struct B : A { } b;
  extern B f();
  const A&amp; rca = f();    //<SPAN style="font-family:Times;font-style:italic"> Bound to the </SPAN>A<SPAN style="font-family:Times;font-style:italic"> subobject of the </SPAN>B<SPAN style="font-family:Times;font-style:italic"> rvalue.</SPAN>
  A&amp;&amp; rcb = f();         //<SPAN style="font-family:Times;font-style:italic"> Same as above</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  struct X {
    operator B();
  } x;
  const A&amp; r = x;        //<SPAN style="font-family:Times;font-style:italic"> Bound to the </SPAN>A<SPAN style="font-family:Times;font-style:italic"> subobject of the result of the conversion</SPAN></SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

<LI><P>...</P></LI>

</UL>

</UL>

<P><I>Editorial note: <A HREF="
     cwg_defects.html#589">issue 589</A> makes edits
to the top-level bullet preceding this one.  The wording resulting
from those edits should be changed for consistency with this wording
so that the text there reads, &#8220;...in the first case and to the
lvalue result of the conversion in the second case <SPAN style="font-weight:bold;background-color:#A0FFA0">(or, in either
case, to the appropriate base class subobject of the
object)</SPAN>.&#8221;</I></P>

<LI><P>Change 13.3 [over.match] paragraph 2, last bullet as
follows:</P></LI>

<UL><LI>invocation of a conversion function for conversion to an
lvalue <SPAN style="font-weight:bold;background-color:#A0FFA0">or class rvalue</SPAN> to which a reference (8.5.3 [dcl.init.ref]) will be directly bound (13.3.1.6 [over.match.ref]).</LI></UL>

<LI><P>Change 13.3.1.6 [over.match.ref] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

Under the conditions specified in 8.5.3 [dcl.init.ref], a
reference can be bound directly to an lvalue <SPAN style="font-weight:bold;background-color:#A0FFA0">or class
rvalue</SPAN> that is the result of applying a conversion function to
an initializer expression.  Overload resolution is used to select the
conversion function to be invoked.  Assuming that &#8220;<I>cv1</I>
<TT>T</TT>&#8221; is the underlying type of the reference being
initialized, and &#8220;<I>cv</I> <TT>S</TT>&#8221; is the type of the
initializer expression, with <TT>S</TT> a class type, the candidate
functions are selected as follows:

<UL><LI><P>The conversion functions of <TT>S</TT> and its base classes
are considered, except that for copy-initialization, only the
non-explicit conversion functions are considered.  Those that are not
hidden within <TT>S</TT> and yield type &#8220;lvalue reference to
<I>cv2</I> <TT>T2</TT>&#8221; <SPAN style="font-weight:bold;background-color:#A0FFA0">(when 8.5.3 [dcl.init.ref]
requires an lvalue result), or &#8220;<I>cv2</I> <TT>T2</TT>&#8221; or
&#8220;rvalue reference to <I>cv2</I> <TT>T2</TT> (when 8.5.3 [dcl.init.ref] requires an rvalue result)</SPAN>, where
&#8220;<I>cv1</I> <TT>T</TT>&#8221; is reference-compatible
(8.5.3 [dcl.init.ref]) with &#8220;<I>cv2</I>
<TT>T2</TT>&#8221;, are candidate functions.</P></LI></UL>

</BLOCKQUOTE>

</OL>

<P>(Note: this resolution also resolves <A HREF="
     cwg_defects.html#896">issue 896</A>.)</P>

<BR><BR><HR><A NAME="664"></A><H4>664.
  
Direct binding of references to non-class rvalue references
</H4><B>Section: </B>8.5.3&#160; [dcl.init.ref]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Eric Niebler
 &#160;&#160;&#160;

 <B>Date: </B>1 December 2007<BR>


<P>[Voted into WP at March, 2010 meeting as document N3055.]</P>



<P>According to 8.5.3 [dcl.init.ref] paragraph 5, a reference
initialized with a reference-compatible rvalue of class type binds
directly to the object.  A reference-compatible non-class rvalue
reference, however, is first copied to a temporary and the reference
binds to that temporary, not to the target of the rvalue reference.
This can cause problems when the result of a forwarding function is
used in such a way that the address of the result is captured.  For
example:</P>

<PRE>
    struct ref {
        explicit ref(int&amp;&amp; i): p(&amp;i) { }
        int* p;
    };

    int&amp;&amp; forward(int&amp;&amp; i) {
        return i;
    }

    void f(int&amp;&amp; i) {
        ref r(forward(i));
        //<SPAN style="font-family:Times;font-style:italic"> Here </SPAN>r.p<SPAN style="font-family:Times;font-style:italic"> is a dangling pointer, pointing to a defunct </SPAN>int<SPAN style="font-family:Times;font-style:italic"> temporary</SPAN>
    }
</PRE>

<P>A formulation is needed so that rvalue references are treated like
class and array rvalues.</P>

<P><B>Notes from the February, 2008 meeting:</B></P>

<P>You can't just treat scalar rvalues like class and array rvalues,
because they might not have an associated object.  However, if you have
an rvalue reference, you know that there is an object, so probably the
best way to address this issue is to specify somehow that binding a
reference to an rvalue reference does not introduce a new temporary.</P>

<P>(See also issues <A HREF="
     cwg_defects.html#690">690</A> and
<A HREF="
     cwg_defects.html#846">846</A>.)</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>See paper N3030.</P>

<BR><BR><HR><A NAME="896"></A><H4>896.
  
Rvalue references and rvalue-reference conversion functions
</H4><B>Section: </B>8.5.3&#160; [dcl.init.ref]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>9 May, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>Consider the following example:</P>

<PRE>
    struct A { } a;
    struct B {
      operator A&amp;&amp;() {
        return static_cast&lt;A&amp;&amp;&gt;(a);
      }
    };
    A&amp;&amp; r = B();
</PRE>

<P>One would expect that <TT>r</TT> would be bound to the object
returned by <TT>B::operator A&amp;&amp;()</TT>, i.e., <TT>a</TT>.
However, the logic in 8.5.3 [dcl.init.ref] paragraph 5
requires that the result of the conversion function be copied to a
temporary and <TT>r</TT> bound to the temporary.</P>

<P>Probably the way to address this is to add another top-level bullet
between the first and second that would essentially mimic the first
bullet except dealing with rvalue references: direct binding to
reference-compatible rvalues or to the reference-compatible result of
a conversion function.  (Note that this should only apply to class
rvalues; the creation of a temporary for non-class rvalues is
necessary to have an object for the reference to bind to.)</P>

<P>(See also <A HREF="
     cwg_defects.html#656">issue 656</A>.)</P>

<P><B>Proposed resolution (September, 2009):</B></P>

<P>This issue is resolved by the resolution of <A HREF="
     cwg_defects.html#656">issue 656</A>.</P>

<BR><BR><HR><A NAME="703"></A><H4>703.
  
Narrowing for literals that cannot be exactly represented
</H4><B>Section: </B>8.5.4&#160; [dcl.init.list]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2 July, 2008<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>Both of the following initializations are ill-formed because of
narrowing, although they were previously well-formed:</P>

<PRE>
    struct A { int i; } a = { 1.0 };
    struct B { float f; } b = { 1.1 };
</PRE>

<P>The first one doesn't seem like a big problem, as there probably
isn't much code that has this kind of aggregate initialization.  The
second might be of more concern, because <TT>1.1</TT> is not
representable in either <TT>float</TT> or <TT>double</TT>.  Is the
resulting loss of precision a kind of narrowing that we want to
diagnose?</P>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>The CWG agreed that the second initialization should not be a
narrowing error; furthermore, this exemption should apply not
only to literals but to any floating-point constant expression.
Instead of the current formulation, requiring exact bidirectional
convertibility, the Standard should only require that the
initializer value be within the representable range of the target
type.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 8.5.4 [dcl.init.list] paragraph 6 as follows:</P>

<BLOCKQUOTE>

<P>A <I>narrowing conversion</I> is an implicit conversion</P>

<UL><LI><P>from a floating-point type to an integer type, or</P></LI>

<LI><P>from <TT>long double</TT> to <TT>double</TT> or <TT>float</TT>,
or from <TT>double</TT> to <TT>float</TT>, except where the source is
a constant expression and the actual value after conversion <SPAN style="text-decoration:line-through;background-color:#FFA0A0">will
fit into the target type and will produce the original value when
converted back to the original type</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">is within the range of
values that can be represented (even if it cannot be represented
exactly)</SPAN>, or</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="865"></A><H4>865.
  
Initializing a <TT>std::initializer_list</TT>
</H4><B>Section: </B>8.5.4&#160; [dcl.init.list]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>James Widman
 &#160;&#160;&#160;

 <B>Date: </B>8 April, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>There are several problems with the wording of 8.5.4 [dcl.init.list]
paragraph 4:</P>

<BLOCKQUOTE>

When an initializer list is implicitly converted to a
<TT>std::initializer_list&lt;E&gt;</TT>, the object passed is
constructed as if the implementation allocated an array of <I>N</I>
elements of type <TT>E</TT>, where <I>N</I> is the number of elements
in the initializer list. Each element of that array is initialized
with the corresponding element of the initializer list converted to
<TT>E</TT>, and the <TT>std::initializer_list&lt;E&gt;</TT> object is
constructed to refer to that array.  If a narrowing conversion is
required to convert the element to <TT>E</TT>, the program is
ill-formed.

</BLOCKQUOTE>

<P>First, an initializer list is not an expression, so it is not
appropriate to refer to &#8220;implicitly convert[ing]&#8221; it,
as is done in the first sentence.</P>

<P>Also, the conversion of the elements of the initializer list to the
elements of the array is not specified to be either
copy-initialization or direct-initialization.  If this is intended to
be viewed as an aggregate initialization, it would be
copy-initialization, but that needs to be specified more clearly.</P>

<P>Finally, the initializer list can have nested initializer lists, so
the references to converting the element also need to be cleaned
up.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 8.5.4 [dcl.init.list] paragraph 4 as follows:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">When an initializer list is implicitly converted to a</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">An object of type</SPAN> <TT>std::initializer_list&lt;E&gt;</TT>
<SPAN style="font-weight:bold;background-color:#A0FFA0">is constructed from an initializer list</SPAN><SPAN style="text-decoration:line-through;background-color:#FFA0A0">, the object
passed is constructed</SPAN> as if the implementation allocated an
array of <I>N</I> elements of type <TT>E</TT>, where <I>N</I> is the
number of elements in the initializer list. Each element of that array
is <SPAN style="font-weight:bold;background-color:#A0FFA0">copy-</SPAN>initialized with the corresponding element of the
initializer list<SPAN style="text-decoration:line-through;background-color:#FFA0A0"> converted to <TT>E</TT></SPAN>, and the
<TT>std::initializer_list&lt;E&gt;</TT> object is constructed to refer
to that array.  If a narrowing conversion is required to <SPAN style="text-decoration:line-through;background-color:#FFA0A0">convert
the element to <TT>E</TT></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">initialize any of the
elements</SPAN>, the program is ill-formed. [<I>Example:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="934"></A><H4>934.
  
List-initialization of references
</H4><B>Section: </B>8.5.4&#160; [dcl.init.list]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>8 July, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>According to 8.5.4 [dcl.init.list] paragraph 3,</P>

<BLOCKQUOTE>

Otherwise, if <TT>T</TT> is a reference type, an rvalue temporary of
the type referenced by <TT>T</TT> is list-initialized, and the
reference is bound to that temporary.

</BLOCKQUOTE>

<P>This means, for an example like</P>

<PRE>
    int i;
    const int&amp; r1{ i };
    int&amp;&amp; r2{ i };
</PRE>

<P><TT>r1</TT> is bound to a temporary containing the value of
<TT>i</TT>, not to <TT>i</TT> itself, which seems surprising. Also,
there's no prohibition here against binding the rvalue reference to an
lvalue, as there is in 8.5.3 [dcl.init.ref] paragraph 5 bullet
2, so the initialization of <TT>r2</TT> is well-formed, even though
the corresponding non-list initialization <TT>int&amp;&amp; r3(i)</TT>
is ill-formed.</P>

<P>There's also a question as to whether this bullet even applies to
these examples.  According to the decision tree in 8.5 [dcl.init] paragraph 16, initialization of a reference is dispatched
to 8.5.3 [dcl.init.ref] in the first bullet, so these cases
never make it to the third bullet sending the remaining
braced-init-list cases to 8.5.4 [dcl.init.list].  If that's the
correct interpretation, there's a problem with 8.5.3 [dcl.init.ref], since it doesn't deal with the <I>braced-init-list</I>
cases, and the bullet in 8.5.4 [dcl.init.list] paragraph 3
dealing with references is dead code that's never used.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<OL><LI><P>Move the third bullet of the list in 8.5 [dcl.init]
paragraph 16 to the top of the list:</P></LI>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">If the initializer is a <I>braced-init-list</I>, the
object is list-initialized (8.5.4 [dcl.init.list]).</SPAN></P></LI>

<LI><P>If the destination type is a reference type, see 8.5.3 [dcl.init.ref].</P></LI>

<LI><P>...</P></LI>

</UL>

<LI><P>Change 8.5.4 [dcl.init.list] paragraph 3, bullets 4 and 5,
as follows:</P></LI>

<UL><LI><P>Otherwise, if <TT>T</TT> is a reference <SPAN style="font-weight:bold;background-color:#A0FFA0">to class</SPAN>
type, <SPAN style="font-weight:bold;background-color:#A0FFA0">or if <TT>T</TT> is any reference type and the initializer
list has no elements,</SPAN> an rvalue temporary of the type referenced
by <TT>T</TT> is list-initialized, and the reference is bound to that
temporary. [<I>Note:</I>...</P></LI>

<LI><P>Otherwise<SPAN style="text-decoration:line-through;background-color:#FFA0A0"> (i.e., if <TT>T</TT> is not an aggregate, class
type, or reference)</SPAN>, if the initializer list has a single
element...</P></LI>

</UL>

</OL>

<BR><BR><HR><A NAME="989"></A><H4>989.
  
Misplaced list-initialization example
</H4><B>Section: </B>8.5.4&#160; [dcl.init.list]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>20 October, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>The final set of declarations in the example following 8.5.4 [dcl.init.list] paragraph 3 bullet 3 is:</P>

<PRE>
    struct S2 {
      int m1;
      double m2,m3;
    };
    S2 s21 = { 1, 2, 3.0 };    // OK
    S2 s22 { 1.0, 2, 3 };      // error: narrowing
    S2 s23 {};                 // OK: default to 0,0,0
</PRE>

<P>However, <TT>S2</TT> is an aggregate.  Aggregates are handled
in bullet 1, while bullet 3 deals with classes with constructors.
This part of the example should be moved to the first bullet.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Move the <TT>S2</TT> example from bullet 3 to bullet 1 in
8.5.4 [dcl.init.list] paragraph 3:</P>

<UL><LI><P>If <TT>T</TT> is an aggregate, aggregate initialization is
performed (8.5.1 [dcl.init.aggr]).</P>

<P>[<I>Example:</I></P>

<PRE>
  double ad[] = { 1, 2.0 };   //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
  int ai[] = { 1, 2.0 };      //<SPAN style="font-family:Times;font-style:italic"> error: narrowing</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">
  struct S2 {
    int m1;
    double m2,m3;
  };
  S2 s21 = { 1, 2, 3.0 };     //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
  S2 s22 { 1.0, 2, 3 };       //<SPAN style="font-family:Times;font-style:italic"> error: narrowing</SPAN>
  S2 s23 {};                  //<SPAN style="font-family:Times;font-style:italic"> OK: default to 0,0,0</SPAN></SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

</LI>

<LI><P>Otherwise, if <TT>T</TT> is a specialization...</P></LI>

<LI><P>Otherwise, if T is a class type...</P>

<P>[<I>Example:</I></P>

<PRE>
  ...
  S s3 { };                   //<SPAN style="font-family:Times;font-style:italic"> OK: invoke #2</SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">
  struct S2 {
    int m1;
    double m2,m3;
  };
  S2 s21 = { 1, 2, 3.0 };     //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
  S2 s22 { 1.0, 2, 3 };       //<SPAN style="font-family:Times;font-style:italic"> error: narrowing</SPAN>
  S2 s23 {};                  //<SPAN style="font-family:Times;font-style:italic"> OK: default to 0,0,0</SPAN></SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

</LI>

<LI><P>...</P></LI>

</UL>

<BR><BR><HR><A NAME="990"></A><H4>990.
  
Value initialization with multiple initializer-list constructors
</H4><B>Section: </B>8.5.4&#160; [dcl.init.list]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>20 October, 2009<BR>


<P>[Voted into WP at March, 2010 meeting as part of document N3079.]</P>

<P>It should always be possible to use the new brace syntax to
value-initialize an object.  However, the current rules make the
following example ill-formed because of ambiguity:</P>

<PRE>
    struct S {
      S();
      S(std::initializer_list&lt;int&gt;);
      S(std::initializer_list&lt;double&gt;);
    };
    S s{};    //<SPAN style="font-family:Times;font-style:italic"> Ambiguous initializer-list constructor reference,</SPAN>
              //<SPAN style="font-family:Times;font-style:italic"> not value initialization.</SPAN>
</PRE>



<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 8.5.4 [dcl.init.list] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<P>List-initialization of an object or reference of type <TT>T</TT> is
defined as follows:</P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">If the initializer list has no elements and <TT>T</TT> is
a class type with a default constructor, the object is
value-initialized.</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">Otherwise, if the initializer list has no elements
and <TT>T</TT> is an aggregate, the initializer list is used to
initialize each of the members of
<TT>T</TT>. [<I>Example:</I></SPAN></P></LI>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  struct A {
    A(std::initializer_list&lt;int&gt;);  //<SPAN style="font-family:Times;font-style:italic"> #1</SPAN>
  };
  struct B {
    A a;
  };
  B b { };    //<SPAN style="font-family:Times;font-style:italic"> OK, uses #1</SPAN>
  B b { 1 };  //<SPAN style="font-family:Times;font-style:italic"> error</SPAN></SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">If</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Otherwise, if</SPAN> <TT>T</TT> is an
aggregate...</P></LI>

<LI><P>...</P></LI>

<P>[<I>Example:</I></P>

<PRE>
  struct S {
    S(std::initializer_list&lt;double&gt;);  //<SPAN style="font-family:Times;font-style:italic"> #1</SPAN>
    S(std::initializer_list&lt;int&gt;);     //<SPAN style="font-family:Times;font-style:italic"> #2</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">    S();                                     //<SPAN style="font-family:Times;font-style:italic"> #3</SPAN></SPAN>
    // ...
  };
  S s1 = { 1.0, 2.0, 3.0 };            //<SPAN style="font-family:Times;font-style:italic"> invoke #1</SPAN>
  S s2 = { 1, 2, 3 };                  //<SPAN style="font-family:Times;font-style:italic"> invoke #2</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  S s3 = { };                          //<SPAN style="font-family:Times;font-style:italic"> invoke #3 (for value-initialization; see above)</SPAN></SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="905"></A><H4>905.
  
Explicit defaulted copy constructors and trivial copyability
</H4><B>Section: </B>9&#160; [class]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>27 May, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>It is presumably possible to declare a defaulted copy constructor
to be <TT>explicit</TT>.  Should that render a class not trivially
copyable, even though the copy constructor is trivial?  That is,
does being &#8220;trivally copyable&#8221; mean that copy
initialization, and not just direct initialization, is possible?</P>

<P>A related question is whether the specification of triviality
should require that the copy constructor and copy assignment operator
must be public.  (With the advent of &#8220;<TT>=default</TT>&#8221; it
is possible to make them non-public, which was not the case when these
definitions were crafted.)</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>This issues is resolved by the resolution of
<A HREF="
     cwg_defects.html#906">issue 906</A>.</P>

<BR><BR><HR><A NAME="645"></A><H4>645.
  
Are bit-field and non-bit-field members layout compatible?
</H4><B>Section: </B>9.2&#160; [class.mem]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Alan Stokes
 &#160;&#160;&#160;

 <B>Date: </B>9 Aug 2007<BR>


<P>[Voted into the WP at the March, 2009 meeting.]</P>



<P>The current wording defining a &#8220;common initial sequence&#8221;
in 9.2 [class.mem] paragraph 17 does not address the case
in which one member is a bit-field and the corresponding member is
not:</P>

<BLOCKQUOTE>

Two standard-layout 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.

</BLOCKQUOTE>

<P>Presumably the intent was something like, &#8220;(and, if one
of the pair is a bit-field, the other is also a bit-field of the
same width).&#8221;</P>

<P><B>Proposed Resolution (September, 2008):</B></P>

<P>Change 9.2 [class.mem] paragraph 18 as follows:</P>
<BLOCKQUOTE>

... Two standard-layout structs share a common initial sequence
if corresponding members have layout-compatible types <SPAN style="text-decoration:line-through;background-color:#FFA0A0">(and,
for bit-fields, the same widths)</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">and either neither member
is a bit-field or both are bit-fields with the same widths</SPAN>
for a sequence of one or more initial members.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="874"></A><H4>874.
  
Class-scope definitions of enumeration types
</H4><B>Section: </B>9.2&#160; [class.mem]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>16 April, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>According to 9.2 [class.mem] paragraph 1,</P>

<BLOCKQUOTE>

The enumerators of an enumeration (7.2 [dcl.enum]) defined
in the class are members of the class... A member shall not be
declared twice in the <I>member-specification</I>, except
that a nested class or member class template can be declared and then
later defined.

</BLOCKQUOTE>

<P>The enumerators of a scoped enumeration are not members of the
containing class; the wording should be revised to apply only to
unscoped enumerations. </P>

<P>The second part of the cited wording from 9.2 [class.mem]
prohibits constructs like:</P>

<PRE>
    class C {
      public:
        enum E: int;
      private:
        enum E: int { e0 };
    };
</PRE>

<P>which might be useful in making the enumeration type, but not its
enumerators, accessible.</P>

<P><B>Notes from the July, 2009 meeting:</B></P>

<P>According to 11.1 [class.access.spec] paragraph 4, the access must
be the same for all declarations of a class member.  The suggested
usage given above violates that requirement: the second declaration of
<TT>E</TT> declares the enumeration itself, not just the enumerators,
to be private.  The CWG did not feel that the utility of the suggested
feature warranted the complexity of an exception to the general rule.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<OL><LI><P>Change 9.2 [class.mem] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...The enumerators of an <SPAN style="font-weight:bold;background-color:#A0FFA0">unscoped</SPAN> enumeration (7.2 [dcl.enum])
defined in the class are members of the class... A member shall not be
declared twice in the <I>member-specification</I>, except that a
nested class or member class template can be declared and then later
defined<SPAN style="font-weight:bold;background-color:#A0FFA0">, and except that an enumeration can be first introduced with
an <I>opaque-enum-declaration</I> and then later be redeclared with an
<I>enum-specifier</I></SPAN>.

</BLOCKQUOTE>

<LI><P>Change the example in 11.1 [class.access.spec] paragraph 4
as follows:</P></LI>

<P>When a member is redeclared within its class definition, the access
specified at its redeclaration shall be the same as at its initial
declaration. [<I>Example:</I></P>

<PRE>
  struct S {
    class A;
<SPAN style="font-weight:bold;background-color:#A0FFA0">    enum E : int;</SPAN>
  private:
    class A { };          //<SPAN style="font-family:Times;font-style:italic"> error: cannot change access</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">    enum E : int { e0 };  //<SPAN style="font-family:Times;font-style:italic"> error: cannot change access</SPAN></SPAN>
  };
</PRE>

<P>&#8212;<I>end example</I>]</P>

</OL>

<BR><BR><HR><A NAME="714"></A><H4>714.
  
Static const data members and <I>braced-init-list</I>s
</H4><B>Section: </B>9.4.2&#160; [class.static.data]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>15 September, 2008<BR>


<P>[Voted into WP at July, 2009 meeting.]</P>

<P>The recent changes in the handling of initialization have not
touched the requirement that the in-class initializer for a const
static data member must be of the form
<TT>=</TT>&#160;<I>assignment-expression</I> and not a
<I>braced-init-list</I>.  It would be more consistent and
general to allow the braced form as well.</P>

<P><B>Proposed resolution (March, 2009):</B></P>

<OL><LI><P>Change 5.19 [expr.const] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

...as enumerator initializers (7.2 [dcl.enum]), <SPAN style="text-decoration:line-through;background-color:#FFA0A0">as static
member initializers (9.4.2 [class.static.data]),</SPAN> and as integral or
enumeration non-type template arguments (14.4 [temp.type]).

</BLOCKQUOTE>

<LI><P>Change 9.4.2 [class.static.data] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

If a <TT>static</TT> data member is of <TT>const</TT> effective
literal type, its declaration in the class definition can specify a
<I>brace-or-equal-initializer</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">with an</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">in which every</SPAN>
<I>initializer-clause</I> that is an <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>assignment-expression</I>
is a</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">integral</SPAN> constant expression.  A <TT>static</TT> data member
of effective literal type can be declared in the class definition with
the <TT>constexpr</TT> specifier; if so, its declaration shall specify
a <I>brace-or-equal-initializer</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">with an</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">in which every</SPAN>
<I>initializer-clause</I> that is an <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>assignment-expression</I>
is a</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">integral</SPAN> constant expression.  <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I></SPAN> In
both these cases, the member may appear in <SPAN style="text-decoration:line-through;background-color:#FFA0A0">integral</SPAN> constant
expressions. <SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end note</I>]</SPAN> The member shall still be
defined in a namespace scope if it is used in the program and the
namespace scope definition shall not contain an initializer.

</BLOCKQUOTE>

</OL>

<P><I>[Drafting note: this change also corrects an editorial error
resulting from overlapping changes that inadvertently retained the
original restriction that only members of integral type could be
initialized inside the class definition.]</I></P>

<BR><BR><HR><A NAME="716"></A><H4>716.
  
Specifications that should apply only to non-static union data members
</H4><B>Section: </B>9.5&#160; [class.union]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>17 September, 2008<BR>


<P>[Voted into WP at July, 2009 meeting.]</P>

<P>Unions are no longer forbidden to have static data members; however,
much of the wording of 9.5 [class.union] (and possibly other
places in the Standard) is still written with that assumption and
refers only to &#8220;data members&#8221; when clearly non-static
data members are in view.  From paragraph 1, for example:</P>

<BLOCKQUOTE>

In a union, at most one of the <B>data members</B> can be active
at any time... The size of a union is sufficient
to contain the largest of its <B>data members</B>...

</BLOCKQUOTE>

<P><B>Proposed resolution (March, 2009):</B></P>

<OL>
<LI><P>Change the footnote in 3.9.3 [basic.type.qualifier] paragraph 1
as follows:</P></LI>

<BLOCKQUOTE>

The same representation and alignment requirements are meant to imply
interchangeability as arguments to functions, return values from
functions, and <SPAN style="font-weight:bold;background-color:#A0FFA0">non-static data</SPAN> members of unions.

</BLOCKQUOTE>

<LI><P>Change 3.10 [basic.lval] paragraph 15 bullet 6 as
follows:</P></LI>

<UL><LI>an aggregate or union type that includes one of the
aforementioned types among its <SPAN style="font-weight:bold;background-color:#A0FFA0">elements or non-static data</SPAN>
members (including, recursively, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an element or non-static
data</SPAN> member of a subaggregate or contained union),</LI></UL>

<LI><P>Change 5.9 [expr.rel] paragraph 2 bullet 5 as
follows:</P></LI>

<UL><LI>If two pointers point to <SPAN style="font-weight:bold;background-color:#A0FFA0">non-static</SPAN> data members of the
same union object, they compare equal (after conversion to
<TT>void*</TT>, if necessary)...</LI></UL>

<LI><P>Change 7.6.2 [dcl.align] paragraph 8 as follows:</P></LI>

<BLOCKQUOTE>

[<I>Note:</I> the alignment of a union type can be strengthened by
applying the alignment attribute to any <SPAN style="font-weight:bold;background-color:#A0FFA0">non-static data</SPAN> member
of the union.  &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Change 8.5.1 [dcl.init.aggr] paragraph 15 as follows:</P></LI>

<BLOCKQUOTE>

When a union is initialized with a brace-enclosed initializer, the
braces shall only contain an <I>initializer-clause</I> for the
first <SPAN style="font-weight:bold;background-color:#A0FFA0">non-static data</SPAN> member of the union...

</BLOCKQUOTE>

<LI><P>Change 9.5 [class.union] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

In a union, at most one of the <SPAN style="font-weight:bold;background-color:#A0FFA0">non-static</SPAN> data members can be
active at any time, that is, the value of at most one of the
<SPAN style="font-weight:bold;background-color:#A0FFA0">non-static</SPAN> data members can be stored in a union at any time.
[<I>Note:</I> one special guarantee is made in order to simplify the
use of unions: If a standard-layout union contains several
standard-layout structs that share a common initial sequence
(9.2 [class.mem]), and if an object of this standard-layout
union type contains one of the standard-layout structs, it is
permitted to inspect the common initial sequence of any of
standard-layout struct members; see 9.2 [class.mem]. &#8212;<I>end note</I>] The size of a union is sufficient
to contain the largest of its <SPAN style="font-weight:bold;background-color:#A0FFA0">non-static</SPAN> data members.  Each
<SPAN style="font-weight:bold;background-color:#A0FFA0">non-static</SPAN> data member is allocated as if it were the sole
member of a struct.  A union can have...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="608"></A><H4>608.
  
Determining the final overrider of a virtual function
</H4><B>Section: </B>10.3&#160; [class.virtual]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>7 December 2006<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>According to 10.3 [class.virtual] paragraph 2:</P>

<BLOCKQUOTE>

Then in any well-formed class, for each virtual function declared
in that class or any of its direct or indirect base classes there
is a unique <I>final overrider</I> that overrides that function
and every other overrider of that function. The rules for member
lookup (10.2 [class.member.lookup]) are used to determine the
final overrider for a virtual function in the scope of a derived
class but ignoring names introduced by <I>using-declaration</I>s.

</BLOCKQUOTE>

<P>I think that description is wrong on at least a couple of
counts.  First, consider the following example:</P>

<PRE>
    struct A { virtual void f(); };
    struct B: A { };
    struct C: A { void f(); };
    struct D: B, C { };
</PRE>

<P>What is the &#8220;unique final overrider&#8221; of
<TT>A::f()</TT> in <TT>D</TT>?  According to
10.3 [class.virtual] paragraph 2, we determine that by
looking up <TT>f</TT> in <TT>D</TT> using the lookup rules in
10.2 [class.member.lookup].  However, that lookup determines that
<TT>f</TT> in <TT>D</TT> is ambiguous, so there is no
&#8220;unique final overrider&#8221; of <TT>A::f()</TT> in
<TT>D</TT>.  Consequently, because &#8220;any well-formed
class&#8221; must have such an overrider, <TT>D</TT> must be
ill-formed.</P>

<P>Of course, we all know that <TT>D</TT> is <I>not</I>
ill-formed.  In fact, 10.3 [class.virtual] paragraph 10
contains an example that illustrates exactly this point:</P>

<BLOCKQUOTE>

<PRE>
struct A {
    virtual void f();
};
struct B1 : A {     //<SPAN style="font-family:Times;font-style:italic"> note non-virtual derivation</SPAN>
    void f();
};
struct B2 : A {
    void f();
};
struct D : B1, B2 { //<SPAN style="font-family:Times;font-style:italic"> </SPAN>D<SPAN style="font-family:Times;font-style:italic"> has two separate </SPAN>A<SPAN style="font-family:Times;font-style:italic"> subobjects</SPAN>
};
</PRE>

<P>In class <TT>D</TT> above there are two occurrences of
class <TT>A</TT> and hence two occurrences of the virtual member
function <TT>A::f</TT>.  The final overrider of <TT>B1::A::f</TT>
is <TT>B1::f</TT> and the final overrider of <TT>B2::A::f</TT>
is <TT>B2::f</TT>.</P>

</BLOCKQUOTE>

<P>It appears that the requirement for a &#8220;unique final
overrider&#8221; in 10.3 [class.virtual] paragraph 2 needs
to say something about sub-objects.  Whatever that
&#8220;something&#8221; is, you can't just say &#8220;look up the
name in the derived class using 10.2 [class.member.lookup].&#8221;</P>

<P>There's another problem with using the 10.2 [class.member.lookup]
lookup to specify the final overrider: name lookup just looks up the
name, while the overriding relationship is based not only on the name
but on a matching parameter-type-list and cv-qualification.  To
illustrate this point:</P>

<PRE>
    struct X {
        virtual void f();
    };
    struct Y: X {
        void f(int);
    };
    struct Z: Y { };
</PRE>

<P>What is the &#8220;unique final overrider&#8221; of
<TT>X::f()</TT> in <TT>A</TT>?  Again, 10.3 [class.virtual]
paragraph 2 says you're supposed to look up <TT>f</TT> in
<TT>Z</TT> to find it; however, what you find is
<TT>Y::f(int)</TT>, not <TT>X::f()</TT>, and that's clearly
wrong.</P>

<P><B>Proposed Resolution (December, 2006):</B></P>

<P>Change 10.3 [class.virtual] paragraph 2 as follows:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Then in any well-formed class, for each virtual function declared in
that class or any of its direct or indirect base classes there is a
unique <I>final overrider</I> that overrides that function and every
other overrider of that function. The rules for member lookup
(10.2 [class.member.lookup]) are used to determine the final overrider
for a virtual function in the scope of a derived class but ignoring
names introduced by <I>using-declaration</I> s.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">A virtual
member function <TT>vf</TT> of a class <TT>C</TT> is a <I>final
overrider</I> unless the most derived class (1.8 [intro.object])
of which <TT>C</TT> is a base class (if any) declares or inherits
another member function that overrides <TT>vf</TT>.  In a derived class,
if a virtual member function of a base class subobject has more than
one final overrider, the program is ill-formed.</SPAN>

</BLOCKQUOTE>

<P><B>Proposed resolution (July, 2009):</B></P>

<P> Change 10.3 [class.virtual] paragraph 2 as follows: </P>

<BLOCKQUOTE>

<P>...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Then in any well-formed class, for each virtual function
declared in that class or any of its direct or indirect base classes
there is a unique <I>final overrider</I> that overrides that function
and every other overrider of that function. The rules for member
lookup (10.2 [class.member.lookup]) are used to determine the final
overrider for a virtual function in the scope of a derived class but
ignoring names introduced by <I>using-declaration</I>s.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">A
virtual member function <TT>C::vf</TT> of a class object <TT>S</TT> is
a <I>final overrider</I> unless the most derived class (1.8 [intro.object]) of which <TT>S</TT> is a base class subobject (if any)
declares or inherits another member function that overrides
<TT>vf</TT>. In a derived class, if a virtual member function of a
base class subobject has more than one final overrider, the program is
ill-formed.</SPAN> [<I>Example:</I> ... &#8212;<I>end example</I>]
<SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">    struct A { virtual void f(); };
    struct B: A { };
    struct C: A { void f(); };
    struct D: B, C { };    //<SPAN style="font-family:Times;font-style:italic"> OK; </SPAN>A::f<SPAN style="font-family:Times;font-style:italic"> and </SPAN>C::f<SPAN style="font-family:Times;font-style:italic"> are the final overriders</SPAN>
                           //<SPAN style="font-family:Times;font-style:italic"> for the </SPAN>B<SPAN style="font-family:Times;font-style:italic"> and </SPAN>C<SPAN style="font-family:Times;font-style:italic"> subobjects, respectively</SPAN>
</SPAN></PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="939"></A><H4>939.
  
Explicitly checking virtual function overriding
</H4><B>Section: </B>10.3&#160; [class.virtual]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>FI/US
 &#160;&#160;&#160;

 <B>Date: </B>14 July, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#FI1">N2800 comment
  FI&#160;1<BR></A>
<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#US41">N2800 comment
  US&#160;41<BR></A>

<P>[Voted into WP at July, 2009 meeting as N2928.]</P>

<P>There should be a way to detect errors in overriding a virtual
function.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>This issue is resolved by paper PL22.16/09-0118 = WG21 N2928.</P>

<BR><BR><HR><A NAME="960"></A><H4>960.
  
Covariant functions and lvalue/rvalue references
</H4><B>Section: </B>10.3&#160; [class.virtual]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>James Widman
 &#160;&#160;&#160;

 <B>Date: </B>1 September, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>10.3 [class.virtual] paragraph 5 requires that covariant
return types be either both pointers or both references, but it does
not specify that references must be both lvalue references or both
rvalue references.  Presumably this is an oversight.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 10.3 [class.virtual] paragraph 5 bullet 1 as follows:</P>

<BLOCKQUOTE>

<P>...If a function <TT>D::f</TT> overrides a function
<TT>B::f</TT>, the return types of the functions are covariant if
they satisfy the following criteria:</P>

<UL><LI><P>both are pointers to classes<SPAN style="font-weight:bold;background-color:#A0FFA0">, both are lvalue references
to classes,</SPAN> or <SPAN style="font-weight:bold;background-color:#A0FFA0">both are rvalue</SPAN> references to
classes<SUP>106</SUP></P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="922"></A><H4>922.
  
Implicit default constructor definitions and <TT>const</TT> variant members
</H4><B>Section: </B>12.1&#160; [class.ctor]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>19 June, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>According to 12.1 [class.ctor] paragraph 5,</P>

<BLOCKQUOTE>

An implicitly-declared default constructor for class <TT>X</TT> is
defined as deleted if: ... any non-static data member of
const-qualified type (or array thereof) does not have a user-provided
default constructor, or...

</BLOCKQUOTE>

<P>It is not clear if this adequately covers the case in which some
variant members are const-qualified but others are not.  The intent
of the restriction is to prevent creation of an object with
uninitialized members that would require a <TT>const_cast</TT> to
set their value later, but const-qualified members of an anonymous
union in which other members are not const do not seem to present
that problem.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 12.1 [class.ctor] paragraph 5 bullet 3
of the second list and add a fourth bullet as follows:</P>

<UL><LI><P>...</P></LI>

<LI><P>any <SPAN style="font-weight:bold;background-color:#A0FFA0">non-variant</SPAN> non-static data member of
const-qualified type (or array thereof) does not have a user-provided
default constructor, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">all variant members are of const-qualified type (or array
thereof), or</SPAN></P></LI>

<LI><P>...</P></LI>

</UL>

<P><B>Proposed resolution (November, 2009):</B></P>

<P>Change 12.1 [class.ctor] paragraph 5 bullet 3
of the second list and add two bullets as follows:</P>

<UL><LI><P>...</P></LI>

<LI><P>any <SPAN style="font-weight:bold;background-color:#A0FFA0">non-variant</SPAN> non-static data member of
const-qualified type (or array thereof) does not have a user-provided
default constructor, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>X</TT> is a union and all its variant members are of
const-qualified type (or array thereof),</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>X</TT> is a non-union class and all members of any
anonymous union member are of const-qualified type (or array
thereof), or</SPAN></P></LI>

<LI><P>...</P></LI>

</UL>

<BR><BR><HR><A NAME="927"></A><H4>927.
  
Implicitly-deleted default constructors and member initializers
</H4><B>Section: </B>12.1&#160; [class.ctor]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>1 July, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<commmittee_only><P>(From message <A href="
   http://accu.org/cgi-bin/wg21/message?wg=core&amp;msg=14555">14555</A>.)</P></commmittee_only>

<P>The reasons for which an implicitly-declared default constructor is
defined as deleted, given in 12.1 [class.ctor] paragraph 4,
all deal with cases in which a member cannot be
default-initialized. Presumably a <I>brace-or-equal-initializer</I>
for such a member would eliminate the need to define the constructor
as deleted, but this case is not addressed by the current wording.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 12.1 [class.ctor] paragraph 5, the second list, as
follows:</P>

<BLOCKQUOTE>

<P>An implicitly-declared default constructor for class <TT>X</TT> is
defined as deleted if:</P>

<UL><LI><P><TT>X</TT> is a union-like class that has a variant member
with a non-trivial default constructor,</P></LI>

<LI><P>any non-static data member <SPAN style="font-weight:bold;background-color:#A0FFA0">with no
<I>brace-or-equal-initializer</I></SPAN> is of reference type,</P></LI>

<LI><P>any non-static data member of const-qualified type (or array
thereof) <SPAN style="font-weight:bold;background-color:#A0FFA0">with no <I>brace-or-equal-initializer</I></SPAN> does not
have a user-provided default constructor, or</P></LI>

<LI><P>any <SPAN style="font-weight:bold;background-color:#A0FFA0">direct or virtual base class, or</SPAN> non-static data
member <SPAN style="font-weight:bold;background-color:#A0FFA0">with no <I>brace-or-qual-initializer,</I></SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or
direct or virtual base class</SPAN> has class type <TT>M</TT> (or array
thereof) and <SPAN style="font-weight:bold;background-color:#A0FFA0">either</SPAN> <TT>M</TT> has no default
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">constructor, or if</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">constructor or</SPAN> overload
resolution (13.3 [over.match]) as applied to <TT>M</TT>'s
default constructor<SPAN style="text-decoration:line-through;background-color:#FFA0A0">,</SPAN> results in an ambiguity or
<SPAN style="font-weight:bold;background-color:#A0FFA0">in</SPAN> a function that is deleted or inaccessible from the
implicitly-declared default constructor.</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="650"></A><H4>650.
  
Order of destruction for temporaries bound to the returned value of a function
</H4><B>Section: </B>12.2&#160; [class.temporary]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>14 Aug 2007<BR>


<P>[Voted into the WP at the March, 2009 meeting.]</P>

<P>In describing the order of destruction of temporaries,
12.2 [class.temporary] paragraphs 4-5 say,</P>

<BLOCKQUOTE>

<P>There are two contexts in which temporaries are destroyed at a
different point than the end of the full-expression...</P>

<P>The second context is when a reference is bound to a
temporary...  A temporary bound to the returned value in a function
return statement (6.6.3 [stmt.return]) persists until the
function exits.</P>

</BLOCKQUOTE>

<P>The following example illustrates the issues here:</P>

<PRE>
    struct S {
        ~S();
    };

    S&amp; f() {
        S s;            // #1
        return
            (S(),       // #2
             S());      // #3
    }
</PRE>

<P>If the return type of <TT>f()</TT> were simply <TT>S</TT> instead
of <TT>S&amp;</TT>, the two temporaries would be destroyed at the end
of the full-expression in the <TT>return</TT> statement in reverse
order of their construction, followed by the destruction of the
variable <TT>s</TT> at block-exit, i.e., the order of destruction
of the <TT>S</TT> objects would be #3, #2, #1.</P>

<P>Because the temporary #3 is bound to the returned value, however,
its lifetime is extended beyond the end of the full-expression, so
that <TT>S</TT> object #2 is destroyed before #3.</P>

<P>There are two problems here.  First, it is not clear what
&#8220;until the function exits&#8221; means.  Does it mean that
the temporary is destroyed as part of the normal block-exit
destructions, as described in 6.6 [stmt.jump] paragraph 2:</P>

<BLOCKQUOTE>

On exit from a scope (however accomplished), destructors (12.4 [class.dtor]) are called for all constructed objects with automatic
storage duration (3.7.3 [basic.stc.auto]) (named objects or
temporaries) that are declared in that scope, in the reverse order of
their declaration.

</BLOCKQUOTE>

<P>Or is the point of destruction for #3
<I>after</I> the destruction of the &#8220;constructed objects...
that are <I>declared</I> [emphasis mine] in that scope&#8221;
(because temporary #3 was not &#8220;declared&#8221;)?  I.e.,
should #3 be destroyed before or after #1?</P>

<P>The other problem is that, according to the recollection of one
of the participants responsible for this wording, the intent was not
to extend the lifetime of #3 but simply to emphasize that its
lifetime ended before the function returned, i.e., that the result of
<TT>f()</TT> could not be used without causing undefined behavior.
This is also consistent with the treatment of this example by many
implementations; MSVC++, g++, and EDG all destroy #3 before #2.</P>

<P><U>Suggested resolution:</U></P>

<P>Change 12.2 [class.temporary] paragraph 5 as indicated:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">The lifetime of a</SPAN> temporary bound to the returned
value in a function return statement (6.6.3 [stmt.return])
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">persists until the function exits</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">is not extended; it is
destroyed at the end of the full-expression in the return statement</SPAN>.

</BLOCKQUOTE>

<P><B>Proposed resolution (June, 2008):</B></P>

<P>Change 12.2 [class.temporary] paragraph 5 as follows (converting
the running text into a bulleted list and making the indicated edits
to the wording):</P>

<BLOCKQUOTE>

... The temporary to which the reference is bound or the temporary
that is the complete object of a subobject to which the reference is
bound persists for the lifetime of the reference except<SPAN style="font-weight:bold;background-color:#A0FFA0">:</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">as
specified below.</SPAN>

<UL><LI><P>A temporary bound to a reference member in a constructor's
ctor-initializer (12.6.2 [class.base.init]) persists until the
constructor exits.</P></LI>

<LI><P>A temporary bound to a reference parameter in a function call
(5.2.2 [expr.call]) persists until the completion of the full
expression containing the call.</P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">A</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">The lifetime of a</SPAN> temporary bound to the
returned value in a function return statement (6.6.3 [stmt.return]) <SPAN style="text-decoration:line-through;background-color:#FFA0A0">persists until the function exits</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">is not extended; the
temporary is destroyed at the end of the full-expression in the return
statement.</SPAN></P></LI>

</UL>

<P>The destruction of a temporary whose lifetime is not extended...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="542"></A><H4>542.
  
Value initialization of arrays of POD-structs
</H4><B>Section: </B>12.6&#160; [class.init]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>27 October 2005<BR>


<P>[Voted into the WP at the March, 2009 meeting.]</P>

<P>12.6 [class.init] paragraph 2 says,</P>

<BLOCKQUOTE>

When an array of class objects is initialized (either explicitly or
implicitly), the constructor shall be called for each element of the
array, following the subscript order;

</BLOCKQUOTE>

<P>That implies that, given</P>

<PRE>
    struct POD {
      int x;
    };

    POD data[10] = {};
</PRE>

<P>this should call the implicitly declared default ctor 10 times,
leaving 10 uninitialized ints, rather than value initialize each
member of data, resulting in 10 initialized ints (which is required
by 8.5.1 [dcl.init.aggr] paragraph 7).</P>

<P>I suggest rephrasing along the lines:</P>

<BLOCKQUOTE>

When an array is initialized (either explicitly or implicitly), each
element of the array shall be initialized in turn, following the
subscript order;

</BLOCKQUOTE>

<P>This would allow for PODs and other classes with a dual nature under
value/default initialization, and cover copy initialization for arrays
too.</P>

<P><B>Proposed resolution (October, 2006):</B></P>

<P>Change 12.6 [class.init] paragraph 3 as follows:</P>

<BLOCKQUOTE>

When an array of class objects is initialized (either explicitly or
implicitly) <SPAN style="font-weight:bold;background-color:#A0FFA0">and the elements are initialized by constructor</SPAN>,
the constructor shall be called for each element of the array,
following the subscript order; see 8.3.4 [dcl.array].

</BLOCKQUOTE>

<BR><BR><HR><A NAME="257"></A><H4>257.
  
Abstract base constructors and virtual base initialization
</H4><B>Section: </B>12.6.2&#160; [class.base.init]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>1 Nov 2000<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>Must a constructor for an abstract base class provide a
<I>mem-initializer</I> for each virtual base class from which it is
directly or indirectly derived?  Since the initialization of
virtual base classes is performed by the most-derived class, and
since an abstract base class can never be the most-derived class,
there would seem to be no reason to require constructors for
abstract base classes to initialize virtual base classes.</P>

<P>It is not clear from the Standard whether there actually is
such a requirement or not.  The relevant text is found in
12.6.2 [class.base.init] paragraph 6:</P>

<BLOCKQUOTE>

All sub-objects representing virtual base classes are initialized by
the constructor of the most derived class (1.8 [intro.object]). If the constructor of the most derived class does not
specify a <I>mem-initializer</I> for a virtual base class <TT>V</TT>,
then <TT>V</TT>'s default constructor is called to initialize the virtual
base class subobject. If <TT>V</TT> does not have an accessible default
constructor, the initialization is ill-formed. A <I>mem-initializer</I>
naming a virtual base class shall be ignored during execution of the
constructor of any class that is not the most derived class.

</BLOCKQUOTE>

<P>This paragraph requires only that the most-derived class's
constructor have a <I>mem-initializer</I> for virtual base classes.
Should the silence be construed as permission for constructors
of classes that are not the most-derived to omit such
<I>mem-initializer</I>s?</P>

<P><U>Christopher Lester</U>, on comp.std.c++, March 19, 2004:
If any of you reading this posting happen to be members of the above
working group, I would like to encourage you to review the suggestion
contained therein, as it seems to me that the final tenor of the
submission is both (a) correct (the silence of the standard DOES
mandate the omission) and (b) describes what most users would
intuitively expect and desire from the C++ language as well.</P>

<P>The suggestion is to make it clearer that constructors for abstract
base classes should not be required to provide initialisers for any
virtual base classes they contain (as only the most-derived class has
the job of initialising virtual base classes, and an abstract base
class cannot possibly be a most-derived class).</P>

<P>For example:</P>
<PRE>
struct A {
  A(const int i, const int j) {};
};

struct B1 : virtual public A {
  virtual void moo()=0;
  B1() {};   // (1) Look! not "B1() : A(5,6) {};"
};

struct B2 : virtual public A {
  virtual void cow()=0;
  B2() {};   // (2) Look! not "B2() : A(7,8) {};"
};

struct C : public B1, public B2 {
  C() : A(2,3) {};
  void moo() {};
  void cow() {};
};

int main() {
  C c;
  return 0;
};
</PRE>

<P>I believe that, by not expressly forbidding it, the standard does
(and should!) allow the above code.  However, as the standard doesn't
expressly allow it either (have I missed something?) there appears to
be room for misunderstanding. For example, g++ version 3.2.3 (and
maybe other versions as well) rejects the above code with messages 
like:</P>
<PRE>
	In constructor `B1::B1()':
	no matching function for call to `A::A()'
	candidates are: A::A(const A&amp;)
         	        A::A(int, int)
</PRE>

<P>Fair enough, the standard is perhaps not clear enough.  But it seems
to be a shame that although this issue was first raised in 2000, we
are still living with it today.</P>

<P>Note that we can work-around, and persuade g++ to compile the above
by either (a) providing a default constructor A() for A, or (b)  
supplying default values for i and j in A(i,j), or (c) replace the
construtors B1() and B2() with the forms shown in the two comments in
the above example.</P>

<P>All three of these workarounds may at times be appropriate, but 
equally there are other times when all of these workarounds are 
particularly bad.  (a) and (b) may be very bad if you are trying to 
enforce string contracts among objects, while (c) is just barmy (I 
mean why did I have to invent random numbers like 5, 6, 7 and 8 just 
to get the code to compile?).</P>

<P>So to to round up, then, my plea to the working group is:

	"at the very least, please make the standard clearer on 
this issue, but preferrably make the decision to expressly allow 
code that looks something like the above"</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<OL><LI><P>Add the indicated text (moved from paragraph 11) to the end
of 12.6.2 [class.base.init] paragraph 7:</P></LI>

<BLOCKQUOTE>

...The initialization of each base and member constitutes a
full-expression.  Any expression in a <I>mem-initializer</I> is
evaluated as part of the full-expression that performs the
initialization. <SPAN style="font-weight:bold;background-color:#A0FFA0">A <I>mem-initializer</I> where the
<I>mem-initializer-id</I> names a virtual base class is ignored during
execution of a constructor of any class that is not the most derived
class.</SPAN>

</BLOCKQUOTE>

<LI><P>Change 12.6.2 [class.base.init] paragraph 8 as follows:</P></LI>

<BLOCKQUOTE>

<P>If a given non-static data member or base class is not named by a
<I>mem-initializer-id</I> (including the case where there is no
<I>mem-initializer-list</I> because the constructor has no
<I>ctor-initializer</I>) <SPAN style="font-weight:bold;background-color:#A0FFA0">and the entity is not a virtual base
class of an abstract class (10.4 [class.abstract])</SPAN>, then</P>

<UL><LI><P>if the entity is a non-static data member that has a
<I>brace-or-equal-initializer</I>, the entity is initialized as
specified in 8.5 [dcl.init];</P></LI>

<LI><P>otherwise, if the entity is a variant member (9.5 [class.union]), no initialization is performed;</P></LI>

<LI><P>otherwise, the entity is default-initialized (8.5 [dcl.init]).</P></LI>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> An abstract class (10.4 [class.abstract]) is
never a most derived class, thus its constructors never initialize
virtual base classes, therefore the corresponding
<I>mem-initializer</I>s may be omitted. &#8212;<I>end note</I>]</SPAN>
After the call to a constructor for class <TT>X</TT> has
completed...</P>

</BLOCKQUOTE>

<LI><P>Change 12.6.2 [class.base.init] paragraph 10 as follows:</P></LI>

<BLOCKQUOTE>

<P>Initialization <SPAN style="text-decoration:line-through;background-color:#FFA0A0">shall proceed</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">proceeds</SPAN> in the
following order:</P>

<UL><LI><P>First, and only for the constructor of the most derived
class <SPAN style="text-decoration:line-through;background-color:#FFA0A0">as described below</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">(1.8 [intro.object])</SPAN>, virtual base classes <SPAN style="text-decoration:line-through;background-color:#FFA0A0">shall be</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">are</SPAN> initialized in the order they appear on a depth-first
left-to-right traversal of the directed acyclic graph of base classes,
where &#8220;left-to-right&#8221; is the order of appearance of the
base class names in the derived class <I>base-specifier-list</I>.</P></LI>

<LI><P>Then, direct base classes <SPAN style="text-decoration:line-through;background-color:#FFA0A0">shall be</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">are</SPAN>
initialized in declaration order as they appear in the
<I>base-specifier-list</I> (regardless of the order of the
<I>mem-initializer</I>s).</P></LI>

<LI><P>Then, non-static data members <SPAN style="text-decoration:line-through;background-color:#FFA0A0">shall be</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">are</SPAN> initialized in the order they were declared in the
class definition (again regardless of the order of the
<I>mem-initializer</I>s).</P></LI>

<LI><P>Finally, the <I>compound-statement</I> of the constructor body
is executed.</P></LI>

</UL>

<P>[<I>Note:</I> the declaration order is mandated to ensure that base and
member subobjects are destroyed in the reverse order of
initialization. &#8212;<I>end note</I>]</P>

</BLOCKQUOTE>

<LI><P>Remove all normative text in 12.6.2 [class.base.init] paragraph
11, keeping the example:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">All subobjects representing virtual base classes are initialized
by the constructor of the most derived class (1.8 [intro.object]).  If the constructor of the most derived class does not
specify a <I>mem-initializer</I> for a virtual base class <TT>V</TT>,
then <TT>V</TT>'s default constructor is called to initialize the
virtual base class subobject. If <TT>V</TT> does not have an
accessible default constructor, the initialization is ill-formed.  A
<I>mem-initializer</I> naming a virtual base class shall be ignored during
execution of the constructor of any class that is not the most derived
class.</SPAN> [<I>Example:</I>...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="888"></A><H4>888.
  
Union member initializers
</H4><B>Section: </B>12.6.2&#160; [class.base.init]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>6 May, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>12.6.2 [class.base.init] paragraph 5 forbids initializing
multiple members of a union via <I>mem-initializer</I>s:</P>

<BLOCKQUOTE>

If a <I>ctor-initializer</I> specifies more than one
<I>mem-initializer</I> for the same member, for the same base class or
for multiple members of the same union (including members of anonymous
unions), the <I>ctor-initializer</I> is ill-formed.

</BLOCKQUOTE>

<P>However, there is no corresponding restriction against specifying
<I>brace-or-equal-initializer</I>s for multiple union members, nor
for a non-overlapping pair of <I>brace-or-equal-initializer</I> and
<I>mem-initializer</I>.  This is presumably an oversight.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<OL><LI><P>Change 9.5 [class.union] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...If a union contains a non-static data member of reference type the
program is ill-formed. <SPAN style="font-weight:bold;background-color:#A0FFA0">At most one non-static data member of a
union shall have a <I>brace-or-equal-initializer</I>.</SPAN>
[<I>Note:</I>...

</BLOCKQUOTE>

<LI><P>Change 12.6.2 [class.base.init] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

...If a <I>ctor-initializer</I> specifies more than one
<I>mem-initializer</I> for the same member<SPAN style="text-decoration:line-through;background-color:#FFA0A0">,</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">or</SPAN>
for the same base class <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or for multiple members of the same union
(including members of anonymous unions)</SPAN>, the
<I>ctor-initializer</I> is ill-formed.

</BLOCKQUOTE>

<LI><P>Change 12.6.2 [class.base.init] paragraph 8 as follows:</P></LI>

<BLOCKQUOTE>

...<SPAN style="font-weight:bold;background-color:#A0FFA0">An attempt to initialize more than one non-static data member
of a union renders the program ill-formed.</SPAN> After the call to a
constructor for class <TT>X</TT> has completed...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="710"></A><H4>710.
  
Data races during construction
</H4><B>Section: </B>12.7&#160; [class.cdtor]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Jeffrey Yasskin
 &#160;&#160;&#160;

 <B>Date: </B>3 May, 2008<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>Consider the following example:</P>

<PRE>
    struct A {
      A() {
        std::thread(&amp;A::Func, this).detach();
      }
      virtual void Func() {
        printf("In A");
      }
    };

    struct B : public A {
      virtual void Func() {
        printf("In B");
      }
    };

    struct C : public B {
      virtual void Func() {
        printf("In C");
      }
    };

    C c;
</PRE>

<P>What is the program allowed to print?  Should it be undefined
behavior or merely unspecified which of the <TT>Func()</TT>s is
called?</P>

<P>There is a related question about which variables <TT>C::Func()</TT>
can depend on having been constructed.  Unless we want to require
the equivalent of at least <TT>memory_order_consume</TT> on the
presumed virtual function table pointer, I think the answer is just
the members of <TT>A</TT>.</P>

<P>If I instead just have</P>

<PRE>
    A a;
</PRE>

<P>I think the only reasonable behavior is to print <TT>In A</TT>.</P>

<P>Finally, given</P>

<PRE>
    struct F {
      F() {
        std::thread(&amp;F::Func, this).detach();
      }
      virtual void Func() {
        print("In F");
      }
    };

    struct G : public F {
    };

    G g;
</PRE>

<P>I can see the behavior being undefined, but I think a lot of
people would be confused if it did anything other than print
<TT>In F</TT>.</P>

<P>Suggested resolution:</P>

<P>I think the intent here is that an object should not be used in
another thread until any non-trivial constructor has been called.
One possible way of saying that would be to add a new paragraph
at the end of 12.7 [class.cdtor]:</P>

<BLOCKQUOTE>

A constructor for a class with virtual functions or virtual
base classes modifies a memory location in the object that is
accessed by any access to a virtual function or virtual base
class or by a <TT>dynamic_cast</TT>.  [<I>Note:</I> This implies
that access to an object by another thread while it is being
constructed often introduces a data race (see
1.10 [intro.multithread]). &#8212;<I>end note</I>]

</BLOCKQUOTE>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Add the following as a new paragraph at the end of 3.8 [basic.life]:</P>

<BLOCKQUOTE>

<SPAN style="font-weight:bold;background-color:#A0FFA0">In this section, &#8220;before&#8221; and &#8220;after&#8221; refer to
the &#8220;happens before&#8221; relation (1.10 [intro.multithread]). [<I>Note:</I> Therefore, undefined behavior results if
an object that is being constructed in one thread is referenced from a
different thread without adequate synchronization. &#8212;<I>end
note</I>]</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="653"></A><H4>653.
  
Copy assignment of unions
</H4><B>Section: </B>12.8&#160; [class.copy]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Jens Maurer
 &#160;&#160;&#160;

 <B>Date: </B>3 October 2007<BR>


<P>[Voted into WP at July, 2009 meeting.]</P>



<P>How does copy assignment for unions work?  For example,</P>

<PRE>
  union U {
    int a;
    float b;
  };

  void f() {
    union U u = { 5 };
    union U v;
    v = u;    // what happens here?
  }
</PRE>

<P>9.5 [class.union] is silent on the issue, therefore it
seems that 12.8 [class.copy] applies.  There is no special
case for unions, thus paragraph 13 (memberwise assignment of
subobjects) seems to apply.  That would seem to imply these actions in
the compiler-generated copy assignment operator:</P>

<PRE>
  v.a = u.a;
  v.b = u.b;
</PRE>

<P>And this is just wrong.  For example, the lifetime of
<TT>v.a</TT> ends once the second assignment reuses the memory
of <TT>v.a</TT>.</P>

<P>We should probably prescribe &#8220;memcpy&#8221; copying for
unions (both for the copy constructor and the assignment operator)
unless the user provided his own special member function.</P>

<P><B>Proposed resolution (March, 2008):</B></P>

<OL><LI><P>Change 12.8 [class.copy] paragraph 8 as follows:</P></LI>

<BLOCKQUOTE>

The implicitly-defined or explicitly-defaulted copy constructor for
<SPAN style="font-weight:bold;background-color:#A0FFA0">a non-union</SPAN> class <TT>X</TT> performs a memberwise copy of its
subobjects...

</BLOCKQUOTE>

<LI><P>Add a new paragraph after 12.8 [class.copy]
paragraph 8:</P></LI>

<BLOCKQUOTE>

The implicitly-defined or explicitly-defaulted copy constructor for a
union <TT>X</TT> where all members have a trivial copy constructor
copies the object representation (3.9 [basic.types]) of
<TT>X</TT>. [<I>Note:</I> The behavior is undefined if <TT>X</TT> is
not a trivial type. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraph 13 as follows:</P></LI>

<BLOCKQUOTE>

The implicitly-defined or explicitly-defaulted copy assignment
operator for <SPAN style="font-weight:bold;background-color:#A0FFA0">a non-union</SPAN> class <TT>X</TT> performs memberwise
assignment of its subobjects...

</BLOCKQUOTE>

<LI><P>Add a new paragraph after 12.8 [class.copy]
paragraph 13:</P></LI>

<BLOCKQUOTE>

The implicitly-defined or explicitly-defaulted copy assignment
operator for a union <TT>X</TT> where all members have a trivial copy
assignment operator copies the object representation (3.9 [basic.types]) of <TT>X</TT>. [<I>Note:</I> The behavior is undefined if
<TT>X</TT> is not a trivial type. &#8212;<I>end note</I>]

</BLOCKQUOTE>

</OL>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>The proposed wording needs to be updated to reflect the
changes adopted in papers N2757 and N2762, resolving <A HREF="
     cwg_defects.html#683">issue 683</A>, which require &#8220;no
non-trivial&#8221; special member functions instead of &#8220;a
trivial&#8221; function.  Also, the notes regarding undefined
behavior are incorrect, because the member functions involved are
defined as deleted when there are non-trivial members.</P>

<P><B>Proposed resolution (October, 2008):</B></P>

<OL>
<LI><P>Change 12.8 [class.copy] paragraph 8 as follows:</P></LI>

<BLOCKQUOTE>

The implicitly-defined or explicitly-defaulted copy constructor for
<SPAN style="font-weight:bold;background-color:#A0FFA0">a non-union</SPAN> class <TT>X</TT> performs a memberwise copy of its
subobjects...

</BLOCKQUOTE>

<LI><P>Add a new paragraph following 12.8 [class.copy]
paragraph 8:</P></LI>

<BLOCKQUOTE>

The implicitly-defined or explicitly-defaulted copy constructor for a
union <TT>X</TT> copies the object representation (3.9 [basic.types]) of <TT>X</TT>.

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraph 13 as follows:</P></LI>

<BLOCKUOTE>

The implicitly-defined or explicitly-defaulted copy assignment
operator for <SPAN style="font-weight:bold;background-color:#A0FFA0">a non-union</SPAN> class <TT>X</TT> performs memberwise
assignment of its subobjects...

</BLOCKUOTE>

<LI><P>Add a new paragraph following 12.8 [class.copy]
paragraph 13:</P></LI>

<BLOCKQUOTE>

The implicitly-defined or explicitly-defaulted copy assignment operator
for a union <TT>X</TT> copies the object representation
(3.9 [basic.types]) of <TT>X</TT>.

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="667"></A><H4>667.
  
Trivial special member functions that cannot be implicitly defined
</H4><B>Section: </B>12.8&#160; [class.copy]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>James Widman
 &#160;&#160;&#160;

 <B>Date: </B>14 December 2007<BR>


<P>[Voted into WP at March, 2010 meeting as part of document N3079.]</P>



<P>Should the following class have a trivial copy assignment operator?</P>

<PRE>
    struct A {
        int&amp; m;
        A();
        A(const A&amp;);
    };
</PRE>

<P>12.8 [class.copy] paragraph 11 does not mention whether the
presence of reference members (or cv-qualifiers, etc.) should affect
triviality.  Should it?</P>

<P>One reason why this matters is that implementations have to make
the builtin type trait operator <TT>__has_trivial_default_ctor(T)</TT>
work so that they can support the type trait template
<TT>std::has_trivial_default_constructor</TT>.</P>

<P>Assuming the answer is &#8220;yes,&#8221; it looks like we probably
need similar wording for trivial default and trivial copy ctors.
</P>

<P><B>Notes from the February, 2008 meeting:</B></P>

<P>Deleted special member functions are also not trivial.  Resolution
of this issue should be coordinated with the concepts proposal.</P>

<P><B>Notes from the June, 2008 meeting:</B></P>

<P>It appears that this issue will be resolved by the concepts
proposal directly.  The issue is in &#8220;review&#8221; status to
check if that is indeed the case in the final version of the
proposal.</P>

<P><B>Additional notes (May, 2009):</B></P>



<P>Consider the following example:</P>

<PRE>
    struct Base {
      private:
        ~Base() = default;
    };

    struct Derived: Base {
    };
</PRE>

<P>The implicitly-declared destructor of <TT>Derived</TT> is
defined as deleted because <TT>Base::~Base()</TT> is inaccessible,
but it fulfills the requirements for being trivial.  Presumably
the <TT>Base</TT> destructor should be non-trivial, either by
directly specifying that it is non-trivial or by specifying that it
is user-provided.  An alternative would be to make it ill-formed to
attempt to declare a defaulted non-public special member function.</P>



<P>Any changes to the definition of triviality should be checked
against 9 [class] paragraph 6 for any changes needed
there to accommodate the new definitions.</P>

<P><B>Notes from the July, 2009 meeting:</B></P>

<P>The July, 2009 resolution of <A HREF="
     cwg_defects.html#906">issue 906</A>
addresses the example above (with an inaccessible defaulted
destructor): a defaulted special member function can only have
non-public access if the defaulted definition is outside the class,
making it non-trivial.  The example as written above would be
ill-formed.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<OL><LI><P>Change 8.4 [dcl.fct.def] paragraph 9 as follows:</P></LI>

<BLOCKQUOTE>

...Only special member functions may be explicitly defaulted<SPAN style="font-weight:bold;background-color:#A0FFA0">.
Explicitly-defaulted functions and implicitly-declared functions are
collectively called <I>defaulted</I> functions</SPAN>, and the
implementation shall <SPAN style="text-decoration:line-through;background-color:#FFA0A0">define them as if they had</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">provide</SPAN> implicit definitions <SPAN style="font-weight:bold;background-color:#A0FFA0">for them</SPAN>
(12.1 [class.ctor], 12.4 [class.dtor], 12.8 [class.copy])<SPAN style="font-weight:bold;background-color:#A0FFA0">, which might mean defining them as deleted</SPAN>. A
special member function that would be implicitly defined as deleted
may be explicitly defaulted only on its first declaration, in which
case it is defined as deleted.  A special member function is
<I>user-provided</I> if it is user-declared and not explicitly
defaulted on its first declaration. A user-provided
explicitly-defaulted function is defined at the point where it is
explicitly defaulted. [<I>Note:</I>...

</BLOCKQUOTE>

<LI><P>Change 12.1 [class.ctor] paragraphs 5-6 as follows:</P></LI>

<BLOCKQUOTE>

<P>A <I>default</I> constructor for a class <TT>X</TT> is a
constructor of class <TT>X</TT> that can be called without an
argument.  If there is no user-declared constructor for class
<TT>X</TT>, a constructor having no parameters is implicitly declared
<SPAN style="font-weight:bold;background-color:#A0FFA0">as defaulted (8.4 [dcl.fct.def])</SPAN>.  An
implicitly-declared default constructor is an <TT>inline public</TT>
member of its class.  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">A default constructor is
<I>trivial</I> if it is not user-provided (8.4 [dcl.fct.def])
and if:</SPAN></P>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">its class has no virtual functions (10.3 [class.virtual]) and no virtual base classes (10.1 [class.mi]),
and</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">no non-static data member of its class has a
<I>brace-or-equal-initializer</I>, and</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">all the direct base classes of its class have trivial default
constructors, and</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">for all the non-static data members of its class that are of
class type (or array thereof), each such class has a trivial default
constructor.</SPAN></P></LI>

</UL>

<P>A<SPAN style="text-decoration:line-through;background-color:#FFA0A0">n implicitly-declared</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">defaulted</SPAN> default
constructor for class <TT>X</TT> is defined as deleted if:</P>

<UL><LI><P><TT>X</TT> is a union-like class that has a variant member
with a non-trivial default constructor,</P></LI>

<LI><P>any non-static data member is of reference type,</P></LI>

<LI><P>any non-static data member of const-qualified
type (or array thereof) does not have a user-provided default
constructor, or</P></LI>

<LI><P>any non-static data member or direct or virtual base class has
class type <TT>M</TT> (or array thereof) and <TT>M</TT> has no default
constructor, or if overload resolution (13.3 [over.match]) as
applied to <TT>M</TT>'s default constructor, results in an ambiguity
or a function that is deleted or inaccessible from the
implicitly-declared default constructor.</P></LI>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">A default constructor is trivial if it is neither
user-provided nor deleted and if:</SPAN></P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">its class has no virtual functions (10.3 [class.virtual]) and no virtual base classes (10.1 [class.mi]),
and</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">no non-static data member of its class has a
<I>brace-or-equal-initializer</I>, and</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">all the direct base classes of its class have trivial default
constructors, and</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">for all the non-static data members of its class that are of
class type (or array thereof), each such class has a trivial default
constructor.</SPAN></P></LI>

</UL>

<P>Otherwise, the default constructor is <I>non-trivial</I>.</P>

<P>A <SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-user-provided</SPAN> default constructor <SPAN style="text-decoration:line-through;background-color:#FFA0A0">for a
class</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">that is defaulted and not deleted</SPAN> is
<I>implicitly defined</I> when it is used (3.2 [basic.def.odr])
to create an object of its class type (1.8 [intro.object])<SPAN style="font-weight:bold;background-color:#A0FFA0">,
or when it is explicitly defaulted after its first declaration</SPAN>.
The implicitly-defined <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or explicitly-defaulted</SPAN> default
constructor performs the set of initializations of the class that
would be performed by a user-written default constructor for that
class with no <I>ctor-initializer</I> (12.6.2 [class.base.init])
and an empty <I>compound-statement</I>. If that user-written default
constructor would be ill-formed, the program is ill-formed.  If that
user-written default constructor would satisfy the requirements of a
constexpr constructor (7.1.5 [dcl.constexpr]), the
implicitly-defined default constructor is constexpr. Before the
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-user-provided</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">defaulted</SPAN> default constructor
for a class is implicitly defined, all the non-user-provided default
constructors for its base classes and its non-static data members
shall have been implicitly defined. [<I>Note:</I> an
implicitly-declared default constructor has an
<I>exception-specification</I> (15.4 [except.spec]).  An
explicitly-defaulted definition has no implicit
<I>exception-specification</I>. &#8212;<I>end note</I>]</P>

</BLOCKQUOTE>

<LI><P>Change 12.4 [class.dtor] paragraphs 3-4 as follows:</P></LI>

<BLOCKQUOTE>

<P>If a class has no user-declared destructor, a destructor is
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">declared</SPAN> implicitly <SPAN style="font-weight:bold;background-color:#A0FFA0">declared as defaulted
(8.4 [dcl.fct.def])</SPAN>. An implicitly-declared destructor is
an <TT>inline public</TT> member of its class. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">If the class is a
union-like class that has a variant member with a non-trivial
destructor, an implicitly-declared destructor is defined as deleted
(8.4 [dcl.fct.def]). A destructor is <I>trivial</I> if it is
not user-provided and if:</SPAN></P>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">the destructor is not <TT>virtual</TT>,</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">all of the direct base classes of its class have trivial
destructors, and</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">for all of the non-static data members of its class that are of
class type (or array thereof), each such class has a trivial
destructor.</SPAN></P></LI>

</UL>

<P>A<SPAN style="text-decoration:line-through;background-color:#FFA0A0">n implicitly-declared</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">defaulted</SPAN> destructor
for a class <TT>X</TT> is defined as deleted if:</P>

<UL><LI><P><TT>X</TT> is a union-like class that has a variant member
with a non-trivial destructor,</P></LI>

<LI><P>any of the non-static data members has class type <TT>M</TT>
(or array thereof) and <TT>M</TT> has <SPAN style="text-decoration:line-through;background-color:#FFA0A0">an</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">a</SPAN>
deleted destructor or a destructor that is inaccessible from the
implicitly-declared destructor, or</P></LI>

<LI><P>any direct or virtual base class has a deleted destructor or a
destructor that is inaccessible from the implicitly-declared
destructor.</P></LI>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">A destructor is trivial if it is neither user-provided nor
deleted and if:</SPAN></P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">the destructor is not <TT>virtual</TT>,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">all of the direct base classes of its class have trivial
destructors, and</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">for all of the non-static data members of its class that are of
class type (or array thereof), each such class has a trivial
destructor.</SPAN></P></LI>

</UL>

<P>Otherwise, the destructor is <I>non-trivial</I>.</P>

<P>A <SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-user-provided</SPAN> destructor <SPAN style="font-weight:bold;background-color:#A0FFA0">that is defaulted
and not defined as deleted</SPAN> is <I>implicitly defined</I> when it
is used to destroy an object of its class type (3.7 [basic.stc])<SPAN style="font-weight:bold;background-color:#A0FFA0">, or when it is explicitly defaulted after its first
declaration</SPAN>.  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">A program is ill-formed if the class for which a
destructor is implicitly defined or explicitly defaulted has:</SPAN></P>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">a non-static data member of class type (or array thereof)
with an inaccessible destructor, or</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">a base class with an inaccessible destructor.</SPAN></P></LI>

</UL>

<P>Before the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-user-provided</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">defaulted</SPAN>
destructor for a class is implicitly defined, all the
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-user-defined</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">non-user-provided</SPAN> destructors
for its base classes and its non-static data members shall have been
implicitly defined.  [<I>Note:</I> an implicitly-declared destructor
has an <I>exception-specification</I> (15.4 [except.spec]).  An
explictly defaulted definition has no implicit
<I>exception-specification</I>. &#8212;<I>end note</I>]</P>

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraphs 4-9 as follows:</P></LI>

<BLOCKQUOTE>

<P>If the class definition does not explicitly declare a copy
constructor, one is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">declared <I>implicitly</I></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">implicitly declared as defaulted (8.4 [dcl.fct.def])</SPAN>. Thus...</P>

<P>...An implicitly-declared copy constructor is an <TT>inline
public</TT> member of its class.  A<SPAN style="text-decoration:line-through;background-color:#FFA0A0">n implicitly-declared</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">defaulted</SPAN> copy constructor for a class <TT>X</TT> is
defined as deleted if <TT>X</TT> has: ...</P>

<P>A copy constructor for class <TT>X</TT> is
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>trivial</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">trivial</SPAN> if it is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">not</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">neither</SPAN> user-provided <SPAN style="font-weight:bold;background-color:#A0FFA0">nor deleted</SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">(8.4 [dcl.fct.def])</SPAN> and if...</P>

<P>A <SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-user-provided</SPAN> copy constructor <SPAN style="font-weight:bold;background-color:#A0FFA0">that is
defaulted and not defined as deleted</SPAN> is <I>implicitly
defined</I> if it is used to initialize an object of its class type
from a copy of an object of its class type or of a class type derived
from its class type<SUP>116</SUP><SPAN style="font-weight:bold;background-color:#A0FFA0">, or when it is explicitly
defaulted after its first declaration</SPAN>.  [<I>Note:</I> the copy
constructor is implicitly defined even if the implementation elided
its use (12.2 [class.temporary]). &#8212;<I>end note</I>]</P>

<P>Before the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-user-provided</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">defaulted</SPAN> copy
constructor for a class is implicitly defined, all non-user-provided
copy constructors...</P>

<P>The implicitly-defined <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or explicitly-defaulted</SPAN> copy
constructor for a non-union class <TT>X</TT> performs...</P>

<P>The implicitly-defined <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or explicitly-defaulted</SPAN> copy
constructor for a union <TT>X</TT> copies the object representation
(3.9 [basic.types]) of <TT>X</TT>.</P>

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraphs 11-15 as follows:</P></LI>

<BLOCKQUOTE>

<P>If the class definition does not explicitly declare a copy
assignment operator, one is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">declared <I>implicitly</I></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">implicitly declared as defaulted (8.4 [dcl.fct.def])</SPAN>...</P>

<P>...A<SPAN style="text-decoration:line-through;background-color:#FFA0A0">n implicitly-declared</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">defaulted</SPAN> copy
assignment operator for class <TT>X</TT> is defined as deleted if
<TT>X</TT> has:...</P>

<P>A copy assignment operator for class <TT>X</TT> is <I>trivial</I>
if it is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">not</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">neither</SPAN> user-provided <SPAN style="font-weight:bold;background-color:#A0FFA0">nor
deleted</SPAN> and if...</P>

<P>A <SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-user-provided</SPAN> copy assignment operator <SPAN style="font-weight:bold;background-color:#A0FFA0">that
is defaulted and not defined as deleted</SPAN> is <I>implicitly
defined</I> when an object of its class type is assigned a value of
its class type or a value of a class type derived from its class
type<SPAN style="font-weight:bold;background-color:#A0FFA0">, or when it is explicitly defaulted after its first
declaration</SPAN>.</P>

<P>Before the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-user-provided</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">defaulted</SPAN> copy
assignment operator for a class is implicitly defined...</P>

<P>The implicitly-defined <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or explicitly-defaulted</SPAN> copy
assignment operator for a non-union class <TT>X</TT> performs...</P>

<P>It is unspecified whether subobjects representing virtual base
classes are assigned more than once by the implicitly-defined <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or
explicitly-defaulted</SPAN> copy assignment
operator. [<I>Example:</I>...</P>

<P>The implicitly-defined <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or explicitly-defaulted</SPAN> copy
assignment operator for a union <TT>X</TT> copies the object
representation (3.9 [basic.types]) of <TT>X</TT>.</P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="680"></A><H4>680.
  
What is a move constructor?
</H4><B>Section: </B>12.8&#160; [class.copy]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2008<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#US33">N2800 comment
  US&#160;33<BR></A>

<P>[Voted into the WP at the July, 2009 meeting as part of N2927.]</P>

<P>Although the term &#8220;move constructor&#8221; appears multiple
times in the library clauses and is referenced in the newly-added
text for the lambda feature, it is not defined anywhere.</P>

<P><B>Notes from the June, 2008 meeting:</B></P>

<P>The only reference to &#8220;move constructor&#8221; in the core
language clauses of the Standard is in 5.1.2 [expr.prim.lambda]
paragraph 10; there are no semantic implications of the term. This
issue will be addressed by using a function signature instead of the
term, thus allowing the library section to provide a definition that
is appropriate for its needs.</P>

<P><B>Proposed resolution (July, 2009)</B></P>

<P>See document PL22.16/09-0117 = WG21 N2927.</P>

<BR><BR><HR><A NAME="887"></A><H4>887.
  
Move construction of thrown object
</H4><B>Section: </B>12.8&#160; [class.copy]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>6 May, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>12.8 [class.copy] paragraph 16 details the conditions
under which a thrown object can be moved instead of copied.  However,
the optimization as currently described is unsafe.  Consider the
following example:</P>

<PRE>
    void f() {
        X x;
        try {
            throw x;
        } catch (...) {
        }
        // x may have been moved from but can still be accessed here
    }
</PRE>

<P>When the operation is a throw, as opposed to a return, there
must be a restriction that the object potentially being moved
be defined within the innermost enclosing try block.</P>

<P><B>Notes from the July, 2009 meeting:</B></P>

<P>It is not clear how important this optimization is in the context
of <TT>throw</TT>: how often is a large object with substantial copying
overhead thrown?  Also, throwing an exception is already a heavyweight
operation, so presumably moving instead of copying an object would not
make much difference.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 12.8 [class.copy] paragraph 17 second bullet as
follows:</P>

<UL><LI>in a <I>throw-expression</I>, when the operand is the name of
a non-volatile automatic object <SPAN style="font-weight:bold;background-color:#A0FFA0">whose scope does not extend
beyond the end of the innermost enclosing <I>try-block</I> (if there
is one)</SPAN>, the copy operation from the operand to the exception
object (15.1 [except.throw]) can be omitted by constructing the
automatic object directly into the exception object</LI></UL>

<BR><BR><HR><A NAME="910"></A><H4>910.
  
Move constructors and implicitly-declared copy constructors
</H4><B>Section: </B>12.8&#160; [class.copy]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>4 June, 2009<BR>


<P>[Voted into WP at March, 2010 meeting as document N3053.]</P>



<P>A constructor of the form <TT>T::T(T&amp;&amp;)</TT> is a
candidate function for copy construction; however, the declaration
of such a constructor does not inhibit the implicit declaration and
definition of a copy constructor.  This can lead to surprising
results.  We should consider suppressing the implicit copy constructor
if a move constructor is declared.</P>

<BR><BR><HR><A NAME="999"></A><H4>999.
  
&#8220;Implicit&#8221; or &#8220;implied&#8221; object argument/parameter?
</H4><B>Section: </B>13.3&#160; [over.match]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>James Widman
 &#160;&#160;&#160;

 <B>Date: </B>20 November, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>The terminology used to refer to the parameter for
<TT>this</TT> and its corresponding argument is inconsistent,
sometimes using &#8220;implied&#8221; and sometimes
&#8220;implicit.&#8221; It would be easier to search the text of
the Standard if this usage were made regular.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<OL><LI><P>Change the index to refer to
&#8220;implicit object parameter&#8221; and &#8220;implied object
argument&#8221; instead of the current permutations of these
terms.</P></LI>

<LI><P>Change 13.3 [over.match] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...how well (for non-static member functions) the object matches
the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">implied</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">implicit</SPAN> object parameter...

</BLOCKQUOTE>

<LI><P>Change 13.3.1 [over.match.funcs] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

...For conversion functions, the function is considered to be a
member of the class of the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">implicit</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">implied</SPAN>
object argument for the purpose of defining the type of the
implicit object parameter...

</BLOCKQUOTE>

<LI><P>Change the footnote in 13.3.3 [over.match.best]
paragraph 1 bullet 1 as follows:</P></LI>

<UL><LI>[<I>Footnote:</I> If a function is a static member
function, this definition means that the first argument, the
implied object <SPAN style="text-decoration:line-through;background-color:#FFA0A0">parameter</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">argument</SPAN>, has no
effect in the determination of whether the function is better or
worse than any other function. &#8212;<I>end
footnote</I>]</LI></UL>

</OL>

<BR><BR><HR><A NAME="704"></A><H4>704.
  
To which <I>postfix-expression</I>s does overload resolution apply?
</H4><B>Section: </B>13.3.1.1&#160; [over.match.call]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Jens Maurer
 &#160;&#160;&#160;

 <B>Date: </B>29 July, 2008<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>There are several problems with the phrasing of 13.3.1.1 [over.match.call] paragraphs 1 and 3.  Paragraph 1 reads,</P>

<BLOCKQUOTE>

Recall from 5.2.2 [expr.call], that a <I>function
call</I> is a <I>postfix-expression</I>, possibly nested
arbitrarily deep in parentheses, followed by an optional
<I>expression-list</I> enclosed in parentheses:

<UL><TT>(</TT> ... <TT>(</TT><SUB><I>opt</I></SUB> <I>postfix-expression</I> <TT>)</TT> ... <TT>)</TT><SUB><I>opt</I></SUB> <TT>(</TT> <I>expression-list<SUB>opt</SUB></I> <TT>)</TT></UL>

Overload resolution is required if the <I>postfix-expression</I>
is the name of a function, a function template (14.5.6 [temp.fct]), an object of class type, or a set of
pointers-to-function.

</BLOCKQUOTE>

<P>Aside from the fact that directly addressing the reader
(&#8220;Recall that...&#8221;) is stylistically incongruous with
the rest of the Standard, as well as the fact that 5.2.2 [expr.call] doesn't mention parentheses at all, this wording
does not cover member function calls: a member access expression
isn't &#8220;the name&#8221; of anything.  This should perhaps be
reworded to refer to being either an <I>id-expression</I> or the
<I>id-expression</I> in a member access expression.  This could
be either by using two lines in the &#8220;of the form&#8221;
citation or in the discussion following the syntax reference. 
</P>

<P>In addition, paragraph 3 refers to &#8220;a
<I>postfix-expression</I> of the form <TT>&amp;F</TT>,&#8221;
which is an oxymoron: <TT>&amp;F</TT> is a
<I>unary-expression</I>, not a <I>postfix-expression</I>.  One
possibility would be to explicitly include the parentheses needed
in this case, i.e., &#8220;a <I>postfix-expression</I> of the
form <TT>(&amp;F)</TT>...&#8221;</P>

<P><B>Proposed resolution (September, 2009):</B></P>

<P>Replace the entirety of 13.3.1.1 [over.match.call] with
the following two paragraphs:</P>

<BLOCKQUOTE>

<P>In a function call (5.2.2 [expr.call])</P>

<UL><I>postfix-expression</I> <TT>(</TT> <I>expression-list<SUB>opt</SUB></I> <TT>)</TT></UL>

<P>if the <I>postfix-expression</I> denotes a set of overloaded
functions and/or function templates, overload resolution is applied as
specified in 13.3.1.1.1 [over.call.func]. If the <I>postfix-expression</I>
denotes an object of class type, overload resolution is applied as
specified in 13.3.1.1.2 [over.call.object].</P>

<P>If the <I>postfix-expression</I> denotes the address of a set of
overloaded functions and/or function templates, overload resolution is
applied using that set as described above. If the function selected by
overload resolution is a non-static member function, the program is
ill-formed. [<I>Note:</I> The resolution of the address of an overload
set in other contexts is described in 13.4 [over.over]. &#8212;<I>end note</I>]</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="604"></A><H4>604.
  
Argument list for overload resolution in copy-initialization
</H4><B>Section: </B>13.3.1.3&#160; [over.match.ctor]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Dawn Perchik
 &#160;&#160;&#160;

 <B>Date: </B>4 November 2006<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>According to 13.3.1.3 [over.match.ctor],</P>

<BLOCKQUOTE>

When objects of class type are direct-initialized (8.5 [dcl.init]), or copy-initialized from an expression of the
same or a derived class type (8.5 [dcl.init])... [the] argument list is
the <I>expression-list</I> within the parentheses of the
initializer.

</BLOCKQUOTE>

<P>However, in copy initialization (using the &#8220;=&#8221;
notation), there need be no parentheses.  What is the argument list
in that case?</P>

<P><B>Proposed resolution (June, 2009):</B></P>

<P>Change 13.3.1.3 [over.match.ctor] paragraph 1 as follows:</P>

<BLOCKQUOTE>

...The argument list is the <I>expression-list</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">or
<I>assignment-expression</I></SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">within the parentheses</SPAN> of the
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">initializer</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>initializer</I></SPAN>.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="899"></A><H4>899.
  
Explicit conversion functions in direct class initialization
</H4><B>Section: </B>13.3.1.4&#160; [over.match.copy]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>13 May, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>Consider the following example:</P>

<PRE>
    struct C { };

    struct A {
       explicit operator int() const;
       explicit operator C() const;
    };

    struct B {
       int i;
       B(const A&amp; a): i(a) { }
    };

    int main() {
       A a;
       int i = a;
       int j(a);
       C c = a;
       C c2(a);
    }
</PRE>

<P>It's clear that the <TT>B</TT> constructor and the declaration of
<TT>j</TT> are well-formed and the declarations of <TT>i</TT> and
<TT>c</TT> are ill-formed.  But what about the declaration of <TT>c2</TT>?
This is supposed to work, but it doesn't under the current wording.
</P>

<P><TT>C c2(a)</TT> is direct-initialization of a class, so
constructors are considered.  The only possible candidate is the
default copy constructor.  So we look for a conversion from <TT>A</TT>
to <TT>const C&amp;</TT>.  There is a conversion operator to
<TT>C</TT>, but it is explicit and we are now performing
copy-initialization of a reference temporary, so it is not a
candidate, and the declaration of <TT>c2</TT> is ill-formed.
</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 13.3.1.4 [over.match.copy] paragraph 1 second bullet
as follows:</P>

<UL><LI>When the type of the initializer expression is a class type
&#8220;<I>cv</I> <TT>S</TT>&#8221;, the non-explicit conversion
functions of <TT>S</TT> and its base classes are considered. <SPAN style="font-weight:bold;background-color:#A0FFA0">When
initializing a temporary to be bound to the first parameter of a copy
constructor (12.8 [class.copy]) called with a single argument
in the context of direct-initialization, explicit conversion functions
are also considered.</SPAN> Those that are not hidden within <TT>S</TT>
and yield a type whose cv-unqualified version is the same type as
<TT>T</TT> or is a derived class thereof are candidate functions.
Conversion functions that return &#8220;reference to <TT>X</TT>&#8221;
return lvalues or rvalues, depending on the type of reference, of type
<TT>X</TT> and are therefore considered to yield <TT>X</TT> for this
process of selecting candidate functions.</LI></UL>

<BR><BR><HR><A NAME="641"></A><H4>641.
  
Overload resolution and conversion-to-same-type operators
</H4><B>Section: </B>13.3.2&#160; [over.match.viable]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Nathan Sidwell
 &#160;&#160;&#160;

 <B>Date: </B>2 Aug 2007<BR>


<P>[Voted into the WP at the March, 2009 meeting.]</P>



<P>12.3.2 [class.conv.fct] paragraph 1 says,</P>

<BLOCKQUOTE>

A conversion function is never used to convert a (possibly
cv-qualified) object to the (possibly cv-qualified) same object
type (or a reference to it), to a (possibly cv-qualified) base
class of that type (or a reference to it), or to (possibly
cv-qualified) void.

</BLOCKQUOTE>

<P>At what point is this enforced, and how is it enforced?</P>

<OL>

<LI>Does such a user-declared conversion operator participate in
overload resolution? Or is it never entered into the overload
set?</LI>

<LI>If it does participate in overload resolution, what happens
if it is selected?  Is the program ill-formed (and diagnostic
required), or is it silently ignored?  The above wording doesn't
really make it clear.</LI>

</OL>

<P>Consider this test case:</P>

<PRE>
    struct abc;

    struct xyz {
       xyz();

       xyz(xyz &amp;);

       operator xyz&amp; (); // #1
       operator abc&amp; (); // #2
    };

    struct abc : xyz {};

    void foo(xyz &amp;);

    void bar() {
             foo (xyz ());
    }
</PRE>

<P>If such conversion functions are part of the overload set, #1
is a better conversion than #2 to convert the temporary xyz
object to a non-const reference required for foo's operand.  If
such conversion functions are not part of the overload set, then
#2 would be selected, and AFAICT the program would be well
formed.</P>

<P>If the conversion functions are not part of the overload set,
then it would seem one cannot take their address.  For instance,
adding the following line to the above test case would find no
suitable function:</P>

<PRE>
    xyz &amp;(xyz::*ptr) () = &amp;xyz::operator xyz &amp;;
</PRE>

<P><B>Notes from the October, 2007 meeting:</B></P>

<P>The intent of 12.3.2 [class.conv.fct] paragraph 1 is that
overload resolution not be attempted at all for the listed cases;
that is, if the target type is <TT>void</TT>, the object's type, or a
base of the object's type, the conversion is done directly without
considering any conversion functions.  Consequently, the questions about
whether the conversion function is part of the overload set or not
are moot.  The wording will be changed to make this clearer.</P>

<P><B>Proposed Resolution (October, 2007):</B></P>

<P>Change the footnote in 12.3.2 [class.conv.fct] paragraph 1 as
follows:</P>

<BLOCKQUOTE>

A conversion function is never used to convert a (possibly
cv-qualified) object to the (possibly cv-qualified) same object type
(or a reference to it), to a (possibly cv-qualified) base class of
that type (or a reference to it), or to (possibly cv-qualified) void.
[<I>Footnote:</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">These conversions are considered as standard
conversions for the purposes of overload resolution
(13.3.3.1 [over.best.ics], 13.3.3.1.4 [over.ics.ref])
and therefore initialization (8.5 [dcl.init]) and
explicit casts (5.2.9 [expr.static.cast]).  A conversion to
<TT>void</TT> does not invoke any conversion function (5.2.9 [expr.static.cast]).</SPAN> Even though never directly called to perform a
conversion, such conversion functions can be declared and can
potentially be reached through a call to a virtual conversion function
in a base class &#8212;<I>end footnote</I>]

</BLOCKQUOTE>

<P><B>Additional note (March, 2008):</B></P>

<P>A slight change to the example above indicates that there is a
need for a normative change as well as the clarification of the
rationale in the October, 2007 proposed resolution.  If the
declaration of <TT>foo</TT> were changed to</P>

<PRE>
    void foo(const xyz&amp;);
</PRE>

<P>with the current wording, the call <TT>foo(xyz())</TT> would
be interpreted as <TT>foo(xyz().operator&#160;abc&amp;())</TT> instead
of binding the parameter directly to the rvalue, which is clearly
wrong.</P>

<P><B>Proposed resolution (March, 2008):</B></P>

<OL>
<LI><P>Change the footnote in 12.3.2 [class.conv.fct] paragraph 1
as described in the October, 2007 proposed resolution.</P></LI>

<LI><P>Change 8.5.3 [dcl.init.ref] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

<P>A reference to type &#8220;<I>cv1</I> <TT>T1</TT>&#8221; is
initialized by an expression of type &#8220;<I>cv2</I>
<TT>T2</TT>&#8221; as follows:</P>

<UL>
<LI><P>If the initializer expression</P></LI>

<UL>
<LI><P>is an lvalue (but is not a bit-field), and
&#8220;<I>cv1</I> <TT>T1</TT>&#8221; is reference-compatible with
&#8220;<I>cv2</I> <TT>T2</TT>,&#8221; or</P></LI>

<LI><P>has a class type (i.e., <TT>T2</TT> is a class type)<SPAN style="font-weight:bold;background-color:#A0FFA0">,
where <TT>T1</TT> is not reference-related to <TT>T2</TT>,</SPAN>
and can be implicitly converted to an lvalue of type
&#8220;<I>cv3</I> <TT>T3</TT>,&#8221; where &#8220;<I>cv1</I>
<TT>T1</TT>&#8221; is reference-compatible with &#8220;<I>cv3</I>
<TT>T3</TT>&#8221; [<I>Footnote:</I> This requires a conversion
function (12.3.2 [class.conv.fct]) returning a reference
type. &#8212;<I>end footnote</I>] (this conversion is selected by
enumerating the applicable conversion functions (13.3.1.6 [over.match.ref]) and choosing the best one through overload
resolution (13.3 [over.match])),</P></LI>

</UL>

<P>then...</P>

</UL>

</BLOCKQUOTE>

<P><I>[Drafting note: this resolution makes the example in the
issue description ill-formed.]</I></P>

</OL>

<BR><BR><HR><A NAME="877"></A><H4>877.
  
Viable functions and binding references to rvalues
</H4><B>Section: </B>13.3.2&#160; [over.match.viable]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>23 April, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>13.3.2 [over.match.viable] paragraph 3 says,</P>

<BLOCKQUOTE>

If the parameter has reference type, the implicit conversion sequence
includes the operation of binding the reference, and the fact that a
reference to non-const cannot be bound to an rvalue can affect the
viability of the function (see 13.3.3.1.4 [over.ics.ref]).

</BLOCKQUOTE>

<P>This should say &#8220;lvalue reference to non-const,&#8221; as
is correctly stated in 13.3.3.1.4 [over.ics.ref] paragraph 3.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 13.3.2 [over.match.viable] paragraph 3 as follows:</P>

<BLOCKQUOTE>

If the parameter has reference type, the implicit conversion sequence
includes the operation of binding the reference, and the fact that
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">a</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an lvalue</SPAN> reference to non-const cannot be
bound to an rvalue can affect the viability of the function (see
13.3.3.1.4 [over.ics.ref]).

</BLOCKQUOTE>

<BR><BR><HR><A NAME="495"></A><H4>495.
  
Overload resolution with template and non-template conversion functions
</H4><B>Section: </B>13.3.3&#160; [over.match.best]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Nathan Sidwell
 &#160;&#160;&#160;

 <B>Date: </B>20 Dec 2004<BR>


<P>[Voted into WP at July, 2009 meeting.]</P>

<P>
The overload resolution rules for ranking a template against a
non-template function differ for conversion functions in a
surprising way.  13.3.3 [over.match.best] lists four checks,
the last three concern this report.  For the non-conversion
operator case, checks 2 and 3 are applicable, whereas for the
conversion operator case checks 3 and 4 are applicable. Checks 2
and 4 concern the ranking of argument and return value conversion
sequences respectively.  Check 3 concerns only the templatedness
of the functions being ranked, and will prefer a non-template to
a template.  Notice that this check happens after argument
conversion sequence ranking, but <I>before</I> return value
conversion sequence ranking.  This has the effect of always
selecting a non-template conversion operator, as the following
example shows:
</P>

<PRE>
    struct C
    {
      inline operator int () { return 1; }
      template &lt;class T&gt; inline operator T () { return 0; }
    };

    inline long f (long x) { return x; }

    int
    main (int argc, char *argv[])
    {
      return f (C ());
    }
</PRE>

<P>
The non-templated <TT>C::operator int</TT> function will be
selected, rather than the apparently better
<TT>C::operator long&lt;long&gt;</TT> instantiation.  This is a
surprise, and resulted in a bug report where the user expected
the template to be selected.  In addition some C++ compilers have
implemented the overload ranking as if checks 3 and 4 were
transposed.
</P>

<P>
Is this ordering accidental, or is there a rationale?
</P>

<P><B>Notes from the April, 2005 meeting:</B></P>

<P>The CWG agreed that the template/non-template distinction should
be the final tie-breaker.</P>

<P><B>Proposed resolution (March, 2007):</B></P>

<P>In the second bulleted list of 13.3.3 [over.match.best]
paragraph 1, move the second and third bullets to the end of the list,
to read as follows:</P>

<BLOCKQUOTE>

<UL>

<LI><P>for some argument <I>j</I>, ICS<I>j</I>(<TT>F1</TT>) is a
better conversion sequence than ICS<I>j</I>(<TT>F2</TT>), or, if not
that,</P></LI>

<LI><P>the context is an initialization by user-defined conversion
(see 8.5 [dcl.init], 13.3.1.5 [over.match.conv], and
13.3.1.6 [over.match.ref]) and the standard conversion sequence
from the return type of <TT>F1</TT> to the destination type (i.e., the
type of the entity being initialized) is a better conversion sequence
than the standard conversion sequence from the return type
of <TT>F2</TT> to the destination type, [<I>Example:</I> ...
&#8212;<I>end example</I>] or, if not that,</P></LI>

<P><LI><TT>F1</TT> is a non-template function and <TT>F2</TT> is a
function template specialization, or, if not that,</LI></P>

<LI><P><TT>F1</TT> and <TT>F2</TT> are function template
specializations, and the function template for <TT>F1</TT> is more
specialized than the template for <TT>F2</TT> according to the partial
ordering rules described in 14.5.6.2 [temp.func.order].</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="978"></A><H4>978.
  
Incorrect specification for copy initialization
</H4><B>Section: </B>13.3.3.1&#160; [over.best.ics]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>5 October, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>13.3.3.1 [over.best.ics] paragraph 4 says,</P>

<BLOCKQUOTE>

However, when considering the argument of a user-defined conversion
function that is a candidate by 13.3.1.3 [over.match.ctor] when
invoked for the copying of the temporary in the second step of a class
copy-initialization, by 13.3.1.7 [over.match.list] when passing the
initializer list as a single argument or when the initializer list has
exactly one element and a conversion to some class <TT>X</TT> or
reference to (possibly cv-qualified) <TT>X</TT> is considered for the
first parameter of a constructor of <TT>X</TT>, or by 13.3.1.4 [over.match.copy], 13.3.1.5 [over.match.conv], or 13.3.1.6 [over.match.ref] in all cases, only standard conversion sequences and
ellipsis conversion sequences are allowed.

</BLOCKQUOTE>

<P>This is not quite right, as this applies to constructor
arguments, not just arguments of user-defined conversion
functions.  Furthermore, the word &#8220;allowed&#8221; might
be better replaced by something like,</P>

<BLOCKQUOTE>

considered (in particular, for the purposes of determining
whether the candidate function (that is either a constructor
or a conversion function) is viable)

</BLOCKQUOTE>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 13.3.3.1 [over.best.ics] paragraph 4 as follows:</P>

<BLOCKQUOTE>

However, when considering the argument of a <SPAN style="font-weight:bold;background-color:#A0FFA0">constructor or</SPAN>
user-defined conversion function that is a candidate by 13.3.1.3 [over.match.ctor] when invoked for the copying of the temporary in the
second step of a class copy-initialization, by 13.3.1.7 [over.match.list] when passing the initializer list as a single
argument or when the initializer list has exactly one element and a
conversion to some class <TT>X</TT> or reference to (possibly
cv-qualified) <TT>X</TT> is considered for the first parameter of a
constructor of <TT>X</TT>, or by 13.3.1.4 [over.match.copy],
13.3.1.5 [over.match.conv], or 13.3.1.6 [over.match.ref] in all
cases, only standard conversion sequences and ellipsis conversion
sequences are <SPAN style="text-decoration:line-through;background-color:#FFA0A0">allowed</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">considered</SPAN>.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="953"></A><H4>953.
  
Rvalue references and function viability
</H4><B>Section: </B>13.3.3.1.4&#160; [over.ics.ref]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>18 August, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>According to 13.3.3.1.4 [over.ics.ref] paragraphs 3-4,</P>

<BLOCKQUOTE>

<P>A standard conversion sequence cannot be formed if it requires
binding an lvalue reference to non-const to an rvalue (except when
binding an implicit object parameter; see the special rules for that
case in 13.3.1 [over.match.funcs]).  [<I>Note:</I> this means, for
example, that a candidate function cannot be a viable function if it
has a non-<TT>const</TT> lvalue reference parameter (other than the
implicit object parameter) and the corresponding argument is a
temporary or would require one to be created to initialize the lvalue
reference (see 8.5.3 [dcl.init.ref]). &#8212;<I>end note</I>]</P>

<P>Other restrictions on binding a reference to a particular argument
that are not based on the types of the reference and the argument do
not affect the formation of a standard conversion sequence,
however.</P>

</BLOCKQUOTE>

<P>Because this section does not mention attempting to bind an
rvalue reference to an lvalue, such a &#8220;conversion sequence&#8221;
might be selected as best and result in an ill-formed program.  It
should, instead, be treated like trying to bind an lvalue reference
to non-const to an rvalue, making the function non-viable.</P>

<P><B>Proposed resolution (November, 2009):</B></P>

<P>Change 13.3.3.1.4 [over.ics.ref] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Except for an implicit object parameter, for
which see 13.3.1 [over.match.funcs], a</SPAN> standard
conversion sequence cannot be formed if it requires binding an
lvalue reference to non-<TT>const</TT> to an rvalue <SPAN style="text-decoration:line-through;background-color:#FFA0A0">(except
when binding an implicit object parameter; see the special rules
for that case in 13.3.1 [over.match.funcs])</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">or
binding an rvalue reference to an lvalue</SPAN>.  [<I>Note:</I>
this means, for example, that a candidate function cannot be a
viable function if it has a non-<TT>const</TT> lvalue reference
parameter (other than the implicit object parameter) and the
corresponding argument is a temporary or would require one to be
created to initialize the lvalue reference (see
8.5.3 [dcl.init.ref]). &#8212;<I>end note</I>]

</BLOCKQUOTE>

<BR><BR><HR><A NAME="702"></A><H4>702.
  
Preferring conversion to <TT>std::initializer_list</TT>
</H4><B>Section: </B>13.3.3.2&#160; [over.ics.rank]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2 July, 2008<BR>


<P>[Voted into WP at July, 2009 meeting.]</P>



<P>We need another bullet in 13.3.3.2 [over.ics.rank], along
the lines of:</P>

<UL><LI><P>List-initialization sequence <TT>L1</TT> is a better
conversion sequence than list-initialization sequence <TT>L2</TT>
if <TT>L1</TT> converts to <TT>std::initializer_list&lt;X&gt;</TT>
for some <TT>X</TT> and <TT>L2</TT> does not.</P></LI></UL>

<P>This is necessary to make the following example work:</P>

<PRE>
    #include &lt;initializer_list&gt;

    struct string {
      string (const char *) {}
      template &lt;class Iter&gt; string (Iter, Iter);
    };

    template &lt;class T, class U&gt;
    struct pair {
      pair (T t, U u) {}
    };

    template&lt;class T, class U&gt;
    struct map {
      void insert (pair&lt;T,U&gt;);
      void insert (std::initializer_list&lt;pair&lt;T,U&gt; &gt;) {}
    };

    int main() {
      map&lt;string,string&gt; m;
      m.insert({ {"this","that"}, {"me","you"} });
    }
</PRE>

<P><B>Proposed resolution (March, 2009):</B></P>

<P>Add a new top-level bullet at the end of the current list in
13.3.3.2 [over.ics.rank] paragraph 3:</P>

<UL><LI>List-initialization sequence <TT>L1</TT> is a better
conversion sequence than list-initialization sequence <TT>L2</TT> if
<TT>L1</TT> converts to <TT>std::initializer_list&lt;X&gt;</TT> for
some <TT>X</TT> and <TT>L2</TT> does not.</LI></UL>

<BR><BR><HR><A NAME="961"></A><H4>961.
  
Overload resolution and conversion of <TT>std::nullptr_t</TT> to <TT>bool</TT>
</H4><B>Section: </B>13.3.3.2&#160; [over.ics.rank]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>2 September, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>Conversion of a pointer or pointer to member to <TT>bool</TT> is
given special treatment as a tiebreaker in overload resolution in
13.3.3.2 [over.ics.rank] paragraph 4, bullet 1:</P>

<UL><LI>A conversion that is not a conversion of a pointer, or pointer
to member, to <TT>bool</TT> is better than another conversion that is
such a conversion.</LI></UL>

<P>It would be reasonable to expect a similar provision to apply to
conversions of <TT>std::nullptr_t</TT> to <TT>bool</TT>.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 13.3.3.2 [over.ics.rank] paragraph 4 bullet 1 as follows:</P>

<UL><LI>A conversion that <SPAN style="text-decoration:line-through;background-color:#FFA0A0">is not a conversion of</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">does
not convert</SPAN> a pointer, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">a</SPAN> pointer to
member, <SPAN style="font-weight:bold;background-color:#A0FFA0">or <TT>std::nullptr_t</TT></SPAN> to <TT>bool</TT> is
better than <SPAN style="text-decoration:line-through;background-color:#FFA0A0">another conversion that is such a conversion</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">one that does</SPAN>.</LI>

</UL>

<BR><BR><HR><A NAME="935"></A><H4>935.
  
Missing overloads for character types for user-defined literals
</H4><B>Section: </B>13.5.8&#160; [over.literal]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>9 July, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>The list of overloads for user-defined literal operators given in
13.5.8 [over.literal] paragraph 3 should include signatures for
<TT>char</TT>, <TT>wchar_t</TT>, <TT>char16_t</TT>, and
<TT>char32_t</TT>.</P>

<P><B>Proposed resolution (November, 2009):</B></P>

<P>Change 13.5.8 [over.literal] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<P>The declaration of a literal operator shall have a
<I>parameter-declaration-clause</I> equivalent to one of the
following:</P>

<PRE>
  const char*
  unsigned long long int
  long double
<SPAN style="font-weight:bold;background-color:#A0FFA0">  char
  wchar_t
  char16_t
  char32_t</SPAN>
  const char*, std::size_t
  const wchar_t*, std::size_t
  const char16_t*, std::size_t
  const char32_t*, std::size_t
</PRE>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="749"></A><H4>749.
  
References to function types with a <I>cv-qualifier</I> or <I>ref-qualifier</I>
</H4><B>Section: </B>13.6&#160; [over.built]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Alberto Ganesh Barbati
 &#160;&#160;&#160;

 <B>Date: </B>9 December, 2008<BR>


<P>[Voted into WP at July, 2009 meeting.]</P>



<P>13.6 [over.built] paragraph 7 posits the existence of
built-in candidate <TT>operator*</TT> functions &#8220;for every
function type <I>T</I>.&#8221; However, only non-static member
function types can contain a <I>cv-qualifier</I> or
<I>ref-qualifier</I> (8.3.5 [dcl.fct] paragraph 7), and a
reference to such a type cannot be initialized (5.2.5 [expr.ref] paragraph 4, bullet 3, sub-bullet 2).  (See also
_N2914_.14.10.4 [concept.support] paragraph 10, which disallows references
to function types with <I>cv-qualifier</I>s but is silent on
<I>ref-qualifier</I>s.)</P>

<P><B>Proposed resolution (March, 2009):</B></P>

<OL><LI><P>Change 13.6 [over.built] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

For every function type <I>T</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">that does not have cv-qualifiers
or a <I>ref-qualifier</I></SPAN>, there exist candidate operator
functions of the form

<UL>
<I>T</I> <TT>&amp;   operator*(</TT>T<TT>*);</TT>
</UL>

</BLOCKQUOTE>

<LI><P>Change _N2914_.14.10.4 [concept.support] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

<I>Requires:</I> for every type <TT>T</TT> that is an object type, a
function type that does not have cv-qualifiers <SPAN style="font-weight:bold;background-color:#A0FFA0">or a
<I>ref-qualifier</I></SPAN>, or <I>cv</I> <TT>void</TT>, a concept map
<TT>PointeeType&lt;T&gt;</TT> is implicitly defined in namespace
<TT>std</TT>.

</BLOCKQUOTE>

<LI><P>Change _N2914_.14.10.4 [concept.support] paragraph 11 as follows:</P></LI>

<BLOCKQUOTE>

<I>Requires:</I> for every type <TT>T</TT> that is an object type, a
function type that does not have cv-qualifiers <SPAN style="font-weight:bold;background-color:#A0FFA0">or a
<I>ref-qualifier</I></SPAN>, or a reference type, a concept map
<TT>ReferentType&lt;T&gt;</TT> is implicitly defined in namespace
<TT>std</TT>.

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="879"></A><H4>879.
  
Missing built-in comparison operators for pointer types
</H4><B>Section: </B>13.6&#160; [over.built]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>25 April, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>13.6 [over.built] paragraph 15 restricts the built-in comparison
operators to</P>

<BLOCKQUOTE>

every <I>T</I>, where <I>T</I> is an enumeration type or pointer to
effective object type

</BLOCKQUOTE>

<P>This omits both pointers to function types and pointers to void.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<OL><LI><P>Add a new paragraph following 5.9 [expr.rel]
paragraph 2:</P></LI>

<BLOCKUOTE>

<SPAN style="font-weight:bold;background-color:#A0FFA0">Pointers to <TT>void</TT> (after pointer conversions) can be
compared, with a result defined as follows: If both pointers represent
the same address or are both the null pointer value, the result is
<TT>true</TT> if the operator is <TT>&lt;=</TT> or <TT>&gt;=</TT> and
<TT>false</TT> otherwise; otherwise the result is unspecified.</SPAN>

</BLOCKUOTE>

<LI><P>Change 5.10 [expr.eq] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...Pointers <SPAN style="text-decoration:line-through;background-color:#FFA0A0">to objects or functions</SPAN> of the same type (after
pointer conversions) can be compared for equality...

</BLOCKQUOTE>

<LI><P>Change 13.6 [over.built] paragraph 15 as follows:</P></LI>

For every <TT>T</TT>, where <TT>T</TT> is an enumeration type<SPAN style="text-decoration:line-through;background-color:#FFA0A0">
or</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">, a</SPAN> pointer <SPAN style="text-decoration:line-through;background-color:#FFA0A0">to effective object</SPAN> type,
<SPAN style="font-weight:bold;background-color:#A0FFA0">or <TT>std::nullptr_t</TT>,</SPAN> there exist candidate operator
functions of the form...

</OL>

<BR><BR><HR><A NAME="880"></A><H4>880.
  
Built-in conditional operator for scoped enumerations
</H4><B>Section: </B>13.6&#160; [over.built]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>25 April, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>13.6 [over.built] paragraphs 24-25 describe the imaginary built-in
conditional operator functions.  However, neither paragraph 24 (promoted
arithmetic types) nor 25 (pointer and pointer-to-member types) covers
scoped enumerations, whose values should be usable in conditional
expressions.</P>

<P>(See also <A HREF="
     cwg_defects.html#835">issue 835</A>.)</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 13.6 [over.built] paragraph 25 as follows:</P>

<BLOCKQUOTE>

<P>For every type <I>T</I>, where <I>T</I> is a pointer<SPAN style="font-weight:bold;background-color:#A0FFA0">,</SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN> pointer-to-member<SPAN style="font-weight:bold;background-color:#A0FFA0">, or scoped enumeration</SPAN>
type, there exist candidate operator functions of the form</P>

<PRE>
    <I>T</I>        operator?(bool, <I>T</I> , <I>T</I> );
</PRE>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="820"></A><H4>820.
  
Deprecation of <TT>export</TT>
</H4><B>Section: </B>14&#160; [temp]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>UK
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK115">N2800 comment
  UK&#160;115<BR></A>

<P>[Voted into WP at March, 2010 meeting as document N3065.]</P>

<P>
Exported
templates were a great idea that is generally understood to
have failed. In the decade since the standard was adopted,
only one implementation has appeared. No current vendors
appear interested in creating another. We tentatively
suggest this makes the feature ripe for deprecation. Our
main concern with deprecation is that it might turn out
that exported constrained templates become an important
compile-time optimization, as the constraints would be
checked once in the exported definition and not in each
translation unit consuming the exported declarations.
</P>

<P><B>Notes from the March, 2010 meeting:</B></P>

<P>It was decided to remove <TT>export</TT> altogether, rather than
deprecating it.</P>

<BR><BR><HR><A NAME="840"></A><H4>840.
  
Rvalue references as nontype template parameters
</H4><B>Section: </B>14.1&#160; [temp.param]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>13 March, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>Nontype template parameters are currently allowed to have rvalue
reference type (14.1 [temp.param] paragraph 4 bullet 3 just
says &#8220;reference,&#8221; not &#8220;lvalue
reference&#8221;). However, with the change of N2844 voted in (which
prohibits rvalue references from binding to lvalues), I can't think of
any way to specify a valid template argument for a parameter of rvalue
reference type.  If that's the case, should we restrict nontype
template parameters to lvalue reference types?</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 14.1 [temp.param] paragraph 4, bullet 3 as follows:</P>

<UL><LI><SPAN style="font-weight:bold;background-color:#A0FFA0">lvalue</SPAN> reference to object or <SPAN style="font-weight:bold;background-color:#A0FFA0">lvalue</SPAN>
reference to function,</LI></UL>

<BR><BR><HR><A NAME="823"></A><H4>823.
  
Literal types with constexpr conversions as non-type template arguments
</H4><B>Section: </B>14.3.2&#160; [temp.arg.nontype]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>FR
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#FR29">N2800 comment
  FR&#160;29<BR></A>

<P>[Voted into WP at March, 2010 meeting.]</P>

<P>5.19 [expr.const] permits literal types with a <TT>constexpr</TT>
conversion function to an integral type to be used in an integral constant
expression.  However, such conversions are not listed in
14.3.2 [temp.arg.nontype] paragraph 5 bullet 1 among the conversions
applied to <I>template-argument</I>s for a non-type <I>template-parameter</I>
of integral or enumeration type.</P>

<P><B>Notes from the March, 2009 meeting:</B></P>

<P>The original national body comment suggested allowing any literal
type as a non-type template argument.  The CWG was not in favor of this
change, but in the course of discussing the suggestion discovered the
problem with <I>template-parameter</I>s of integral and enumeration
type.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 14.3.2 [temp.arg.nontype] paragraph 1 bullet 1 as follows:</P>

<UL><LI>an integral constant expression <SPAN style="font-weight:bold;background-color:#A0FFA0">(including a constant
expression of literal class type that can be used as an integral constant
expression as described in 5.19 [expr.const])</SPAN>; or</LI></UL>

<BR><BR><HR><A NAME="744"></A><H4>744.
  
Matching template arguments with template template parameters with parameter packs
</H4><B>Section: </B>14.3.3&#160; [temp.arg.template]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Faisal Vali
 &#160;&#160;&#160;

 <B>Date: </B>2 November, 2008<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>According to 14.3.3 [temp.arg.template] paragraph 3,</P>

<BLOCKQUOTE>

A <I>template-argument</I> matches a template <I>template-parameter</I> (call it <TT>P</TT>)
when each of the template parameters in the <I>template-parameter-list</I> of
the <I>template-argument</I>'s corresponding class template or template
alias (call it <TT>A</TT>) matches the corresponding template parameter in the
<I>template-parameter-list</I> of <TT>P</TT>. When <TT>P</TT>'s
<I>template-parameter-list</I> contains a template parameter pack
(14.5.3 [temp.variadic]), the template parameter pack will match
zero or more template parameters or template parameter packs in the
<I>template-parameter-list</I> of <TT>A</TT> with the same type and
form as the template parameter pack in <TT>P</TT> (ignoring whether
those template parameters are template parameter packs).

</BLOCKQUOTE>

<P>The immediately-preceding example, however, assumes that a parameter
pack in the parameter will match only a parameter pack in the argument:</P>

<PRE>
    template&lt;class T&gt; class A { /* ... */ };
    template&lt;class T, class U = T&gt; class B { /* ... */ };
    template&lt;class ... Types&gt; class C { /* ... */ };

    template&lt;template&lt;class ...&gt; class Q&gt; class Y { /* ... */ };

    Y&lt;A&gt; ya;  //<SPAN style="font-family:Times;font-style:italic"> ill-formed: a template parameter pack does not match a template parameter</SPAN>
    Y&lt;B&gt; yb;  //<SPAN style="font-family:Times;font-style:italic"> ill-formed: a template parameter pack does not match a template parameter</SPAN>
    Y&lt;C&gt; yc;  //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
</PRE>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change the final three lines of the second example in
14.3.3 [temp.arg.template] paragraph 2 as follows:</P>

<PRE>
    Y&lt;A&gt; ya;  //<SPAN style="font-family:Times;font-style:italic"> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">ill-formed: a template parameter pack does not match a template parameter</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">OK</SPAN></SPAN>
    Y&lt;B&gt; yb;  //<SPAN style="font-family:Times;font-style:italic"> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">ill-formed: a template parameter pack does not match a template parameter</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">OK</SPAN></SPAN>
    Y&lt;C&gt; yc;  //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
</PRE>

<BR><BR><HR><A NAME="408"></A><H4>408.
  
sizeof applied to unknown-bound array static data member of template
</H4><B>Section: </B>14.5.1.3&#160; [temp.static]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Nathan Myers
 &#160;&#160;&#160;

 <B>Date: </B>14 Apr 2003<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>Is this allowed?</P>
<PRE>
  template&lt;typename T&gt; 
    struct X
    {
        static int s[];
        int c;
    };

  template&lt;typename T&gt;
    int X&lt;T&gt;::s[sizeof(X&lt;T&gt;)];

  int* p = X&lt;char&gt;::s;
</PRE>

<P>I have a compiler claiming that, for the purpose of sizeof(), X&lt;T&gt; is 
an incomplete type, when it tries to instantiate X&lt;T&gt;::s.  It seems to 
me that X&lt;char&gt; should be considered complete enough for sizeof even
though the size of s isn't known yet.</P>


<P><U>John Spicer:</U>
This is a problematic construct that is currently allowed but which I think 
should be disallowed.</P>

<P>I tried this with a number of compilers.
None of which did the right thing. 
The EDG front end accepts it, but gives X&lt;...&gt;::s the wrong size.</P>

<P>It appears that most compilers evaluate the
"declaration" part of the static 
data member definition only once when the definition is processed.  The 
initializer (if any) is evaluated for each instantiation.</P>

<P>This problem is solvable, and if it were
the only issue with incomplete arrays 
as template static data members, then it would make
sense to solve it, but there are other problems.</P>

<P>The first problem is that the size of the static data member is
only known if a template definition of the static data member is
present.  This is weird to start with, but it also means that sizes
would not be available in general for exported templates.</P>

<P>The second problem concerns the rules for specialization.  An explicit 
specialization for a template instance can be provided up until the
point that a use is made that would cause an implicit instantiation.
A reference like "sizeof(X&lt;char&gt;::s)" is not currently a reference
that would cause an implicit instantiation of X&lt;char&gt;::s.
This means you could use such a sizeof and later 
specialize the static data member with a different size, meaning the earlier 
sizeof gave the wrong result.  We could, of course, change the "use"
rules, but I'd rather see us require that static data members that
are arrays have a size specified in the class or have a size based
on their initializer.</P>

<P><B>Notes from the October 2003 meeting:</B></P>

<P>The example provided is valid according to the current
standard.  A static data member must be
instantiated (including the processing of its initializer, if any)
if there is any reference to it.  The compiler need not, however, put out
a definition in that translation unit.  The standard doesn't really
have a concept of a "partial instantiation" for a static data
member, and although we considered adding that, we decided that
to get all the size information that seems to be available one
needs a full instantiation in any case, so there's no need
for the concept of a partial instantiation.</P>

<P><B>Note (June, 2006):</B></P>

<P>Mark Mitchell suggested the following example:</P>

<PRE>
    template &lt;int&gt; void g();

    template &lt;typename T&gt;
    struct S {
      static int i[];
      void f();
    };

    template &lt;typename T&gt;
    int S&lt;T&gt;::i[] = { 1 };

    template &lt;typename T&gt;
    void S&lt;T&gt;::f() {
      g&lt;sizeof (i) / sizeof (int)&gt;();
    }

    template &lt;typename T&gt;
    int S&lt;int&gt;::i[] = { 1, 2 };
</PRE>

<P>Which <TT>g</TT> is called from <TT>S&lt;int&gt;::f()</TT>?</P>

<P>If the program is valid, then surely one would
expect <TT>g&lt;2&gt;</TT> to be called.</P>

<P>If the program is valid, does <TT>S&lt;T&gt;::i</TT> have a
non-dependent type in <TT>S&lt;T&gt;::f</TT>?  If so, is it
incomplete, or is it <TT>int[1]</TT>?  (Here, <TT>int[1]</TT> would be
surprising, since <TT>S&lt;int&gt;::i</TT> actually has
type <TT>int[2]</TT>.)</P>

<P>If the program is invalid, why?</P>

<P>For a simpler example, consider:</P>

<PRE>
    template &lt;typename T&gt;
    struct S {
      static int i[];
      const int N = sizeof (i);
    };
</PRE>

<P>This is only valid if the type of <TT>i</TT> is dependent,
meaning that the <TT>sizeof</TT> expression isn't evaluated until
the class is instantiated.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<OL><LI><P>Add the following as a new paragraph following
14.5.1.3 [temp.static] paragraph 1:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">An explicit specialization of a static data member declared as
an array of unknown bound can have a different bound from its
definition, if any. [<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  template&lt;class T&gt; struct A {
    static int i[];
  };
  template&lt;class T&gt; int A&lt;T&gt;::i[4];    //<SPAN style="font-family:Times;font-style:italic"> 4 elements</SPAN>
  template&lt;&gt; int A&lt;int&gt;::i[] = { 1 };  //<SPAN style="font-family:Times;font-style:italic"> 1 element, OK</SPAN></SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

<LI><P>Change 14.6.2.2 [temp.dep.expr] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

<P>An <I>id-expression</I> is type-dependent if it contains<SPAN style="text-decoration:line-through;background-color:#FFA0A0">:</SPAN></P>

<UL><LI><P>an <I>identifier</I> that was declared with a
dependent type,</P></LI>

<LI><P>a <I>template-id</I> that is dependent,</P></LI>

<LI><P>a <I>conversion-function-id</I> that specifies a dependent
type, <SPAN style="font-weight:bold;background-color:#A0FFA0">or</SPAN></P></LI>

<LI><P>a <I>nested-name-specifier</I> or a <I>qualified-id</I>
that names a member of an unknown
specialization<SPAN style="text-decoration:line-through;background-color:#FFA0A0">.</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">;</SPAN></P></LI>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">or if it names a static data member of the current
instantiation that has type &#8220;array of unknown bound of
<TT>T</TT>&#8221; for some <TT>T</TT> (14.5.1.3 [temp.static]).</SPAN> Expressions of the following forms are
type-dependent only if...</P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="638"></A><H4>638.
  
Explicit specialization and friendship
</H4><B>Section: </B>14.5.4&#160; [temp.friend]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>6 July 2007<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>Is this code well-formed?</P>

<PRE>
    template &lt;typename T&gt; struct A {
        struct B;
    };

    class C {
        template &lt;typename T&gt; friend struct A&lt;T&gt;::B;
        static int bar;
    };

    template &lt;&gt; struct A&lt;char&gt; {
        struct B {
            int f() {
                return C::bar;   // Is A&lt;char&gt;::B a friend of C?
            }
        };
    };
</PRE>

<P>According to 14.5.4 [temp.friend] paragraph 5,</P>

<BLOCKQUOTE>

A member of a class template may be declared to be a friend of a
non-template class. In this case, the corresponding member of
every specialization of the class template is a friend of the
class granting friendship.

</BLOCKQUOTE>

<P>This would tend to indicate that the example is well-formed.
However, technically <TT>A&lt;char&gt;::B</TT> does not
&#8220;correspond to&#8221; the same-named member of the class
template: 14.7.3 [temp.expl.spec] paragraph 4 says,</P>

<BLOCKQUOTE>

The definition of an explicitly specialized class is unrelated to
the definition of a generated specialization.  That is, its
members need not have the same names, types, etc. as the members
of a generated specialization.

</BLOCKQUOTE>

<P>In other words, there are no &#8220;corresponding members&#8221;
in an explicit specialization.</P>

<P>Is this the outcome we want for examples like the preceding?
There is diversity among implementations on this question, with some
accepting the example and others rejecting it as an access violation.</P>

<P><B>Notes from the July, 2009 meeting:</B></P>

<P>The consensus of the CWG was to allow the correspondence of similar
members in explicit specializations.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 14.5.4 [temp.friend] paragraph 5 as follows:</P>

<BLOCKQUOTE>

<P>A member of a class template may be declared to be a friend of a
non-template class.  In this case, the corresponding member of every
specialization of the class template is a friend of the class granting
friendship. <SPAN style="font-weight:bold;background-color:#A0FFA0">For explicit specializations the corresponding member
is the member (if any) that has the same name, kind (type, function,
class template or function template), template parameters, and
signature as the member of the class template instantiation that would
otherwise have been generated.</SPAN> [<I>Example:</I></P>

<PRE>
  template&lt;class T&gt; struct A {
    struct B { };
    void f();
<SPAN style="font-weight:bold;background-color:#A0FFA0">    struct D {
      void g();
    };</SPAN>
  };
<SPAN style="font-weight:bold;background-color:#A0FFA0">  template&lt;&gt; struct A&lt;int&gt; {
    struct B { };
    int f();
    struct D {
      void g();
    };
  };</SPAN>

  class C {
    template&lt;class T&gt; friend struct A&lt;T&gt;::B;    <SPAN style="font-weight:bold;background-color:#A0FFA0">//<SPAN style="font-family:Times;font-style:italic"> grants friendship to </SPAN>A&lt;int&gt;::B<SPAN style="font-family:Times;font-style:italic"> even though</SPAN>
                                                //<SPAN style="font-family:Times;font-style:italic"> it is not a specialization of </SPAN>A&lt;T&gt;::B</SPAN>
    template&lt;class T&gt; friend void A&lt;T&gt;::f();    <SPAN style="font-weight:bold;background-color:#A0FFA0">//<SPAN style="font-family:Times;font-style:italic"> does not grant friendship to </SPAN>A&lt;int&gt;::f()
                                                //<SPAN style="font-family:Times;font-style:italic"> because its return type does not match</SPAN></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">    template&lt;class T&gt; friend void A&lt;T&gt;::D::g(); //<SPAN style="font-family:Times;font-style:italic"> does not grant friendship to </SPAN>A&lt;int&gt;::D::g()
                                                //<SPAN style="font-family:Times;font-style:italic"> because </SPAN>A&lt;int&gt;::D<SPAN style="font-family:Times;font-style:italic"> is not a specialization of </SPAN>A&lt;T&gt;::D</SPAN>
  };
</PRE>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="929"></A><H4>929.
  
What is a template alias?
</H4><B>Section: </B>14.5.7&#160; [temp.alias]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>2 July, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>Although it is a reasonable assumption that a
<I>template-declaration</I> in which the <I>declaration</I> is an
<I>alias-declaration</I> declares a template alias, that is not said
explicitly in 14.5.7 [temp.alias] nor, apparently, anywhere
else.</P>

<P><B>Proposed resolution (September, 2009):</B></P>

<P>Change 14.5.7 [temp.alias] paragraph 1 as follows:</P>

<BLOCKQUOTE>

<SPAN style="font-weight:bold;background-color:#A0FFA0">A <I>template-declaration</I> in which the <I>declaration</I> is
an <I>alias-declaration</I> (clause 7) declares the <I>identifier</I>

to be a <I>template alias.</I></SPAN> A <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>template alias</I>
declares</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">template alias is</SPAN> a name for a family of
types. The name of the template alias is a <I>template-name</I>.

</BLOCKQUOTE>



<BR><BR><HR><A NAME="588"></A><H4>588.
  
Searching dependent bases of classes local to function templates
</H4><B>Section: </B>14.6.2&#160; [temp.dep]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>James Widman
 &#160;&#160;&#160;

 <B>Date: </B>21 June 2006<BR>


<P>[Voted into the WP at the March, 2009 meeting.]</P>



<P>14.6.2 [temp.dep] paragraph 3 reads,</P>

<BLOCKQUOTE>

In the definition of a class template or a member of a class template,
if a base class of the class template depends on
a <I>template-parameter</I>, the base class scope is not examined
during unqualified name lookup either at the point of definition of
the class template or member or during an instantiation of the class
template or member.

</BLOCKQUOTE>

<P>This wording applies only to definitions of class templates and
members of class templates.  That would make the following program
ill-formed (but it probably should be well-formed):</P>

<PRE>
    struct B{ void f(int); };

    template&lt;class T&gt; struct D: B { };

    template&lt;class T&gt; void g() {
       struct B{ void f(); };
       struct A: D&lt;T&gt; {
           B m;
       };
       A a;
       a.m.f(); //<SPAN style="font-family:Times;font-style:italic"> Presumably, we want </SPAN>::g()::B::f()<SPAN style="font-family:Times;font-style:italic">, not </SPAN>::B::f(int)
    }

    int main () {
       g&lt;int&gt;();
       return 0;
    }
</PRE>

<P>I suspect the wording should be something like</P>

<BLOCKQUOTE>

In the definition of a class template <SPAN style="font-weight:bold;background-color:#A0FFA0">or a class defined
(directly or indirectly) within the scope of a class template or
function template</SPAN>, if a base class...

</BLOCKQUOTE>

<P>That should also include deeply nested classes in templates, local
classes of non-template member functions of member classes of class
templates, etc.</P>

<P><B>Proposed resolution (October, 2006):</B></P>

<P>Change 14.6.2 [temp.dep] paragraph 3 as follows:</P>

<BLOCKQUOTE>

In the definition of a <SPAN style="font-weight:bold;background-color:#A0FFA0">class or</SPAN> class template <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or a member
of a class template</SPAN>, if a base class <SPAN style="text-decoration:line-through;background-color:#FFA0A0">of the class template</SPAN>
depends on a <I>template-parameter</I>, the base class scope is not
examined during unqualified name lookup either at the point of
definition of the class template or member or during an instantiation
of the class template or member.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="541"></A><H4>541.
  
Dependent function types
</H4><B>Section: </B>14.6.2.2&#160; [temp.dep.expr]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>22 October 2005<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>14.6.2.2 [temp.dep.expr] paragraph 3 says,</P>

<BLOCKQUOTE>

An <I>id-expression</I> is type-dependent if it contains:

<UL><LI>an identifier that was declared with a dependent type...</LI></UL>

</BLOCKQUOTE>

<P>This treatment seems inadequate with regard to
<I>id-expression</I>s in function calls:</P>

<OL>

<LI><P>According to 14.6.2.1 [temp.dep.type] paragraph 6,</P>

<BLOCKQUOTE>

A type is dependent if it is

<UL>

<LI>...</LI>

<LI>a compound type constructed from any dependent type...</LI>

</UL>

</BLOCKQUOTE>

<P>This would apply to the type of a member function of a class
template if any of its parameters are dependent, even if the return
type is not dependent.  However, there is no need for a call to such a
function to be a type-dependent expression because the type of the
expression is known at definition time.</P>

</LI>

<LI><P>This wording does not handle the case of overloaded functions,
some of which might have dependent types (however defined) and others
not.</P>

</LI>

</OL>

<P><B>Notes from the October, 2009 meeting:</B></P>

<P>The consensus of the CWG was that the first point of the issue
is not sufficiently problematic as to require a change.</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 14.6.2.2 [temp.dep.expr] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<P>An <I>id-expression</I> is type-dependent if it contains:</P>

<UL><LI><P>an <I>identifier</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">that was</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">associated by
name lookup with one or more declarations</SPAN> declared with a
dependent type,</P></LI>

<LI><P>a <I>template-id</I> that is dependent,</P></LI>

<LI><P>a <I>conversion-function-id</I> that specifies a dependent
type, <SPAN style="font-weight:bold;background-color:#A0FFA0">or</SPAN></P></LI>

<LI><P>a <I>nested-name-specifier</I> or a <I>qualified-id</I> that
names a member of an unknown specialization.</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="561"></A><H4>561.
  
Internal linkage functions in dependent name lookup
</H4><B>Section: </B>14.6.4.2&#160; [temp.dep.candidate]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Joaqu&#237;n L&#243;pez Mu&#241;oz
 &#160;&#160;&#160;

 <B>Date: </B>17 February 2006<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>According to 14.6.4.2 [temp.dep.candidate],</P>

<BLOCKQUOTE>

<P>For a function call that depends on a template parameter, if the
function name is an <I>unqualified-id</I> but not
a <I>template-id</I>, the candidate functions are found using the
usual lookup rules (3.4.1 [basic.lookup.unqual], 3.4.2 [basic.lookup.argdep]) except that:</P>

<UL>
<LI><P>For the part of the lookup using unqualified name lookup
(3.4.1 [basic.lookup.unqual]), only function declarations with
external linkage from the template definition context are
found.</P></LI>

<LI><P>For the part of the lookup using associated namespaces
(3.4.2 [basic.lookup.argdep]), only function declarations with
external linkage found in either the template definition context or
the template instantiation context are found.</P></LI>
</UL>

</BLOCKQUOTE>

<P>It is not at all clear why a call using a <I>template-id</I>
would be treated differently from one not using a <I>template-id</I>.
Furthermore, is it really necessary to exclude internal linkage
functions from the lookup?  Doesn't the ODR give implementations
sufficient latitude to handle this case without another wrinkle
on name lookup?</P>

<P>(See also <A HREF="
     cwg_defects.html#524">issue 524</A>.)</P>

<P><B>Notes from the April, 2006 meeting:</B></P>

<P>The consensus of the group was that <I>template-id</I>s should not
be treated differently from <I>unqualified-id</I>s (although it's not
clear how argument-dependent lookup works for <I>template-id</I>s),
and that internal-linkage functions should be found by the lookup
(although they may result in errors if selected by overload
resolution).</P>

<P><B>Note (June, 2006):</B></P>

<P>Although the notes from the Berlin meeting indicate that
argument-dependent lookup for <I>template-id</I>s is under-specified
in the Standard, further examination indicates that that is not the
case: the note in 14.8.1 [temp.arg.explicit] paragraph 8 clearly
indicates that argument-dependent lookup is to be performed for
<I>template-id</I>s, and 3.4.2 [basic.lookup.argdep] paragraph 4
describes the lookup performed:</P>

<BLOCKQUOTE>

When considering an associated namespace, the lookup is the same as
the lookup performed when the associated namespace is used as a
qualifier (3.4.3.2 [namespace.qual]) except that:

<UL>

<LI><P>Any <I>using-directive</I>s in the associated namespace are
ignored.</P></LI>

<LI><P>Any namespace-scope friend functions declared in associated
classes are visible within their respective namespaces even if they
are not visible during an ordinary lookup (11.3 [class.friend]).</P></LI>

</UL>

</BLOCKQUOTE>

<P><B>Proposed resolution (October, 2009):</B></P>

<OL><LI><P>Change 14.6.2 [temp.dep] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<P>In an expression of the form:</P>

<UL><I>postfix-expression</I> <TT>(</TT> <I>expression-list<SUB>opt</SUB></I> <TT>)</TT></UL>

<P>where the <I>postfix-expression</I> is an
<I>unqualified-id</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">but not a <I>template-id</I></SPAN>, the
<I>unqualified-id</I> denotes a <I>dependent name</I> if and only if
any of the expressions in the <I>expression-list</I> is a
type-dependent expression (14.6.2.2 [temp.dep.expr])...</P>

</BLOCKQUOTE>

<LI><P>Change 14.6.4.2 [temp.dep.candidate] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<P>For a function call that depends on a template parameter, if the
function name is an <I>unqualified-id</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">but not a
<I>template-id</I></SPAN>, or if the function is called using operator
notation, the candidate functions are found using the usual lookup
rules (3.4.1 [basic.lookup.unqual], 3.4.2 [basic.lookup.argdep]) except
that:</P>

<UL><LI><P>For the part of the lookup using unqualified name lookup
(3.4.1 [basic.lookup.unqual]), only function declarations <SPAN style="text-decoration:line-through;background-color:#FFA0A0">with
external linkage</SPAN> from the template definition context are
found.</P></LI>

<LI><P>For the part of the lookup using associated namespaces
(3.4.2 [basic.lookup.argdep]), only function declarations <SPAN style="text-decoration:line-through;background-color:#FFA0A0">with
external linkage</SPAN> found in either the template definition context
or the template instantiation context are found.</P></LI>

</UL>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="969"></A><H4>969.
  
Explicit instantiation declarations of class template specializations
</H4><B>Section: </B>14.7.2&#160; [temp.explicit]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>29 December, 2008<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>Consider this example:</P>

<PRE>
    template &lt;class T&gt; struct A {
       virtual void f() {}
    };

    extern template struct A&lt;int&gt;;

    int main() {
       A&lt;int&gt; a;
       a.f();
    }
</PRE>

<P>The intent is that the explicit instantiation declaration will
suppress any compiler-generated machinery such as a virtual function
table or typeinfo data in this translation unit, and that because of
14.7.2 [temp.explicit] paragraph 10,</P>

<BLOCKQUOTE>

An entity that is the subject of an explicit instantiation declaration
and that is also used in the translation unit shall be the subject of
an explicit instantiation definition somewhere in the program;
otherwise the program is ill-formed, no diagnostic required.

</BLOCKQUOTE>

<P>the use of <TT>A&lt;int&gt;</TT> in declaring <TT>a</TT> requires
an explicit instantiation definition in another translation unit that
will provide the requisite compiler-generated data.</P>

<P>The existing wording of 14.7.2 [temp.explicit] does not
express this intent clearly enough, however.</P>

<P><U>Suggested resolution:</U></P>

<OL><LI><P>Change 14.7.2 [temp.explicit] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

An explicit instantiation that names a class template specialization
is <SPAN style="font-weight:bold;background-color:#A0FFA0">also</SPAN> an explicit instantion of the same kind
(declaration or definition) of each of its members (not including
members inherited from base classes) that has not been previously
explicitly specialized in the translation unit containing the explicit
instantiation, except as described below.

</BLOCKQUOTE>

<LI><P>Change 14.7.2 [temp.explicit] paragraph 9 as follows:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">An explicit instantiation declaration that names a class template
specialization has no effect on the class template specialization
itself (except for perhaps resulting in its implicit
instantiation).</SPAN> Except for inline functions <SPAN style="font-weight:bold;background-color:#A0FFA0">and class
template specializations</SPAN>, other explicit instantiation
declarations have the effect of suppressing the implicit instantiation
of the entity to which they refer...

</BLOCKQUOTE>

</OL>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 14.7.2 [temp.explicit] paragraphs 7-9 as follows:</P>

<BLOCKQUOTE>

<P>An explicit instantiation that names a class template
specialization is <SPAN style="font-weight:bold;background-color:#A0FFA0">also</SPAN> an explicit instantion of the same
kind (declaration or definition) of each of its members (not including
members inherited from base classes) that has not been previously
explicitly specialized in the translation unit containing the explicit
instantiation, except as described below. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> In
addition, it will typically be an explicit instantiation of certain
implementation-dependent data about the class. &#8212;<I>end
note</I>]</SPAN></P>

<P>An explicit instantiation definition that names a class template
specialization explicitly instantiates the class template
specialization and is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">only</SPAN> an explicit instantiation
definition of <SPAN style="font-weight:bold;background-color:#A0FFA0">only those</SPAN> members whose definition is
visible at the point of instantiation.</P>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">An explicit instantiation declaration that names a class
template specialization has no effect on the class template
specialization itself (except for perhaps resulting in its implicit
instantiation).</SPAN> Except for inline functions <SPAN style="font-weight:bold;background-color:#A0FFA0">and class
template specializations</SPAN>, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">other</SPAN> explicit
instantiation declarations have the effect of suppressing the implicit
instantiation of the entity to which they refer...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="980"></A><H4>980.
  
Explicit instantiation of a member of a class template
</H4><B>Section: </B>14.7.2&#160; [temp.explicit]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Doug Gregor
 &#160;&#160;&#160;

 <B>Date: </B>14 October, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>14.7.2 [temp.explicit] paragraph 1 says,</P>

<BLOCKQUOTE>

An explicit instantiation of a function template shall not
use the <TT>inline</TT> or <TT>constexpr</TT> specifiers.

</BLOCKQUOTE>

<P>This wording should be revised to apply to member functions of
class templates as well.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 14.7.2 [temp.explicit] paragraph 1 as follows:</P>

<BLOCKQUOTE>

...An explicit instantiation of a function template <SPAN style="font-weight:bold;background-color:#A0FFA0">or
member function of a class template</SPAN> shall not use the
<TT>inline</TT> or <TT>constexpr</TT> specifiers.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="995"></A><H4>995.
  
Incorrect example for <I>using-declaration</I> and explicit instantiation
</H4><B>Section: </B>14.7.2&#160; [temp.explicit]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Doug Gregor
 &#160;&#160;&#160;

 <B>Date: </B>27 Oct, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>14.7.2 [temp.explicit] paragraph 5 has an example that reads,
in significant part,</P>

<PRE>
    namespace N {
      template&lt;class T&gt; class Y {
        void mf() { }
      };
    }

    using N::Y;
    template class Y&lt;int&gt;; // OK: explicit instantiation in namespace N
</PRE>

<P>In fact, paragraph 2 requires that an explicit instantiation with an
unqualified name must appear in the same namespace in which the template
was declared, so the example is ill-formed.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change the example in 14.7.2 [temp.explicit] paragraph 5 as
follows:</P>

<PRE>
  namespace N {
    template&lt;class T&gt; class Y { void mf() { } };
  }

  template class Y&lt;int&gt;;            //<SPAN style="font-family:Times;font-style:italic"> error: class template </SPAN>Y<SPAN style="font-family:Times;font-style:italic"> not visible</SPAN>
                                    //<SPAN style="font-family:Times;font-style:italic"> in the global namespace</SPAN>

  using N::Y;
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">  template class Y&lt;int&gt;;            //<SPAN style="font-family:Times;font-style:italic"> OK: explicit instantiation in namespace </SPAN>N</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  template class Y&lt;int&gt;;            //<SPAN style="font-family:Times;font-style:italic"> error: explicit instantiation outside of the</SPAN>
                                    //<SPAN style="font-family:Times;font-style:italic"> namespace of the template</SPAN></SPAN>

  template class N::Y&lt;char*&gt;;       //<SPAN style="font-family:Times;font-style:italic"> OK: explicit instantiation in namespace </SPAN>N
  template void N::Y&lt;double&gt;::mf(); //<SPAN style="font-family:Times;font-style:italic"> OK: explicit instantiation</SPAN>
                                    //<SPAN style="font-family:Times;font-style:italic"> in namespace </SPAN>N
</PRE>

<BR><BR><HR><A NAME="730"></A><H4>730.
  
Explicit specializations of members of non-template classes
</H4><B>Section: </B>14.7.3&#160; [temp.expl.spec]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Bronek Kozicki
 &#160;&#160;&#160;

 <B>Date: </B>3 October, 2008<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#DE14">N2800 comment
  DE&#160;14<BR></A>

<P>[Voted into WP at October, 2009 meeting.]</P>



<P>The list of entities that can be explicitly specialized in
14.7.3 [temp.expl.spec] paragraph 1 includes member templates of
class templates but not member templates of non-template classes.
This omission could lead to the conclusion that such member templates
cannot be explicitly specialized.  (Note, however, that paragraph 3
refers to &#8220;an explicit specialization for a member template of
[a] class or class template.&#8221;)</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 14.7.3 [temp.expl.spec] paragraph 1 as follows:</P>

<BLOCKQUOTE>

<P>An explicit specialization of any of the following:</P>

<UL><LI><P>...</P></LI>

<LI><P>member class template of a <SPAN style="font-weight:bold;background-color:#A0FFA0">class or</SPAN> class
template</P></LI>

<LI><P>non-deleted member function template of a <SPAN style="font-weight:bold;background-color:#A0FFA0">class or</SPAN>
class template</P></LI>

</UL>

<P>can be declared...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="884"></A><H4>884.
  
Defining an explicitly-specialized static data member
</H4><B>Section: </B>14.7.3&#160; [temp.expl.spec]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>29 April, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>14.7.3 [temp.expl.spec] paragraphs 15-16 contain the following
note:</P>

<BLOCKQUOTE>

[<I>Note:</I> there is no syntax for the definition of a static data
member of a template that requires default initialization.

<PRE>
    template&lt;&gt; X Q&lt;int&gt;::x;
</PRE>

This is a declaration regardless of whether <TT>X</TT> can be default
initialized (8.5 [dcl.init]). &#8212;<I>end note</I>]

</BLOCKQUOTE>

<P>While this note is still accurate, the C++0x list initialization
syntax provides a way around the restriction, which could be useful
if the class is not copyable or movable but has a default constructor.
Perhaps the note should be updated to mention that possibility?</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 14.7.3 [temp.expl.spec] paragraphs 15-16 as follows:</P>

<BLOCKQUOTE>

<P>An explicit specialization of a static data member of a template is
a definition if the declaration includes an initializer; otherwise, it
is a declaration. [<I>Note:</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">there is no syntax for the</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">The</SPAN> definition of a static data member of a template that
requires default initialization<SPAN style="text-decoration:line-through;background-color:#FFA0A0">.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">must use a
<I>braced-init-list:</I></SPAN></P>

<PRE>
  template&lt;&gt; X Q&lt;int&gt;::x;<SPAN style="font-weight:bold;background-color:#A0FFA0">      //<SPAN style="font-family:Times;font-style:italic"> declaration</SPAN>
  template&lt;&gt; X Q&lt;int&gt;::x ();   //<SPAN style="font-family:Times;font-style:italic"> error: declares a function</SPAN>
  template&lt;&gt; X Q&lt;int&gt;::x {};   //<SPAN style="font-family:Times;font-style:italic"> definition</SPAN></SPAN>
</PRE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">This is a declaration regardless of whether <TT>X</TT> can be
default initialized (8.5 [dcl.init]).</SPAN> &#8212;<I>end
note</I>]</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="923"></A><H4>923.
  
Inline explicit specializations
</H4><B>Section: </B>14.7.3&#160; [temp.expl.spec]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>19 June, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>According to 14.7.3 [temp.expl.spec] paragraph 14,</P>

<BLOCKQUOTE>

An explicit specialization of a function template is inline only if it
is explicitly declared to be...

</BLOCKQUOTE>

<P>This could be read to require that the <TT>inline</TT> keyword must
appear in the declaration.  However, 8.4 [dcl.fct.def]
paragraph 10 says that a deleted function is implicitly inline, so it
should be made clear that defining an explicit specialization as
deleted makes it inline.</P>

<P><B>Proposed resolution (November, 2009):</B></P>

<P>Change 14.7.3 [temp.expl.spec] paragraph 14 as follows:</P>

<BLOCKQUOTE>

An explicit specialization of a function template is inline only if it
is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">explicitly</SPAN> declared <SPAN style="text-decoration:line-through;background-color:#FFA0A0">to be</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">with the
<TT>inline</TT> specifier or defined as deleted</SPAN>, and
independently of whether its function template is
<SPAN style="font-weight:bold;background-color:#A0FFA0">inline</SPAN>. [<I>Example:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="657"></A><H4>657.
  
Abstract class parameter in synthesized declaration
</H4><B>Section: </B>14.8.2&#160; [temp.deduct]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>31 October 2007<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>A customer of ours recently brought the following example to
our attention.  There's some question as to whether the
Standard adequately addresses this example, and if it does,
whether the outcome is what we'd like to see.  Here's the
example:</P>

<PRE>
    struct Abs {
      virtual void x() = 0;
    };

    struct Der: public Abs {
      virtual void x();
    };

    struct Cnvt {
      template &lt;typename F&gt; Cnvt(F);
    };

    void foo(Cnvt a);
    void foo(Abs &amp;a);

    void f() {
      Der d;
      Abs *a = &amp;d;
      foo(*a);        //<SPAN style="font-family:Times;font-style:italic"> #1</SPAN>
      return 0;
    }
</PRE>

<P>The question is how to perform overload resolution for the call at
#1.  To do that, we need to determine whether <TT>foo(Cnvt)</TT> is a
viable function.  That entails deciding whether there is an implicit
conversion sequence that converts <TT>Abs</TT> (the type
of <TT>*a</TT> in the call) to <TT>Cnvt</TT> (13.3.2 [over.match.viable] paragraph 3), and that involves a recursive invocation
of overload resolution.</P>

<P>The initialization of the parameter of <TT>foo(Cnvt)</TT> is a case
of copy-initialization of a class by user-defined conversion, so the
candidate functions are the converting constructors of <TT>Cnvt</TT>
(13.3.1.4 [over.match.copy] paragraph 1), of which there are two:
the implicitly-declared copy constructor and the constructor
template.</P>

<P>According to 14.7.1 [temp.inst] paragraph 8,</P>

<BLOCKQUOTE>

If a function template or a member function template specialization is
used in a way that involves overload resolution, a declaration of the
specialization is implicitly instantiated (14.8.3 [temp.over]).

</BLOCKQUOTE>

<P>Template argument deduction results in &#8220;synthesizing&#8221;
(14.8.3 [temp.over] paragraph 1) (or &#8220;instantiating,&#8221; 14.7.1 [temp.inst] paragraph 8) the declaration</P>

<PRE>
    Cnvt::Cnvt(Abs)
</PRE>

<P>Because <TT>Abs</TT> is an abstract class, this declaration
violates the restriction of 10.4 [class.abstract] paragraph 3
(&#8220;An abstract class shall not be used as a parameter
type...&#8221;), and because a parameter of an abstract class type
does not cause a deduction failure (it's not in the bulleted list in
14.8.2 [temp.deduct] paragraph 2), the program is ill-formed.
This error is reported by both EDG and Microsoft compilers, but not by
g++.</P>

<P>It seems unfortunate that the program would be rendered
ill-formed by a semantic violation in a declaration synthesized
solely for the purpose of overload resolution analysis;
<TT>foo(Cnvt)</TT> would not be selected by overload resolution, so
<TT>Cnvt::Cnvt(Abs)</TT> would not be instantiated.</P>

<P>There's at least some indication that a parameter with an
abstract class type should be a deduction failure; an array
element of abstract class type is a deduction failure, so one
might expect that a parameter would be, also.</P>

<P>(See also <A HREF="
     cwg_defects.html#339">issue 339</A>; this question
might be addressed as part of the direction described in the notes
from the July, 2007 meeting.)</P>

<P><B>Notes from the June, 2008 meeting:</B></P>

<P>Paper N2634, adopted at the June, 2008 meeting, replaces the
normative list of specific errors accepted as deduction failures
by a general statement covering all &#8220;invalid types and
expressions in the immediate context of the function type and its
template parameter types,&#8221; so the code is now
well-formed. However, the previous list is now a note, and the
note should be updated to mention this case.
</P>

<P><B>Proposed resolution (August, 2008):</B></P>

<P>Add a new bullet following the last bullet of the note in
14.8.2 [temp.deduct] paragraph 8 as follows:</P>

<UL><LI><P>Attempting to create a function type in which a
parameter type or the return type is an abstract class type
(10.4 [class.abstract]).</P></LI></UL>

<BR><BR><HR><A NAME="847"></A><H4>847.
  
Error in rvalue reference deduction example
</H4><B>Section: </B>14.8.2.1&#160; [temp.deduct.call]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>27 March, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>The adoption of paper N2844 made it ill-formed to attempt to bind an
rvalue reference to an lvalue.  However, the example in
14.8.2.1 [temp.deduct.call] paragraph 3 still reflects the previous
specification:</P>

<PRE>
    template &lt;typename T&gt; int f(T&amp;&amp;);
    int i;
    int j = f(i);        //<SPAN style="font-family:Times;font-style:italic"> calls </SPAN>f&lt;int&amp;&gt;(i)
    template &lt;typename T&gt; int g(const T&amp;&amp;);
    int k;
    int n = g(k);        //<SPAN style="font-family:Times;font-style:italic"> calls </SPAN>g&lt;int&gt;(k)
</PRE>

<P>The last line of that example is now ill-formed, attempting to bind
the <TT>const int&amp;&amp;</TT> parameter of <TT>g</TT> to the lvalue
<TT>k</TT>.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Replace the example in 14.8.2.1 [temp.deduct.call] paragraph 3 with:</P>

<PRE>
    template&lt;typename T&gt; int f(T&amp;&amp;);
    template&lt;typename T&gt; int g(const T&amp;&amp;);
    int i;
    int n1 = f(i);    //<SPAN style="font-family:Times;font-style:italic"> calls </SPAN>f&lt;int&amp;&gt;(int&amp;)
    int n2 = f(0);    //<SPAN style="font-family:Times;font-style:italic"> calls </SPAN>f&lt;int&gt;(int&amp;&amp;)
    int n3 = g(i);    //<SPAN style="font-family:Times;font-style:italic"> error: would call </SPAN>g&lt;int&gt;(const int&amp;&amp;)<SPAN style="font-family:Times;font-style:italic">, which would</SPAN>
                      //<SPAN style="font-family:Times;font-style:italic"> bind an rvalue reference to an lvalue</SPAN>
</PRE>

<P>(See also <A HREF="
     cwg_defects.html#858">issue 858</A>.)</P>

<BR><BR><HR><A NAME="876"></A><H4>876.
  
Type references in rvalue reference deduction specification
</H4><B>Section: </B>14.8.2.1&#160; [temp.deduct.call]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>20 April, 2009<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>14.8.2.1 [temp.deduct.call] paragraph 3 says,</P>

<BLOCKQUOTE>

If <TT>P</TT> is of the form <TT>T&amp;&amp;</TT>, where <TT>T</TT> is
a template parameter, and the argument is an lvalue, the type
<TT>A&amp;</TT> is used in place of <TT>A</TT> for type deduction.

</BLOCKQUOTE>

<P>The type references in that sentence are inconsistent with the
normal usage in the Standard; they should instead refer to
&#8220;an rvalue reference to a cv-unqualified template parameter&#8221;
and &#8220;lvalue reference to <TT>A</TT>.&#8221;</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 14.8.2.1 [temp.deduct.call] paragraph 3 as follows:</P>

<BLOCKQUOTE>

If <TT>P</TT> is a cv-qualified type, the top level cv-qualifiers of
<TT>P</TT>'s type are ignored for type deduction.  If <TT>P</TT> is a
reference type, the type referred to by <TT>P</TT> is used for type
deduction.  If <TT>P</TT> is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">of the form <TT>T&amp;&amp;</TT>,
where <TT>T</TT> is a template parameter,</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an rvalue
reference to a cv-unqualified template parameter</SPAN> and the
argument is an lvalue, the type <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>A&amp;</TT></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">&#8220;lvalue reference to <TT>A</TT>&#8221;</SPAN> is used in
place of <TT>A</TT> for type deduction.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="493"></A><H4>493.
  
Type deduction from a <TT>bool</TT> context
</H4><B>Section: </B>14.8.2.3&#160; [temp.deduct.conv]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>17 Dec 2004<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>An expression used in an <TT>if</TT> statement is implicitly
converted to type <TT>bool</TT> (6.4 [stmt.select]).
According to the rules of template argument deduction for
conversion functions given in 14.8.2.3 [temp.deduct.conv],
the following example is ill-formed:</P>

<PRE>
    struct X {
      template&lt;class T&gt; operator const T&amp;() const;
    };
    int main()
    {
      if( X() ) {}
    }
</PRE>

<P>Following the logic in 14.8.2.3 [temp.deduct.conv],
<TT>A</TT> is <TT>bool</TT> and <TT>P</TT> is <TT>const T</TT>
(because cv-qualification is dropped from <TT>P</TT> before the
reference is removed), and deduction fails.</P>

<P>It's not clear whether this is the intended outcome or
not.</P>

<P><B>Notes from the April, 2005 meeting:</B></P>

<P>The CWG observed that there is nothing special about either
<TT>bool</TT> or the context in the example above; instead, it
will be a problem wherever a copy occurs, because cv-qualification
is always dropped in a copy operation.  This appears to be a case
where the conversion deduction rules are not properly symmetrical
with the rules for arguments.  The example should be accepted.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#976">issue 976</A>.</P>

<BR><BR><HR><A NAME="913"></A><H4>913.
  
Deduction rules for array- and function-type conversion functions
</H4><B>Section: </B>14.8.2.3&#160; [temp.deduct.conv]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Clamage
 &#160;&#160;&#160;

 <B>Date: </B>10 June, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>The rules for deducing function template arguments from a
conversion function template include provisions in
14.8.2.3 [temp.deduct.conv] paragraph 2 for array and function
return types, even though such types are prohibited and cannot
occur in the <I>conversion-type-id</I> of a conversion function
template.  They should be removed.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#976">issue 976</A>.  In particular, under that
resolution, if a conversion function returns a reference to an array
or function type, the reference will be dropped prior to the
adjustments mentioned in this issue, so they are, in fact, needed.</P>

<BR><BR><HR><A NAME="976"></A><H4>976.
  
Deduction for <TT>const T&amp;</TT> conversion operators
</H4><B>Section: </B>14.8.2.3&#160; [temp.deduct.conv]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Jens Maurer
 &#160;&#160;&#160;

 <B>Date: </B>1 October, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>



<P>Consider this program:</P>

<PRE>
    struct F {
       template&lt;class T&gt;
       operator const T&amp;() { static T t; return t; }
    };

    int main() {
       F f;
       int i = f;   // ill-formed
    }
</PRE>

<P>It's ill-formed, because according to 14.8.2.3 [temp.deduct.conv],
we try to match <TT>const T</TT> with <TT>int</TT>.</P>

<P>(The reference got removed from <TT>P</TT> because of paragraph 3,
but the <TT>const</TT> isn't removed, because paragraph 2 bullet 3
comes before paragraph 3 and thus isn't applied any more.)</P>

<P>Changing the declaration of the conversion operator to</P>

<PRE>
   operator T&amp;() { ... }
</PRE>

<P>makes the program compile, which is counter-intuitive to me:
I'm in an rvalue (read-only) context, and I can use a conversion
to <TT>T&amp;</TT>, but I can't use a conversion to <TT>const T&amp;</TT>?</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 14.8.2.3 [temp.deduct.conv] paragraphs 1-3 as follows,
inserting a new paragraph between the current paragraphs 1 and 2:</P>

<BLOCKQUOTE>

<P>Template argument deduction is done by comparing the return
type of the conversion function template (call it
<TT>P</TT><SPAN style="font-weight:bold;background-color:#A0FFA0">; see 8.5 [dcl.init], 13.3.1.5 [over.match.conv], and 13.3.1.6 [over.match.ref] for the
determination of that type</SPAN>) with the type that is required
as the result of the conversion (call it <TT>A</TT>) as described
in 14.8.2.5 [temp.deduct.type].</P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">If <TT>P</TT> is a reference type, the type referred to
by <TT>P</TT> is used in place of <TT>P</TT> for type deduction
and for any further references to or transformations of
<TT>P</TT> in the remainder of this section.</SPAN></P>

<P>If <TT>A</TT> is not a reference type:</P>

<UL><LI><P>If <TT>P</TT> is an array type, the pointer type
produced by the array-to-pointer standard conversion
(4.2 [conv.array]) is used in place of <TT>P</TT> for type
deduction; otherwise,</P></LI>

<LI><P>If <TT>P</TT> is a function type, the pointer type
produced by the function-to-pointer standard conversion
(4.3 [conv.func]) is used in place of <TT>P</TT> for
type deduction; otherwise,</P></LI>

<LI><P>If <TT>P</TT> is a cv-qualified type, the top level cv-qualifiers
of <TT>P</TT>'s type are ignored for type deduction.</P></LI>

</UL>

<P>If <TT>A</TT> is a cv-qualified type, the top level
cv-qualifiers of <TT>A</TT>'s type are ignored for type
deduction.  If <TT>A</TT> is a reference type, the type referred
to by <TT>A</TT> is used for type deduction. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">If <TT>P</TT>
is a reference type, the type referred to by <TT>P</TT> is used
for type deduction.</SPAN></P>

</BLOCKQUOTE>

<P>(This resolution also resolves issues <A HREF="
     cwg_defects.html#493">493</A>
and <A HREF="
     cwg_defects.html#913">913</A>.)</P>

<P><I>[Drafting note: This change intentionally reverses the
resolution of <A HREF="
     cwg_defects.html#322">issue 322</A> (and applies it in
a different form).]</I></P>

<BR><BR><HR><A NAME="499"></A><H4>499.
  
Throwing an array of unknown size
</H4><B>Section: </B>15.1&#160; [except.throw]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>19 Jan 2005<BR>


<P>[Voted into the WP at the March, 2009 meeting.]</P>

<P>According to 15.1 [except.throw] paragraph 3,</P>

<BLOCKQUOTE>

The type of the <I>throw-expression</I> shall not be an incomplete
type, or a pointer to an incomplete type other than (possibly
cv-qualified) <TT>void</TT>.

</BLOCKQUOTE>

<P>This disallows cases like the following, because <TT>str</TT> has
an incomplete type (an array of unknown size):</P>

<PRE>
    extern const char str[];
    void f() {
        throw str;
    }
</PRE>

<P>The array-to-pointer conversion is applied to the operand of
<TT>throw</TT>, so there's no problem creating the exception object,
which is the reason for the restriction on incomplete types.  I
believe this case should be permitted.</P>

<P><B>Notes from the April, 2005 meeting:</B></P>

<P>The CWG agreed that the example should be permitted.  Note
that the reference to <I>throw-expression</I> in the cited text
is incorrect; a <I>throw-expression</I> includes the <TT>throw</TT>
keyword and is always of type <TT>void</TT>.  This wording problem
is addressed in the proposed resolution for <A HREF="
     cwg_defects.html#475">issue 475</A>.</P>

<P><B>Proposed resolution (October, 2006)</B></P>

<P>Change 15.1 [except.throw] paragraph 3 as indicated:</P>

<BLOCKQUOTE>

...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The type of the <I>throw-expression</I> shall not</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">If the type
of the exception object would</SPAN> be an incomplete type,
or a pointer to an incomplete type other than (possibly cv-qualified)
<TT>void</TT> <SPAN style="font-weight:bold;background-color:#A0FFA0">the program is ill-formed</SPAN>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="828"></A><H4>828.
  
Destruction of exception objects
</H4><B>Section: </B>15.1&#160; [except.throw]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>UK
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK130">N2800 comment
  UK&#160;130<BR></A>

<P>[Voted into WP at March, 2010 meeting.]</P>

<P>15.1 [except.throw] paragraph 4 says,</P>

<BLOCKQUOTE>

When the last remaining active handler for the exception exits by any
means other than <TT>throw;</TT> the temporary object is destroyed and the
implementation may deallocate the memory for the temporary object...

</BLOCKQUOTE>

<P>With <TT>std::current_exception()</TT> (18.8.5 [propagation]
paragraph 7), it might be possible to refer to the exception object
after its last handler exits (if the exception object is not copied).
The text needs to be updated to allow for that possibility.</P>

<P><B>Proposed resolution (September, 2009):</B></P>

<P>Change 15.1 [except.throw] paragraph 4 as follows:</P>

<BLOCKQUOTE>

The memory for the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">temporary copy of the exception being
thrown</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">exception object</SPAN> is allocated in an
unspecified way, except as noted in 3.7.4.1 [basic.stc.dynamic.allocation]. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The temporary persists as long as there is a
handler being executed for that exception. In particular, if</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">If</SPAN> a handler exits by <SPAN style="text-decoration:line-through;background-color:#FFA0A0">executing a <TT>throw;</TT>
statement, that passes control</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">rethrowing, control is
passed</SPAN> to another handler for the same exception<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, so the
temporary remains</SPAN>. <SPAN style="font-weight:bold;background-color:#A0FFA0">The exception object is destroyed after
either</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">When</SPAN> the last remaining active handler for the
exception exits by any means other than <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>throw;</TT></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">rethrowing, or the last object of type
<TT>std::exception_ptr</TT> (18.8.5 [propagation]) that refers
to the exception object is destroyed, whichever is later. In the
former case, the destruction occurs when the handler exits,
immediately after the destruction of the object declared in the
<I>exception-declaration</I> in the handler, if any. In the latter
case, the destruction occurs before the destructor of
<TT>std::exception_ptr</TT> returns.</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the temporary object
is destroyed and the</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">The</SPAN> implementation may
<SPAN style="font-weight:bold;background-color:#A0FFA0">then</SPAN> deallocate the memory for the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">temporary</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">exception</SPAN> object; any such deallocation is done in an
unspecified way. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The destruction occurs immediately after the
destruction of the object declared in the
<I>exception-declaration</I> in the handler.</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="830"></A><H4>830.
  
Deprecating exception specifications
</H4><B>Section: </B>15.4&#160; [except.spec]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>UK
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK136">N2800 comment
  UK&#160;136<BR></A>

<P>[Voted into WP at March, 2010 meeting as paper N3051.]</P>

<P>
Exception specifications have proven close
to worthless in practice, while adding a measurable
overhead to programs. The feature should be deprecated. The
one exception to the rule is the empty throw specification
which could serve a legitimate optimizing role if the
requirement to call <TT>std::unexpected</TT> were
relaxed in this case.
</P>

<P><B>Notes from the July, 2009 meeting:</B></P>

<P>The consensus of the CWG was in favor of deprecating exception
specifications.  Further discussion, and with a wider constituency,
is needed to determine a position on the status of <TT>throw()</TT>.</P>

<P>(See also <A HREF="
     cwg_defects.html#814">issue 814</A>.)</P>

<BR><BR><HR><A NAME="973"></A><H4>973.
  
Function types in <I>exception-specification</I>s
</H4><B>Section: </B>15.4&#160; [except.spec]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>12 October, 2009<BR>


<P>[Voted into WP at March, 2010 meeting.]</P>

<P>There is no prohibition against specifying a function type in an
<I>exception-specification</I>, and the normal conversion of a
function type to a pointer-to-function type occurs in both
<I>throw-expression</I>s (<sectioni_ref ref="15.1">15.1 [except.throw]</sectioni_ref> paragraph 3) and
in <I>handler</I>s (15.3 [except.handle] paragraph 2), but that
was apparently overlooked in the description of
<I>exception-specification</I>s.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 15.4 [except.spec] paragraphs 2-3 as follows:</P>

<BLOCKQUOTE>

<P>A type denoted in an <I>exception-specification</I> shall not
denote an incomplete type.  A type denoted in an
<I>exception-specification</I> shall not denote a pointer or
reference to an incomplete type, other than <TT>void*</TT>,
<TT>const void*</TT>, <TT>volatile void*</TT>, or <TT>const
volatile void*</TT>. <SPAN style="font-weight:bold;background-color:#A0FFA0">A type <I>cv</I> <TT>T</TT>,
&#8220;array of <TT>T</TT>,&#8221; or &#8220;function returning
<TT>T</TT>&#8221; denoted in an <I>exception-specification</I> is
adjusted to type <TT>T</TT>, &#8220;pointer to <TT>T</TT>,&#8221;
or &#8220;pointer to function returning <TT>T</TT>,&#8221;
respectively.</SPAN></P>

<P>If any declaration of a function has an
<I>exception-specification</I>, all declarations, including the
definition and <SPAN style="text-decoration:line-through;background-color:#FFA0A0">an</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">any</SPAN> explicit
specialization, of that function shall have an
<I>exception-specification</I> with the same set of
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>type-id</I>s</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">adjusted types</SPAN>.  If any
declaration of a pointer to function, reference to function, or
pointer to member function has an <I>exception-specification</I>,
all occurrences of that declaration shall have an
<I>exception-specification</I> with the same set of
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>type-id</I>s</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">adjusted types</SPAN>.  In an
explicit instantiation an <I>exception-specification</I> may be
specified, but is not required. If an
<I>exception-specification</I> is specified in an explicit
instantiation directive, it shall have the same set of
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>type-id</I>s</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">adjusted types</SPAN> as other
declarations of that function. A diagnostic is required only if
the sets of <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>type-id</I>s</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">adjusted types</SPAN>
are different within a single translation unit.</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="668"></A><H4>668.
  
Throwing an exception from the destructor of a local static object
</H4><B>Section: </B>15.5.1&#160; [except.terminate]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>16 December 2007<BR>


<P>[Voted into the WP at the March, 2009 meeting.]</P>

<P>The destruction of local static objects occurs at the same time as
that of non-local objects (3.6.3 [basic.start.term] paragraph 1) and
the execution of functions registered with <TT>std::atexit</TT>
(paragraph 3).  According to 15.5.1 [except.terminate] paragraph 1,
<TT>std::terminate</TT> is called if a destructor for a non-local
object or a function registered with <TT>std::atexit</TT> exits via
an exception, but the Standard is silent about the result of throwing
an exception from a destructor for a local static object.  Presumably
this is an oversight and the same rules should apply to destruction of
local static objects.</P>

<P><B>Proposed resolution (September, 2008):</B></P>

<P>Change 15.5.1 [except.terminate] paragraph 1, fourth bullet as
indicated, and add an additional bullet to follow it:</P>

<UL>
<LI><P>when construction <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or destruction</SPAN> of a non-local
object with static or thread storage duration exits using an
exception (3.6.2 [basic.start.init]), or</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">when destruction of an object with static or thread
storage duration exits using an exception (3.6.3 [basic.start.term]), or</SPAN></P></LI> </UL>

<BR><BR><HR><A NAME="601"></A><H4>601.
  
Type of literals in preprocessing expressions
</H4><B>Section: </B>16.1&#160; [cpp.cond]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>23 October 2006<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>The description of preprocessing expressions in
16.1 [cpp.cond] paragraph 4 says,</P>

<BLOCKQUOTE>

The resulting tokens comprise the controlling constant expression
which is evaluated according to the rules of 5.19 using arithmetic
that has at least the ranges specified in 18.3 [support.limits],
except that all signed and unsigned integer types act as if they have
the same representation as, respectively, <TT>intmax_t</TT> or
<TT>uintmax_t</TT> (18.3.2).

</BLOCKQUOTE>

<P>However, this does not address the type implicitly assigned to
integral literals.  For example, in an implementation where <TT>int</TT>
is 32 bits and <TT>long long</TT> is 64 bits, is a literal like
<TT>0xffffffff</TT> signed or unsigned?  WG14 adopted
<A HREF="http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_265.htm">
DR 265</A> to deal with this issue in the essentially-identical
wording in C99; we should probably follow suit for C++.</P>

<P><B>Proposed Resolution (July, 2009):</B></P>

<P>Change 16.1 [cpp.cond] paragraph 4 as follows:</P>

<BLOCKQUOTE>

...and then each preprocessing token is converted into a token. The
resulting tokens comprise the controlling constant expression which is
evaluated according to the rules of 5.19 [expr.const] using
arithmetic that has at least the ranges specified in 18.3 [support.limits]<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, except that</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">. For the purposes of this token
conversion and evaluation</SPAN> all signed and unsigned integer types
act as if they have the same representation as,
respectively, <TT>intmax_t</TT> or <TT>uintmax_t</TT> (_N3035_.18.4.2 [stdinth])<SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Footnote:</I> Thus on an implementation where
<TT>std::numeric_limits&lt;int&gt;::max()</TT> is 0x7FFF and
<TT>std::numeric_limits&lt;unsigned int&gt;::max()</TT> is 0xFFFF,
the integer literal <TT>0x8000</TT> is signed and positive within a
<TT>#if</TT> expression even though it is unsigned in translation
phase 7 (2.2 [lex.phases]). &#8212;<I>end footnote</I>]</SPAN>.
This includes interpreting character literals...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="618"></A><H4>618.
  
Casts in preprocessor conditional expressions
</H4><B>Section: </B>16.1&#160; [cpp.cond]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Martin Sebor
 &#160;&#160;&#160;

 <B>Date: </B>12 February 2007<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>



<P>16.1 [cpp.cond] paragraph 1 states,</P>

<BLOCKQUOTE>

The expression that controls conditional inclusion shall be an
integral constant expression except that: it shall not contain a
cast...

</BLOCKQUOTE>

<P>The prohibition of casts is vacuous and misleading: as
pointed out in the footnote in that paragraph, </P>

<BLOCKQUOTE>

Because the controlling constant expression is evaluated during
translation phase 4, all identifiers either are or are not macro names
&#8212; there simply are no keywords, enumeration constants, and so on.

</BLOCKQUOTE>

<P>As a result, there can be no casts, which require either
keywords or identifiers that resolve to types in order to be
recognized as casts.  The wording on casts should be removed and
replaced by a note recognizing this implication.</P>

<P><B>Notes from the April, 2007 meeting:</B></P>

<P>The CWG agreed with this suggested resolution; however, the
reference is in the &#8220;Preprocessing Directives&#8221; clause,
which WG21 intends to keep in as close synchronization as possible
with the corresponding wording in the C Standard.  Any change here
must therefore be done in consultation with WG14.  Clark Nelson will
fulfill this liaison function.</P>

<P>It was also noted that the imminent introduction of
<TT>constexpr</TT> also has the potential for a similar kind of
confusion, so the proposed resolution should address both casts and
<TT>constexpr</TT>.</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<P>Change 16.1 [cpp.cond] paragraph 1 as follows:</P>

<BLOCKQUOTE>

The expression that controls conditional inclusion shall be an
integral constant expression except that: <SPAN style="text-decoration:line-through;background-color:#FFA0A0">it shall not contain a
cast;</SPAN> identifiers (including those lexically identical to
keywords)...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="626"></A><H4>626.
  
Preprocessor string literals
</H4><B>Section: </B>16.3.2&#160; [cpp.stringize]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>Gennaro Prota
 &#160;&#160;&#160;

 <B>Date: </B>12 September 2006<BR>


<P>[Voted into WP at October, 2009 meeting.]</P>

<P>Clause 16 [cpp] refers in several places to
&#8220;character string literals&#8221; without specifying
whether they are narrow or wide strings.  For instance, what kind
of string does the <TT>#</TT> operator (16.3.2 [cpp.stringize]) produce?</P>

<P>16.4 [cpp.line] paragraph 1 says,</P>

<BLOCKQUOTE>

The string literal of a <TT>#line</TT> directive, if present, shall be a
character string literal.

</BLOCKQUOTE>

<P>Is &#8220;character string literal&#8221; intended to mean a
narrow string literal?  (Also, there is no <I>string-literal</I>
mentioned in the grammatical descriptions of <TT>#line</TT>;
paragraph 4 reads,</P>

<P><UL><TT># line</TT> <I>digit-sequence</I> <TT>"</TT> <I>s-char-sequence<SUB>opt</SUB></I> <TT>"</TT> <I>new-line</I></UL></P>

<P>which is apparently intended to suggest a string literal but does
not use the term.)</P>

<P>16.8 [cpp.predefined] should also specify what kind of
character string literals are produced by the various string-valued
predefined macros.</P>

<P><B>Notes from the July, 2007 meeting:</B></P>

<P>The CWG affirmed that all the string literals mentioned in
Clause 16 [cpp] are intended to be narrow strings.</P>

<P><B>Proposed resolution (September, 2008)</B></P>

<OL>
<LI><P>Change the footnote in 16 [cpp] paragraph 1 as
follows:
</P></LI>

<BLOCKQUOTE>

Thus, preprocessing directives are commonly called
&#8220;lines.&#8221; These &#8220;lines&#8221; have no other
syntactic significance, as all white space is equivalent except
in certain situations during preprocessing (see the <TT>#</TT>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">character</SPAN> string literal creation operator in 16.3.2 [cpp.stringize], for example).

</BLOCKQUOTE>

<LI><P>Change 16.3.2 [cpp.stringize] paragraph 2 as follows:
</P></LI>

<BLOCKQUOTE>

If, in the replacement list, a parameter is immediately preceded
by a <TT>#</TT> preprocessing token, both are replaced by a
single <SPAN style="text-decoration:line-through;background-color:#FFA0A0">character</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">ordinary</SPAN> string literal
<SPAN style="font-weight:bold;background-color:#A0FFA0">(2.14.5 [lex.string])</SPAN> preprocessing token that
contains the spelling of the preprocessing token sequence for the
corresponding argument... Otherwise, the original spelling of
each preprocessing token in the argument is retained in the
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">character</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">ordinary</SPAN> string literal, except for special
handling for producing the spelling of string literals and
character literals: a <TT>\</TT> character is inserted before
each <TT>"</TT> and <TT>\</TT> character of a character literal
or string literal (including the delimiting <TT>"</TT>
characters). If the replacement that results is not a valid
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">character</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">ordinary</SPAN> string literal, the behavior is
undefined. The <SPAN style="text-decoration:line-through;background-color:#FFA0A0">character</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">ordinary</SPAN> string literal
corresponding to an empty argument is <TT>""</TT>. The order of
evaluation of <TT>#</TT> and <TT>##</TT> operators is
unspecified.

</BLOCKQUOTE>

<LI><P>Change 16.3.5 [cpp.scope] paragraph 6 as follows:
</P></LI>

<BLOCKQUOTE>

To illustrate the rules for creating <SPAN style="text-decoration:line-through;background-color:#FFA0A0">character</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">ordinary</SPAN> string literals and concatenating tokens, the
sequence... or, after concatenation of the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">character</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">ordinary</SPAN> string literals...

</BLOCKQUOTE>

<LI><P>Change 16.4 [cpp.line] paragraph 1 as follows:
</P></LI>

<BLOCKQUOTE>

The string literal of a <TT>#line</TT> directive, if present,
shall be <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a character</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an ordinary</SPAN> string literal.

</BLOCKQUOTE>

<LI><P>Change 16.4 [cpp.line] paragraph 4 as follows:
</P></LI>

<BLOCKQUOTE>

...and changes the presumed name of the source file to be the
contents of the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">character</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">ordinary</SPAN> string literal.

</BLOCKQUOTE>

<LI><P>Change 16.8 [cpp.predefined] paragraph 1 as follows:
</P></LI>

<BLOCKQUOTE>

<P>__DATE__</P>

<UL>The date of translation of the source file
(<SPAN style="text-decoration:line-through;background-color:#FFA0A0">a character</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an ordinary</SPAN> string literal of the form...</UL>

<P>__FILE__</P>

<UL>The presumed name of the source file (<SPAN style="text-decoration:line-through;background-color:#FFA0A0">a character</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">an ordinary</SPAN> string literal).</UL>

<P>...</P>

<P>__TIME__</P>

<UL>The time of translation of the source file (<SPAN style="text-decoration:line-through;background-color:#FFA0A0">a character</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">an ordinary</SPAN> string literal of the form...</UL>

</BLOCKQUOTE>
</OL>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>The proposed resolution will be discussed with the C Committee
before proceeding, as it is expected that the next revision of the
C Standard will also adopt new forms of string literals.</P>

<P><B>Additional notes (May, 2009):</B></P>

<P>At its most recent meeting, the C Committee decided to keep
the existing term, &#8220;character string literal.&#8221;</P>

<P>One possibility for maintaining compatible phraseology with
the C Standard would be to replace the occurrences of &#8220;ordinary
string literal&#8221; in 2.14.5 [lex.string] with
&#8220;character string literal,&#8221; instead of the extensive
set of changes above.</P>

<P>Another possibility would be to leave the references in clause
16 [cpp] unchanged and just insert a prefatory comment
near the beginning that every occurrence of &#8220;character string
literal&#8221; refers to a <I>string-literal</I> with no prefix.  (The
use of &#8220;ordinary string literal&#8221; in the preceding edits is
problematic in that the phrase includes raw string literals as well as
unprefixed literals.)</P>

<P><B>Proposed resolution (July, 2009):</B></P>

<OL><LI><P>Change 16.3.2 [cpp.stringize] paragraph 2 as
follows:</P></LI>

<BLOCKQUOTE>

<SPAN style="font-weight:bold;background-color:#A0FFA0">A <I>character string literal</I> is a <I>string-literal</I> with
no prefix.</SPAN> If, in the replacement list, a parameter is
immediately preceded by a <TT>#</TT> preprocessing token...

</BLOCKQUOTE>

<LI><P>Change the fifteenth bullet of Annex B [implimits]
paragraph 2 as follows:</P></LI>

<UL><LI>Characters in a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">character</SPAN> string literal <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or
wide string literal</SPAN> (after concatenation) [65 536].</LI></UL>

</OL>

<BR><BR><HR><A NAME="831"></A><H4>831.
  
Limit on recursively nested template instantiations
</H4><B>Section: </B>B&#160; [implimits]
 &#160;&#160;&#160;

 <B>Status: </B>CD2
 &#160;&#160;&#160;

 <B>Submitter: </B>DE
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#DE25">N2800 comment
  DE&#160;25<BR></A>

<P>[Voted into WP at October, 2009 meeting.]</P>

<P>The limit of 17 recursively-nested template instantiations is too
small for modern programming practices such as template metaprogramming.
It is unclear, however, whether this is a useful metric; see
<A href="http://ubiety.uwaterloo.ca/~tveldhui/papers/2003/turing.pdf">
this paper</A> for an example that honors the limit but results in
over 750 billion instantiations.</P>

<P><B>Notes from the July, 2009 meeting:</B></P>

<P>The consensus of the CWG was to increase the limit to 1024.</P>

<P><B>Proposed resolution (September, 2009):</B></P>

<P>Change B [implimits], the fourth bullet from the end, as follows:</P>

<UL><LI>Recursively nested template instantiations [<SPAN style="text-decoration:line-through;background-color:#FFA0A0">17</SPAN>

<SPAN style="font-weight:bold;background-color:#A0FFA0">1 024</SPAN>].</LI></UL>

<BR><BR><BR><BR><HR><A NAME="TC1 Status"></A><H3>Issues with "TC1" Status</H3>
<HR><A NAME="131"></A><H4>131.
  
Typo in Lao characters
</H4><B>Section: </B>_N2691_.E&#160; [extendid]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>23 June 1999<BR>





<P>The Lao character 0e0d should be 0e8d.  0e0d is both out of order
and already used in the Thai characters.</P>

<P><B>Proposed resolution (10/99):</B> As suggested.</P>
<BR><BR><HR><A NAME="173"></A><H4>173.
  
Constraints on execution character set
</H4><B>Section: </B>2.3&#160; [lex.charset]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Markus Mauhart
 &#160;&#160;&#160;

 <B>Date: </B>27 Sep 1999<BR>



<P>22.4.1.1.2 [locale.ctype.virtuals]

paragraph 13 states a constraint on the values of the characters
representing the decimal digits in the execution character set:</P>

<BLOCKQUOTE>
for any digit character <TT>c</TT>, the expression
<TT>(do_narrow( c, dfault)-'0')</TT> evaluates to the digit
value of the character.
</BLOCKQUOTE>

This requirement is not reflected in the description of the
execution character set
(2.3 [lex.charset]
 paragraph 3).

<P><B>Proposed resolution (10/00):</B></P>

<P>In 2.3 [lex.charset]
 paragraph 3,
after the sentence</P>

<BLOCKQUOTE>
For each basic execution character
set, the values of the members shall be non-negative and distinct
from one another.
</BLOCKQUOTE>

insert the following:

<BLOCKQUOTE>
In both the source and execution basic character sets, the value of each
character after 0 in the above list of decimal digits shall be one
greater than the value of the previous.
</BLOCKQUOTE>
<BR><BR><HR><A NAME="41"></A><H4>41.
  
Clarification of lookup of names after declarator-id
</H4><B>Section: </B>3.4.1&#160; [basic.lookup.unqual]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>1 Sep 1998<BR>





<P>Footnotes 26 and 29 both use the phrase "following the function declarator"
incorrectly: the function declarator includes the parameter list, but the
footnotes make clear that they intend what's said to apply to names inside
the parameter list. Presumably the phrase should be "following the function
<I>declarator-id</I>."</P>

<P><B>Proposed Resolution (04/99):</B>
Change the text in 3.4.1 [basic.lookup.unqual]
 
paragraph 6 from:</P>
<BLOCKQUOTE>A name used in the definition of a function [<I>footnote:</I> This
refers to unqualified names following the function declarator; such a name
may be used as a type or as a default argument name in the
<I>parameter-declaration-clause</I>,
or may be used in the function body. <I>end footnote</I>] that is ...</BLOCKQUOTE>
to:
<BLOCKQUOTE>A name used in the definition of a function following the function's
<I>declarator-id [footnote:</I>
This refers to unqualified names that occur, for instance, in a type or
default argument expression in the <I>parameter-declaration-clause</I>
or used in the function body. <I>end footnote</I>] that is ...</BLOCKQUOTE>
Change the text in 3.4.1 [basic.lookup.unqual]
paragraph 8 from:
<BLOCKQUOTE>A name used in the definition of a function that is a member
function (9.3 [class.mfct]
)
[<I>footnote:</I> That is, an unqualified name following the function
declarator; such a name may be used as a type or as a default argument
name in the <I>parameter-declaration-clause</I>, or may be used in the function
body, or, if the function is a constructor, may be used in the expression
of a <I>mem-initializer</I>. <I>end footnote</I>] of class <TT>X</TT> shall be ...</BLOCKQUOTE>
to:
<BLOCKQUOTE>A name used in the definition of a member function
(9.3 [class.mfct]
) of
class <TT>X</TT> following the function's <I>declarator-id</I>
[<I>footnote:</I>
That is, an unqualified name that occurs, for instance, in a type or default
argument expression in the <I>parameter-declaration-clause</I>, in the
function body, or in an expression of a <I>mem-initializer</I> in a constructor
definition.
<I>end footnote</I>] shall be ...</BLOCKQUOTE>
<BR><BR><HR><A NAME="33"></A><H4>33.
  
Argument dependent lookup and overloaded functions
</H4><B>Section: </B>3.4.2&#160; [basic.lookup.argdep]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>15 Jul 1998<BR>





<P>If an argument used for lookup is the address of a group of overloaded
functions, are there any associated namespaces or classes? What if it's
the address of a function template?</P>

<P>My inclination is to say no to both.</P>

<P><U>From Mike Miller:</U></P>

<P>We discussed this on the reflector a few weeks ago. I'll leave the template
case for the Core III experts, but I'd find it surprising if the overload
case weren't handled as the obvious generalization of the single-function
case. For a single function, the associated namespaces are those of the
types used in the parameters and return type; I would expect that using
an overloaded function name would simply be the union of the namespaces
from the members of the overload set. That would be the simplest and most
intuitive, IMHO &#8212; is there an argument for doing it differently?</P>

<P><B>Proposed Resolution (04/99):</B>
In 3.4.2 [basic.lookup.argdep]
 paragraph 2,
add following the last bullet in the list of associated classes and namespaces
for various argument types (not a bullet itself because overload sets and
templates do not have a type):</P>
<BLOCKQUOTE>In addition, if the argument is the name or address of a set
of overloaded functions and/or function templates, its associated classes
and namespaces are the union of those associated with each of the members
of the set: the namespace in which the function or function template is
defined and the classes and namespaces associated with its (non-dependent)
parameter types and return type.</BLOCKQUOTE>
<BR><BR><HR><A NAME="90"></A><H4>90.
  
Should the enclosing class be an "associated class" too?
</H4><B>Section: </B>3.4.2&#160; [basic.lookup.argdep]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>2 Feb 1999<BR>





<P>Section
3.4.2 [basic.lookup.argdep]

 includes the following:</P>
<UL>
<LI>
If T is a class type, its associated classes are the class itself and its
direct and indirect base classes. Its associated namespaces are the namespaces
in which its associated classes are defined.</LI>

<LI>
If T is a union or enumeration type, its associated namespace is the namespace
in which it is defined. If it is a class member, its associated class is
the member's class; else it has no associated class.</LI>
</UL>
Note that for a union, the enclosing class is an "associated class", but
for a class type the enclosing class is not an "associated class". This
results in some surprising behavior, as shown in the example below.
<PRE>
    struct A {
        union U {};
        friend void f(U);
    };
            
    struct B {
        struct S {};
        friend void f(S);
    };
             
    int main() { 
        A::U    u; 
        f(u);        // okay: A is an associated class
        B::S    s;
        f(s);        // error: no matching f(), B is not an associated class
    }

</PRE>
Certainly the enclosing class should also be an associated class for nested
class types, shouldn't it?

<P><B>Proposed Resolution (10/99):</B>
Change the two referenced bullets to read:</P>
<UL>
<LI>If <TT>T</TT> is a class type (including unions),
its associated classes are:
the class itself; the
class of which it is a member, if any; and its direct and indirect base
classes. Its associated namespaces are the namespaces in which its
associated classes are defined.</LI>

<LI>If <TT>T</TT> is an enumeration type,
its associated namespace is the namespace in
which it is defined. If it is class member, its associated class is the
member's class; else it has no associated class.</LI>
</UL>
(This proposal also addresses
<A HREF="
     cwg_closed.html#91">Core issue 91</A>.)
<BR><BR><HR><A NAME="164"></A><H4>164.
  
Overlap between Koenig and normal lookup
</H4><B>Section: </B>3.4.2&#160; [basic.lookup.argdep]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Derek Inglis
 &#160;&#160;&#160;

 <B>Date: </B>3 Sep 1999<BR>



<P>The description of Koenig lookup in
3.4.2 [basic.lookup.argdep]
 paragraph 1 says,</P>

<BLOCKQUOTE>
...other namespaces not considered during the usual unqualified lookup
(3.4.1 [basic.lookup.unqual]
) may be
searched.
</BLOCKQUOTE>

Does this mean that Koenig lookup does <I>not</I> search namespaces
that were already searched during the usual unqualified lookup?  The
answer is academic except for the two-stage lookup during template
instantiation.  If a given namespace is searched in the context of the
template definition, are declarations in that namespace in the
instantiation context ignored during the Koenig lookup?  For instance,

<PRE>
    void f(int);

    template &lt;class T&gt; void g(T t) {
        f(t);
    }

    enum E { e };

    void f(E);

    void h() {
        g(e);
    }
</PRE>

In this example, the call <TT>f(t)</TT> in the template function will
resolve to <TT>f(E)</TT> if Koenig lookup reexamines already-searched
namespaces and to <TT>f(int)</TT> if not.

<P><B>Proposed Resolution (10/00):</B></P>

<P>Immediately preceding the example
at the end of
3.4.2 [basic.lookup.argdep]
 paragraph 2, add
the following:</P>

<BLOCKQUOTE>
[<I>Note:</I> the namespaces and classes associated with the argument
types can include namespaces and classes already considered by the
ordinary unqualified lookup.]
</BLOCKQUOTE>
<BR><BR><HR><A NAME="85"></A><H4>85.
  
Redeclaration of member class
</H4><B>Section: </B>3.4.4&#160; [basic.lookup.elab]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>25 Jan 1999<BR>



<P>In
3.4.4 [basic.lookup.elab]

 paragraph 3, there is the example</P>
<PRE>
    struct Base {
        // ...
        struct Data { /* ... */ };  // <I>Defines nested </I>Data
        struct Data;                // <I>OK: Redeclares nested </I>Data
    };
</PRE>

The final redeclaration is invalid according to
9.2 [class.mem] paragraph 1 last sentence.

<P><B>Proposed resolution (10/00):</B> Remove the line</P>

<PRE>
        struct Data;                // <I>OK: Redeclares nested </I>Data
</PRE>

<P>See also
<A HREF="
     cwg_active.html#36">Core issue 36</A>
 and
<A HREF="
     cwg_defects.html#56">Core issue 56</A>.</P>
<BR><BR><HR><A NAME="89"></A><H4>89.
  
Object lifetime does not account for reference rebinding
</H4><B>Section: </B>3.8&#160; [basic.life]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>AFNOR
 &#160;&#160;&#160;

 <B>Date: </B>27 Oct 1998<BR>



<BR>From J16/98-0026 = WG21 N1169, "Proposed Defect Reports on ISO/IEC
14882, Programming Languages - C++":
<BLOCKQUOTE>
A reference is rebindable. This is surprising and unnatural. This can
also cause subtle optimizer bugs.

<P>Example:</P>
<PRE>
    struct T {
        int&amp; ri;
        T (int&amp; r) : ri (r) { }
    };
    
    void bar (T*);
    
    void foo () {
        int i;
        T x (i);
        x.ri = 3;   // the optimizer understands that this is really i = 3
        bar (&amp;x);
        x.ri = 4;   // optimizer assumes that this writes to i, but this is incorrect
    }
    
    int gi;
    
    void bar (T* p) {
        p-&gt;~T ();
        new (p) T (gi);
    }
</PRE>
If we replace <TT>T&amp;</TT> with <TT>T* const</TT> in the example then
undefined behavior result and the optimizer is correct.

<P>Proposal: make <TT>T&amp;</TT> equivalent to <TT>T* const</TT> by extending
the scope of
3.8 [basic.life]
 paragraph
9 to references.</P>
</BLOCKQUOTE>
<P>(See also J16/99-0005 = WG21 N1182, "Proposed Resolutions for Core
Language Issues 6, 14, 20, 40, and 89")</P>

<P>In addition, Lisa Lippincott pointed out the following example:</P>

<PRE>
    void f( const bool * );
    void g();

    int main() {
       const bool *b = new const bool( false );
       f(b);
       if (*b)
          g();
    }

    void f( const bool *b ) {
       new ( const_cast&lt;bool *&gt;(b) ) const bool( true );
    }
</PRE>

<P>The proposed wording in the paper would still permit this usage and
thus prevent an optimizer from eliminating the call to <TT>g()</TT>.</P>

<P><B>Proposed Resolution (10/00):</B></P>

<P>Add a new bullet to the list of restrictions in
3.8 [basic.life]
paragraph 7, following the second bullet ("the new object is of the same
type..."):</P>
<UL>
<LI>
the type of the original object is not const-qualified, and,
if a class type, does not contain any non-static
data member whose type is const-qualified or a reference type, and</LI>
</UL>
<BR><BR><HR><A NAME="93"></A><H4>93.
  
Missing word in 3.8 <U>basic.life</U> paragraph 2
</H4><B>Section: </B>3.8&#160; [basic.life]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>6 Feb 1999<BR>





<P>The text of
3.8 [basic.life]

 paragraph
2 currently reads,</P>
<UL>[<I>Note:</I> the lifetime of an array object or of an object of
type (3.9 [basic.types]


) starts...]</UL>
<P>The phrase "an object of type" is obviously incorrect. I believe it should
read "an object of POD type." Does anyone disagree?</P>

<P><B>Proposed Resolution (10/99):</B>
As suggested.</P>
<BR><BR><HR><A NAME="43"></A><H4>43.
  
Copying base classes (PODs) using memcpy
</H4><B>Section: </B>3.9&#160; [basic.types]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Nathan Myers
 &#160;&#160;&#160;

 <B>Date: </B>15 Sep 1998<BR>





<P>Can you use memcpy on non-member POD subobjects of non-POD objects?</P>

<P>In 3.9 [basic.types]
 paragraphs 2 and 3 we have:</P>
<BLOCKQUOTE>For any complete POD object type <TT>T</TT>, whether or not the object
holds a valid value of type <TT>T</TT>, the underlying bytes
(1.7 [intro.memory]
) making
up the object can be copied into an array of <TT>char</TT>
or <TT>unsigned char</TT>*. If the content of
the array of <TT>char</TT> or <TT>unsigned char</TT> is copied back into the object, the
object shall subsequently hold its original value. <I>[Example elided]</I>
<BLOCKQUOTE>*[<I>Footnote:</I> By using, for example, the library functions
(17.6.1.2 [headers]
)
<TT>memcpy</TT> or <TT>memmove</TT>. <I>end footnote</I>]</BLOCKQUOTE>
For any POD type <TT>T</TT>, if two pointers to <TT>T</TT> point
to distinct <TT>T</TT> objects <TT>obj1</TT>
and <TT>obj2</TT>, if the value of <TT>obj1</TT> is copied into
<TT>obj2</TT>, using the <TT>memcpy</TT> library
function, <TT>obj2</TT> shall subsequently hold the same value as
<TT>obj1</TT>.</BLOCKQUOTE>
Paragraph 3 doesn't repeat the restriction of paragraph 2. Should it be
assumed? Otherwise only complete POD types are copyable to an array of
<TT>char</TT> and back, but scribbling over subobjects is OK.
(Or perhaps a "distinct <TT>T</TT> object" is a complete object...)

<P><B>Proposed Resolution (04/99):</B>
Change the text in 3.9 [basic.types]

paragraph 2 from:</P>
<BLOCKQUOTE>For any complete POD object type <TT>T</TT>, ...</BLOCKQUOTE>
to:
<BLOCKQUOTE>For any object (other than a base class subobject) of POD type
<TT>T</TT>, ...</BLOCKQUOTE>
Change the text in 3.9 [basic.types]
 paragraph 3 from:
<BLOCKQUOTE>For any POD type <TT>T</TT>, if two pointers to <TT>T</TT>
point to distinct <TT>T</TT> objects <TT>obj1</TT> and <TT>obj2</TT>,</BLOCKQUOTE>
to:
<BLOCKQUOTE>For any POD type <TT>T</TT>, if two pointers to <TT>T</TT>
point to distinct <TT>T</TT> objects <TT>obj1</TT> and <TT>obj2</TT>,
where neither <TT>obj1</TT> nor <TT>obj2</TT> is a base class subobject,
...</BLOCKQUOTE>

<BR><BR><HR><A NAME="149"></A><H4>149.
  
Accessibility and ambiguity
</H4><B>Section: </B>4.10&#160; [conv.ptr]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Nathan Sidwell
 &#160;&#160;&#160;

 <B>Date: </B>31 Jul 1999<BR>



<P>The Standard uses confusing terminology when referring to
accessibility in connection with ambiguity.  For instance:</P>

<P>4.10 [conv.ptr]
 paragraph 3:</P>

<BLOCKQUOTE>
If <TT>B</TT> is an inaccessible or ambiguous base ...
</BLOCKQUOTE>

5.2.7 [expr.dynamic.cast]
 paragraph 8:

<BLOCKQUOTE>
... has an unambiguous public base ...
</BLOCKQUOTE>

10.3 [class.virtual]
 paragraph 5:

<BLOCKQUOTE>
... is an unambiguous direct or indirect base ... and
is accessible ...
</BLOCKQUOTE>

15.3 [except.handle]
 paragraph 3:

<BLOCKQUOTE>
not involving conversions to pointers to private or
protected or ambiguous classes
</BLOCKQUOTE>

<P>The phrase "unambiguous public base" is unfortunate as it
could mean either "an
unambiguous base not considering accessibility, which is public"
or "an
unambiguous base considering only the publicly accessible bases."
I believe the
former interpretation correct, as accessibility is applied after visibility
(11 [class.access]
 paragraph 4)
and ambiguity is described in terms of visibility
(10.2 [class.member.lookup]
 paragraph 2).</P>

<P>Suggested Resolution:
Use the phrases "public and unambiguous,"
"accessible and unambiguous,"
"non-public or ambiguous," or "inaccessible or ambiguous" as appropriate.</P>

<P><B>Proposed resolution (10/00):</B>
<UL>
<LI>
5.2.7 [expr.dynamic.cast]
 paragraph 8,
bullet 2: change "unambiguous public base class" to "unambiguous
and public base class"</LI>
<LI>
10.3 [class.virtual]
 paragraph 5: change
"the class in the return type... is an unambiguous direct or
indirect base class... and is accessible in <TT>D</TT>" to "the
class in the return type... is an unambiguous and accessible direct
or indirect base class..."</LI>
</UL></P>
<BR><BR><HR><A NAME="123"></A><H4>123.
  
Bad cross-reference
</H4><B>Section: </B>5.1.1&#160; [expr.prim.general]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>3 June 1999<BR>





The cross-reference is incorrect in the first
sentence after the grammar in
5.1.1 [expr.prim.general]
 paragraph 7:

<BLOCKQUOTE>
A <I>nested-name-specifier</I> that names a class, optionally
followed by the keyword <TT>template</TT>
(14.8.1 [temp.arg.explicit]
), ...
</BLOCKQUOTE>

The use of the <TT>template</TT> keyword in this context is discussed
in 14.2 [temp.names]
, not
14.8.1 [temp.arg.explicit]
.  

<BR><BR><HR><A NAME="147"></A><H4>147.
  
Naming the constructor
</H4><B>Section: </B>5.1.1&#160; [expr.prim.general]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>21 Feb 1999<BR>



<P>From paper J16/99-0010 = WG21 N1187.</P>

<P>5.1.1 [expr.prim.general]
 paragraph 7 says that
<I>class-name::class-name</I> names the constructor when both
<I>class-name</I> refer to the same class.  (Note the different
perspective, at least, in
12.1 [class.ctor]
 paragraph 1, in which
constructors have no names and are recognized by syntactic context
rather than by name.)</P>

<P>This formulation does not address the case of classes in which a
function template is declared as a constructor, for example:</P>

<PRE>
    template &lt;class T&gt; struct A {
        template &lt;class T2&gt; A(T2);
    };
    template&lt;&gt; template&lt;&gt; A&lt;int&gt;::A&lt;int&gt;(int);
</PRE>

<P>Here there is an ambiguity as to whether the second template argument
list is for the injected class name or for the constructor.</P>

<P>Suggested resolution: restate the rule as a component of name
lookup.  Specifically, if when doing a qualified lookup in a given
class you look up a name that is the same as the name of the class,
the entity found is the constructor and not the injected class name.
In all other cases, the name found is the injected class name.  For
example:</P>

<PRE>
    class B { };
    class A: public B {
        A::B ab;       // B is the inherited injected B
        A::A aa;       // Error: A::A is the constructor
    };
</PRE>

<P>Without this rule some very nasty backtracking is needed.  For
example, if the injected class name could be qualified by its own
class name, the following code would be well-formed:</P>

<PRE>
    template &lt;class T&gt; struct A {
        template &lt;class T2&gt; A(T2);
        static A x;
    };
    template&lt;&gt; A&lt;int&gt;::A&lt;int&gt;(A&lt;int&gt;::x);
</PRE>

<P>Here the declarator for the definition of the static data member
has redundant parentheses, and it's only after seeing the declarator
that the parser can know that the second <TT>A&lt;int&gt;</TT> is the
injected class name rather than the constructor.</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>In
9 [class]
 paragraph 2, change</P>

<BLOCKQUOTE>
The <I>class-name</I> is also inserted into the scope of the class
itself.  For purposes of access checking the inserted class name...
</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>
The <I>class-name</I> is also inserted into the scope of the class
itself; this is known as the <I>injected-class-name</I>.  For purposes
of access checking, the injected-class-name...
</BLOCKQUOTE>

<P>Also, in 3.4.3.1 [class.qual], add the following
before paragraph 2:</P>

<BLOCKQUOTE>
If the <I>nested-name-specifier</I> nominates a class <TT>C</TT>, and the
name specified after the <I>nested-name-specifier</I>, when looked up in
<TT>C</TT>, is the injected-class-name of <TT>C</TT> (clause
9 [class]), the name is instead considered
to name the constructor of class <TT>C</TT>.  Such a constructor name
shall only be used in the <I>declarator-id</I> of a constructor
definition that appears outside of the class definition.
[<I>Example:</I>

<PRE>
    struct A { A(); };
    struct B: public A { B(); };

    A::A() { }
    B::B() { }

    B::A ba;    // object of type A
    A::A a;     // error, A::A is not a type name
</PRE>

&#8212;<I>end example</I>]
</BLOCKQUOTE>

<P>Also, change 3.4 [basic.lookup] paragraph 3 from</P>

<BLOCKQUOTE>

Because the name of a class is inserted in its class scope (clause
9 [class]), the name of a class is also considered a
member of that class for the purposes of name hiding and lookup.

</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>

The injected-class-name of a class (clause 9 [class]) is
also considered to be a member of that class for the purposes of name
hiding and lookup.

</BLOCKQUOTE>

<P>(See also <A HREF="
     cwg_defects.html#194">issue 194</A>.)</P>
<BR><BR><HR><A NAME="52"></A><H4>52.
  
Non-static members, member selection and access checking
</H4><B>Section: </B>5.2.5&#160; [expr.ref]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>13 Oct 1998<BR>



<P>5.2.5 [expr.ref]
 paragraph 4 should make
it clear that when a nonstatic member is referenced in a member
selection operation, the type of the left operand is implicitly cast
to the naming class of the member. This allows for the detection of
access and ambiguity errors on that implicit cast.</P>

<P><B>Proposed Resolution (10/00):</B></P>

<OL>

<LI><P>In 11.2 [class.access.base] paragraph 4, remove the following
from the second note:</P>

<BLOCKQUOTE>

If the member <TT>m</TT> is accessible when named in the naming
class according to the rules below, the access to <TT>m</TT> is
nonetheless ill-formed if the type of <TT>p</TT> cannot be
implicitly converted to type <TT>T</TT> (for example, if <TT>T</TT> is an
inaccessible base class of <TT>p</TT>'s class).

</BLOCKQUOTE>
</LI>

<LI><P>Add the following as a new paragraph 5 of
11.2 [class.access.base]:</P>

<BLOCKQUOTE>

If a class member access operator, including an
implicit "<TT>this-&gt;</TT>," is used to access a nonstatic
data member or nonstatic member function, the
reference is ill-formed if the left operand
(considered as a pointer in the "." operator case)
cannot be implicitly converted to a pointer to the
naming class of the right operand.  [<I>Note:</I> this
requirement is in addition to the requirement that the
member be accessible as named.]

</BLOCKQUOTE>
</LI>

<LI><P>In 11.2 [class.access.base] paragraph 4, fix a typographical
error by adding the missing right parenthesis following the text</P>

<BLOCKQUOTE>

(including cases where an implicit "<TT>this-&gt;</TT>" is added

</BLOCKQUOTE>
</LI>

<LI><P>Add following the first sentence of
5.2.2 [expr.call] paragraph 4:</P>

<BLOCKQUOTE>

If the function is a nonstatic member function, the
"<TT>this</TT>" parameter of the function (9.3.2 [class.this]) shall
be initialized with a pointer to the object of the
call, converted as if by an explicit type conversion
(5.4 [expr.cast]).  [<I>Note:</I> there is no access checking on
this conversion; the access checking is done as part of
the (possibly implicit) class member access operator.
See 11.2 [class.access.base].]

</BLOCKQUOTE>
</LI>

</OL>
<BR><BR><HR><A NAME="53"></A><H4>53.
  
Lvalue-to-rvalue conversion before certain static_casts
</H4><B>Section: </B>5.2.9&#160; [expr.static.cast]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>13 Oct 1998<BR>



<P>Section 5.2.9 [expr.static.cast]
 paragraph 6
should make it clear that when any of the
"inverse of any standard conversion sequence" static_casts are done, the
operand undergoes the lvalue-to-rvalue conversions first.</P>

<P><B>Proposed Resolution (10/00):</B></P>

<P>In 5.2.9 [expr.static.cast] paragraph 6, change</P>

<BLOCKQUOTE>

can be performed explicitly using <TT>static_cast</TT> subject to the
restriction that the explicit conversion does not cast away constness
(5.2.11 [expr.const.cast]), ...

</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>

can be performed explicitly using <TT>static_cast</TT>.  <SPAN style="font-weight:bold;background-color:#A0FFA0">The
lvalue-to-rvalue (4.1 [conv.lval]), array-to-pointer
(4.2 [conv.array]), and function-to-pointer (4.3 [conv.func]) conversions are applied to the operand.  Such a
<TT>static_cast</TT> is</SPAN> subject to the restriction that it does
not cast away constness (5.2.11 [expr.const.cast]), ...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="128"></A><H4>128.
  
Casting between enum types
</H4><B>Section: </B>5.2.9&#160; [expr.static.cast]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Clark Nelson
 &#160;&#160;&#160;

 <B>Date: </B>10 June 1999<BR>





<P>According to 7.2 [dcl.enum]
 paragraph 9,
it is permitted to convert from one enumeration type to another.
However, neither 5.2.9 [expr.static.cast]

nor 5.4 [expr.cast]
 allows this
conversion.</P>

<P><B>Proposed resolution (10/00):</B> Change the first two sentences of
5.2.9 [expr.static.cast]
 paragraph 7 to read</P>

<BLOCKQUOTE>
A value of integral <SPAN style="font-weight:bold;background-color:#A0FFA0">or enumeration</SPAN> type can be explicitly
converted to an enumeration type.  The value is unchanged if the
<SPAN style="font-weight:bold;background-color:#A0FFA0">original</SPAN> value is within the range of the enumeration values
(7.2 [dcl.enum]
).
</BLOCKQUOTE>
<BR><BR><HR><A NAME="137"></A><H4>137.
  
<TT>static_cast</TT> of <I>cv</I> <TT>void*</TT>
</H4><B>Section: </B>5.2.9&#160; [expr.static.cast]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>13 July 1999<BR>





<P>According to 5.2.9 [expr.static.cast]

paragraph 10,</P>

<BLOCKQUOTE>
An rvalue of type "pointer to <I>cv</I> <TT>void</TT>" can be explicitly
converted to a pointer to object type.
</BLOCKQUOTE>

No requirements are stated regarding the cv-qualification of the
pointer to object type.  Contrast this with the formula used in
paragraphs 5, 8, and 9, where the treatment of cv-qualification
is explicit, requiring that the target type be at least as
cv-qualified as the source.

There is an apparently general requirement on all forms of
<TT>static_cast</TT> in
5.2.9 [expr.static.cast]
 paragraph 1 that it
"shall not cast away constness."
Assuming that this restriction applies to paragraph 10, since there is
no explicit exception to the general rule, that still leaves
open the question of whether one can "cast away volatility"
in a conversion from <TT>volatile void*</TT> to a pointer to object
type.

Should 5.2.9 [expr.static.cast]
 paragraph 10
be rewritten to handle cv-qualification in
the same way as paragraphs 5, 8, and 9?

<P><B>Proposed resolution (10/00):</B></P>

<P>Change the first sentence of
5.2.9 [expr.static.cast]
 paragraph 10 to</P>
<BLOCKQUOTE>
An rvalue of type "pointer to <I>cv1</I> <TT>void</TT>" can be
converted to an rvalue of type "pointer to <I>cv2</I> <TT>T</TT>", where
<TT>T</TT> is an object type and <I>cv2</I> is the same cv-qualification
as, or greater cv-qualification than, <I>cv1</I>.
</BLOCKQUOTE>
<BR><BR><HR><A NAME="74"></A><H4>74.
  
Enumeration value in direct-new-declarator
</H4><B>Section: </B>5.3.4&#160; [expr.new]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>16 Nov 1998<BR>





<P>5.3.4 [expr.new]

paragraph 6 says:</P>
<BLOCKQUOTE>The expression in a <I>direct-new-declarator</I> shall have integral
type (3.9.1 [basic.fundamental]
) with a non-negative
value.</BLOCKQUOTE>
I assume the intent was to also allow enumeral types, as we do in
5.2.1 [expr.sub]

?

<P><B>Proposed Resolution (10/99):</B>
Replace "integral type" by "integral or enumeration type" in
5.3.4 [expr.new]
 paragraph 6.</P>
<BR><BR><HR><A NAME="127"></A><H4>127.
  
Ambiguity in description of matching deallocation function
</H4><B>Section: </B>5.3.4&#160; [expr.new]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Alexander Schiemann
 &#160;&#160;&#160;

 <B>Date: </B>8 June 1999<BR>



<P>If a placement allocation function has default arguments for all its
parameters except the first, it can be called using non-placement
syntax.  In such a case, it is not clear whether
the deallocation function to be called if the constructor terminates
by throwing an expression is determined on the basis of
the syntax of the <I>new-expression</I> (i.e., a non-placement
deallocation function)
or the declaration of the selected (placement) allocation function.
5.3.4 [expr.new]
 paragraph 19 indicates
that the deallocation function must match the declaration of the
allocation function.
However, 15.2 [except.ctor]
 says that the
distinction is based on whether the <I>new-expression</I> contains
a <I>new-placement</I> or not.</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>In 15.2 [except.ctor] paragraph 2, replace</P>

<BLOCKQUOTE>

If the object or array was allocated in a <I>new-expression</I> and
the <I>new-expression</I> does not contain a <I>new-placement</I>, the
deallocation function (3.7.4.2 [basic.stc.dynamic.deallocation], 12.5 [class.free]) is called to free the storage occupied by the object;
the deallocation function is chosen as specified in 5.3.4 [expr.new]. If the object or array was allocated in a
<I>new-expression</I> and the <I>new-expression</I> contains a
<I>new-placement</I>, the storage occupied by the object is
deallocated only if an appropriate placement operator delete is found,
as specified in 5.3.4 [expr.new].

</BLOCKQUOTE>

<P>with</P>

<BLOCKQUOTE>

If the object or array was allocated in a <I>new-expression</I>, the
matching deallocation function (3.7.4.2 [basic.stc.dynamic.deallocation],
5.3.4 [expr.new], 12.5 [class.free]), if any, is
called to free the storage occupied by the object.

</BLOCKQUOTE>

<P>See also <A HREF="
     cwg_defects.html#429">issue 429</A>.</P>

<BR><BR><HR><A NAME="179"></A><H4>179.
  
Function pointers and subtraction
</H4><B>Section: </B>5.7&#160; [expr.add]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>Nov 1999<BR>



<P>5.7 [expr.add]
 paragraph 8 explicitly
allows subtraction of two pointers to functions:</P>

<BLOCKQUOTE>
If two pointers point to the same object <B>or function</B>... and the
two pointers are subtracted...
</BLOCKQUOTE>

However, 5.7 [expr.add]
 paragraph 2
requires that two pointers that are subtracted be pointers to an
<B>object</B> type; function pointers are not allowed.

<P>Being able to subtract two pointers to functions doesn't seem
terribly useful, especially considering that subtracting two pointers
to different functions appears to produce undefined behavior rather
than simply a non-zero result, according to paragraph 6:</P>

<BLOCKQUOTE>
Unless both pointers point to elements of the same array object, or
one past the last element of the array object, the behavior is
undefined.
</BLOCKQUOTE>

<P><B>Proposed resolution (10/00):</B></P>

<P>Remove the words <B>or function</B>
from paragraph 8.</P>
<BR><BR><HR><A NAME="73"></A><H4>73.
  
Pointer equality
</H4><B>Section: </B>5.10&#160; [expr.eq]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Nathan Myers
 &#160;&#160;&#160;

 <B>Date: </B>13 Nov 1998<BR>





<P><U>Nathan Myers</U>: In
5.10 [expr.eq]
, we have:</P>
<BLOCKQUOTE>Pointers to objects or functions of the same type (after pointer
conversions) can be compared for equality. Two pointers of the same type
compare equal if and only if they are both null, both point to the same
object or function, or both point one past the end of the same array.</BLOCKQUOTE>
What does this say, when we have
<PRE>
    int i[1];
    int j[1];
</PRE>
about the expression <TT>(i+1 == j)</TT> ? It seems to require padding
between <TT>i[0]</TT> and <TT>j[0]</TT> so that the comparison will come
out false.
<BR>
<BR>I think this may be a defect, in that the quoted paragraph extends
operator=='s domain too far beyond operator&lt;'s. It should permit
(but not require) an off-the-end pointer to compare equal to another
object, but not to any element of the same array.

<P><U>Mike Miller</U>: I think this is reading more into the statement
in
5.10 [expr.eq]

 paragraph 1 than is actually
there. What does it mean for a pointer to "point to" an object?
I can't find anything that definitively says that <TT>i+1</TT> cannot "point
to" <TT>j[0]</TT> (although it's obviously not required to do so).
If <TT>i+1</TT> is allowed to "point to" <TT>j[0]</TT>, then <TT>i+1==j</TT>
is allowed to be true, and there's no defect. There are places where
aliasing is forbidden, but the N+1th element of an array doesn't appear
to be one of them.</P>

<P>To put it another way, "points to" is undefined in the Standard. The
only definition I can think of that encompasses the possible ways in which
a pointer can get its value (e.g., the implementation-defined conversion
of an arbitrary integer value to a pointer) is that it means "having the
same value representation as would be produced by applying the (builtin)
&amp; operator to an lvalue expression designating that object".
In other words, if the bits are right, it doesn't matter how you produced
the value, as long as you didn't perform any operations that have undefined
results. The expression <TT>i+1</TT> is not undefined, so if the
bits of <TT>i+1</TT> are the same as those of <TT>&amp;j[0]</TT>, then
<TT>i+1</TT> "points to" <TT>j[0]</TT> and <TT>i+i==j</TT> is allowed to
be true.</P>

<P><U>Tom MacDonald</U>: C9X contains the following words for the "=="
operator:</P>
<BLOCKQUOTE>Two pointers compare equal if both are null pointers, both
are pointers to the same object (including a pointer to an object and a
subobject at its beginning) or function, both are pointers to one
past the last element of the same array object, or one is a pointer to
one past the end of one array object and the other is a pointer to the
start of a different array object that happens to immediately follow the
first array object in the address space.</BLOCKQUOTE>
<U>Matt Austern</U>: I don't think there's anything wrong with saying that
the result of
<PRE>
    int x[1];
    int y[1]; 
    std::cout &lt;&lt; (y == x + 1) &lt;&lt; std::endl;
</PRE>
is implementation defined, or even that it's undefined.

<P><U>Mike Miller</U>: A similar question could be raised about different
objects that (sequentially) share the same storage. Consider the following:</P>
<PRE>
    struct B {
        virtual void f();
    };
    struct D1: B { };
    struct D2: B { };
    void g() {
        B* bp1 = new D1;
        B* bp2 = new (bp1) D2;
        bp1 == bp2; // ???
    }
</PRE>
Section
3.8 [basic.life]

 paragraph 5 does
not list this kind of comparison among the pointer operations that cause
undefined behavior, so presumably the comparison is allowed. However,
5.10 [expr.eq]

paragraph 1 describes pointer comparison in terms of "[pointing] to the
same object," which <TT>bp1</TT> and <TT>bp2</TT> clearly do not do. How
should we describe the result of this comparison?

<P><U>Jason Merrill</U>:
When you consider comparing pointers to void, this seems to suggest that no
two objects can have the same address, depending on your interpretation of
"point to the same object."  This would cripple the empty base
optimization.</P>

<P>3.9.2 [basic.compound]
 refers to 'pointers
to void or objects or functions'.  In that case,
5.10 [expr.eq]
 does
not allow you to compare them; it only allows comparing pointers to
objects and functions.</P>

<P><B>Proposed Resolution (10/00):</B></P>

<UL>

<LI>

In 3.9.2 [basic.compound] paragraph 3, add the following
wording immediately preceding, "The value representation of pointer
types is implementation-defined":

<BLOCKQUOTE>

A valid value of an object pointer type represents either the address
of a byte in memory (1.7 [intro.memory]) or a null pointer
(4.10 [conv.ptr]).  If an object of type <TT>T</TT> is
located at an address <TT>A</TT>, a pointer of type <I>cv</I>
<TT>T*</TT> whose value is the address <TT>A</TT> is said to <I>point
to</I> that object, regardless of how the value was obtained.
[<I>Note:</I> for instance, the address one past the end of an array
(5.7 [expr.add]) would be considered to point to an
unrelated object of the array's element type that might be located at
that address.]

</BLOCKQUOTE>

</LI>
<LI>

In 5.10 [expr.eq] paragraph 1, change the sentence
beginning, "Two pointers of the same type..." to read:

<BLOCKQUOTE>

Two pointers of the same type compare equal if and only if they are
both null, both point to the same function, or both represent the same
address (3.9.2 [basic.compound]).

</BLOCKQUOTE>

</LI>
</UL>

<P>(See also paper J16/00-0011 = WG21 N1234.)</P>
<BR><BR><HR><A NAME="188"></A><H4>188.
  
Comma operator and rvalue conversion
</H4><B>Section: </B>5.18&#160; [expr.comma]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>20 Dec 1999<BR>





<P>Given</P>
 
<PRE>
    char arr[100];
    sizeof(0,arr);
</PRE>
 
<P>What does the <TT>sizeof</TT> expression return?  According to
5.18 [expr.comma]
 paragraph 1,
the comma operator yields
an lvalue if the second argument is an lvalue.  Since
4.2 [conv.array]
 paragraph 1 says that the
array-to-pointer conversion yields an rvalue, it seems that
<TT>sizeof</TT> should see an array type and give the answer <TT>100</TT>.
If so, the value of the <TT>sizeof</TT> expression would be
different from that of the corresponding expression in C, but there
is nothing in Annex
C [diff]
to indicate that an incompatible change was intended.</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>Add the following as paragraph 3 of C.1.4 [diff.expr]:</P>

<BLOCKQUOTE>

<P><B>5.16, 5.17, 5.18</B></P>

<P><B>Change:</B> The result of a conditional expression, an
assignment expression, or a comma expression may be an lvalue.<BR>
<B>Rationale:</B> C++ is an object-oriented language, placing
relatively more emphasis on lvalues. For example, functions may return
lvalues.<BR>
<B>Effect on original feature:</B> Change to semantics of well-defined
feature.  Some C expressions that implicitly rely on lvalue-to-rvalue
conversions will yield different results.  For example,

<PRE>
    char arr[100];
    sizeof(0, arr)
</PRE>

yields <TT>100</TT> in C++ and <TT>sizeof(char*)</TT> in C.<BR>
<B>Difficulty of converting:</B> Programs must add explicit casts to
the appropriate rvalue.<BR>
<B>How widely used:</B> Rare.
</P>

</BLOCKQUOTE>
<BR><BR><HR><A NAME="94"></A><H4>94.
  
Inconsistencies in the descriptions of constant expressions
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>8 Feb 1999<BR>





<OL>
<LI>
According to
9.4.2 [class.static.data]
 paragraph 4, a static const integral or const enumeration data member initialized
with an integral constant expression "can appear in integral constant expressions
<SPAN style="font-weight:bold;background-color:#A0FFA0">within its scope</SPAN>" [emphasis mine]. This means that the following
is not permitted:

<PRE>
    struct S {
        static const int c = 5;
    };
    int a[S::c];    // error: S::c not in scope
</PRE>
Is this restriction intentional? If so, what was the rationale for the
restriction?

<P><U>Bjarne Stroustrup</U>: I think that once you have said <TT>S::</TT>,
<TT>c</TT> is in scope so that</P>
<PRE>
    int a[S::c];
</PRE>
is ok.
    
<P><U>Mike Miller</U>: I'd like to think that's what it meant, but I
don't believe that's what it said. According to
3.3 [basic.scope]
 paragraph 1, the scope of
a name is the region "in which that name may be used as an unqualified
name." You can, indeed, use a qualified name to refer to a name that
is not in scope, but that only goes to reinforce my point that
"<TT>S::c</TT>" is not in scope at the point where the expression
containing it is used. I think the phrase "within its scope" is at
best misleading and should be removed. (Unless there's a reason I'm
missing for restricting the use of static member constants to their
scope.)</P>
</LI>
<LI>
According to 5.19 [expr.const]
 paragraph
1, integral constant expressions can "involve...const variables or static
data members of integral or enumeration types initialized with constant
expressions." However, in 5.19 [expr.const]
paragraph 3, arithmetic constant expressions cannot include them. This
seems a rather gratuitous distinction and one likely to bite programmers
trained always to use const variables instead of preprocessor definitions.
Again, is there a rationale for the difference?

<P>As far as I can tell from 5.19 [expr.const]
paragraph 2, "arithmetic constant expressions" (as distinct from "integral
constant expressions") are used only in static initializers to distinguish
between static and dynamic initialization. They include floating point
types and exclude non-type template parameters, as well as the const variables
and static data members.</P>
<LI>
<P>There is a minor error in 5.19 [expr.const]
paragraph 2. The first sentence says, "Other expressions are considered
constant expressions only for the purpose of non-local static object initialization."
However, 6.7 [stmt.dcl]
 paragraph 4 appears
to rely on the same definition dealing with the initialization of local
static objects. I think that the words "non-local" should be dropped and
a cross reference to 6.7 [stmt.dcl]
added.</P>
</LI>
<LI>
5.19 [expr.const]
paragraph 4 says, "An expression
that designates the address of a member or base class of a non-POD class
object (clause 9) is not an address constant expression (12.7 [class.cdtor]
)."
    
<P>I'm guessing that should be "non-static member," like the similar
prohibition in 12.7 [class.cdtor]
 regarding
out-of-lifetime access to members of non-POD class objects.</P></LI></LI></OL>

<P><B>Proposed resolutions (10/00):</B></P>

<OL>
<LI><P>Remove the phrase "within its scope" in
9.4.2 [class.static.data]
 paragraph 4.</P></LI>
<LI>

Replace 5.19 [expr.const] paragraph 3 with the following:

<BLOCKQUOTE>

An <I>arithmetic constant expression</I> shall satisfy the
requirements for an integral constant expression, except that

<UL>
<LI>floating literals need not be cast to integral or enumeration
type, and</LI>
<LI>conversions to floating point types are permitted.</LI>
</UL>

</BLOCKQUOTE>
</LI>
<LI><P>This is not a defect; no change is required.  The suggested
wording would be more accurate, but since the effect on local
initialization is unobservable the current wording is adequate.</P></LI>

<LI><P>Change the referenced sentence in 5.19 [expr.const]
paragraph 4 to "An expression that designates the address of a
subobject of a non-POD class object is not an address constant
expression."</P></LI>
</OL>
<BR><BR><HR><A NAME="227"></A><H4>227.
  
How many scopes in an <TT>if</TT> statement?
</H4><B>Section: </B>6.4&#160; [stmt.select]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Marc Paterno
 &#160;&#160;&#160;

 <B>Date: </B>21 Apr 2000<BR>


<P>The wording of 6.4 [stmt.select] paragraph 1 is
misleading.  Instead of</P>

<BLOCKQUOTE>

The substatement in a <I>selection-statement</I> (both substatements,
in the <TT>else</TT> form of the <TT>if</TT> statement) implicitly
defines a local scope (3.3 [basic.scope]).

</BLOCKQUOTE>

<P>it should say</P>

<BLOCKQUOTE>

... <B>each substatement</B>, in the <TT>else</TT> form...

</BLOCKQUOTE>

<P>As is, one is left with the impression that both "then" and "else"
clauses together form a single scope.</P>

<P><B>Proposed resolution (10/00):</B> As suggested.</P>

<BR><BR><HR><A NAME="69"></A><H4>69.
  
Storage class specifiers on template declarations
</H4><B>Section: </B>7.1.1&#160; [dcl.stc]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Ball
 &#160;&#160;&#160;

 <B>Date: </B>17 Oct 1998<BR>



<P><U>Mike Ball:</U> I cannot find anything in the standard that tells me the meaning of
a <I>storage-class-specifier</I> on a function template declaration. In
particular, there is no indication what effect, if any, it has on the storage
class of the instantiations.</P>

<P>There is an explicit prohibition of <I>storage-class-specifier</I>s
on explicit specializations.</P>

<P>For example, if we have</P>
<PRE>
    template&lt;class T&gt; static int foo(T) { return sizeof(T); }
</PRE>
does this generate static functions for all instantiations? By
7.1.1 [dcl.stc]

the storage class applies to the name declared in the declarator, which
is the template <TT>foo</TT>, not an instantiation of <TT>foo</TT>, which
is named with a <I>template-id</I>. There is a statement in clause
14 that template names have linkage, which supports the contention that
"<TT>static</TT>" applies to the template, not to instantiations.

<P>So what does the specifier mean? Lacking a direct statement in
the standard, I see the following posibilities, in my preference order.</P>
<OL>
<LI>
<I>storage-class-specifier</I>s have no meaning on template declarations,
their use being subsumed by "<TT>export</TT>" (for the template name) and
the unnamed namespace (for instantiations)</LI>

<LI>
<I>storage-class-specifier</I>s have no effect on the template name, but
do affect the linkage of the instantiations, though this now applies linkage
to <I>template-id</I>s, which I can find no support for. I suspect
this is what was intended, though I don't remember</LI>
</OL>
Of course, if anybody can find some concrete statement, that would settle
it.

<P><U>From John Spicer</U></P>

<P>The standard does say that a namespace scope template has external linkage
unless it is a function template declared "static". It doesn't explicitly
say that the linkage of the template is also the linkage of the instantiations,
but I believe that is the intent. For example, a storage class is
prohibited on an explicit specialization to ensure that a specialization
cannot be given a different storage class than the template on which it
is based.</P>
<BLOCKQUOTE><U>Mike</U>: This makes sense, but I couldn't find much support
in the document. Sounds like yet another interpretation to add to
the list.

<P><U>John</U>: Agreed.</P></BLOCKQUOTE>
The standard does not talk about the linkage of instantiations, because
only "names" are considered to have linkage, and instances are not really
names. So, from an implementation point of view, instances have linkage,
but from a language point of view, only the template from which the instances
are generated has linkage.
<BLOCKQUOTE><U>Mike</U>: Which is why I think it would be cleaner to eliminate
storage class specifiers entirely and rely on the unnamed namespace.
There is a statement that specializations go into the namespace of the
template. No big deal, it's not something it says, so we live with
what's there.

<P><U>John</U>: That would mean prohibiting static function templates.
I doubt those are common, but I don't really see much motivation for getting
rid of them at this point.</P></BLOCKQUOTE>
"export" is an additional attribute that is separate from linkage, but
that can only be applied to templates with external linkage.
<BLOCKQUOTE><U>Mike</U>: I can't find that restriction in the standard,
though there is one that templates in an unnamed namespace can't be exported.
I'm pretty sure that we intended it, though.

<P><U>John</U>: I can't find it either. The "inline" case seems to
be addressed, but not static. Surely this is an error as, by definition,
a static template can't be used from elsewhere.</P></BLOCKQUOTE>

<P><B>Proposed resolution (10/00):</B></P>
Change the text in 14 [temp] paragraph 4 from:
<BLOCKQUOTE>
A template name may have linkage (3.5 [basic.link]).
</BLOCKQUOTE>
to:
<BLOCKQUOTE>
A template name has linkage (3.5 [basic.link]).
A non-member function template
can have internal linkage; any other template name shall have external
linkage. Entities generated from a template with internal linkage are distinct
from all entities generated in other translation units.
</BLOCKQUOTE>

<BR><BR><HR><A NAME="56"></A><H4>56.
  
Redeclaring typedefs within classes
</H4><B>Section: </B>7.1.3&#160; [dcl.typedef]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>13 Oct 1998<BR>



<P>Can a typedef redeclaration be done within a class?</P>
<PRE>
    class X { 
        typedef int I; 
        typedef int I; 
    };
</PRE>
See also
9.2 [class.mem]
,
<A HREF="
     cwg_active.html#36">Core issue 36</A>,
and
<A HREF="
     cwg_defects.html#85">Core issue 85</A>.

<P><B>Proposed Resolution (10/99):</B>
Change 7.1.3 [dcl.typedef]
 paragraph 2
from "In a given scope" to "In a given non-class scope."</P>
<BR><BR><HR><A NAME="76"></A><H4>76.
  
Are const volatile variables considered "constant expressions"?
</H4><B>Section: </B>7.1.6.1&#160; [dcl.type.cv]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Judy Ward
 &#160;&#160;&#160;

 <B>Date: </B>15 Dec 1998<BR>



<P>The following code does not compile with the EDG compiler:</P>
<PRE>
    volatile const int a = 5;
    int b[a];
</PRE>
The standard,
7.1.6.1 [dcl.type.cv]
, says:
<BLOCKQUOTE>A variable of const-qualified integral or enumeration type
initialized by an integral constant expression can be used in integral
constant expressions.</BLOCKQUOTE>
This doesn't say it can't be const volatile-qualified, although I think
that was what was intended.

<P><B>Proposed Resolution (10/99):</B>
Change the referenced text in paragraph 2 of
7.1.6.1 [dcl.type.cv]
 to read:</P>

<UL>A variable of <SPAN style="font-weight:bold;background-color:#A0FFA0">non-volatile</SPAN> const-qualified ...</UL>
<BR><BR><HR><A NAME="68"></A><H4>68.
  
Grammar does not allow "friend class A&lt;int&gt;;"
</H4><B>Section: </B>7.1.6.3&#160; [dcl.type.elab]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Ball
 &#160;&#160;&#160;

 <B>Date: </B>17 Oct 1998<BR>



<P>I can't find the answer to the following in the standard. Does
anybody have a reference?</P>

<P>The syntax for elaborated type specifier is
<UL><I>elaborated-type-specifier</I>:
<UL><I>class-key</I> <TT>::</TT><SUB>opt</SUB> <I>nested-name-specifier<SUB>opt</SUB>
identifier</I>
<BR><TT>enum</TT> <TT>::</TT><I><SUB>opt</SUB> nested-name-specifier<SUB>opt</SUB>
identifier</I>
<BR><TT>typename</TT> <TT>::</TT><SUB>opt</SUB>&#160;
<I>nested-name-specifier</I> <I>identifier</I>
<BR><TT>typename</TT> <TT>::</TT><SUB>opt</SUB>&#160;
<I>nested-name-specifier</I> <TT>template</TT><SUB>opt</SUB>&#160;<I>template-id</I></UL>
<BR>
If an <I>elaborated-type-specifier</I> is the sole constituent of a declaration,
the declaration is ill-formed unless it is an explicit specialization
(14.7.3 [temp.expl.spec]
),
an explicit instantiation
(14.7.2 [temp.explicit]
) or it has one of the following
forms:
<BR>
<BR>
<UL><I>class-key</I> <I>identifier</I> <TT>;</TT><BR>
<TT>friend</TT> <I>class-key</I> <I>identifier</I> <TT>;</TT>
<BR><TT>friend</TT> <I>class-key</I> <TT>::</TT> <I>identifier</I> <TT>;</TT>
<BR><TT>friend</TT> <I>class-key</I> <I>nested-name-specifier</I>&#160;<I>identifier</I>&#160;<TT>;</TT></UL>
</UL>
Which does not allow the production</P>
<PRE>
    class foo&lt;int&gt; // foo is a template
</PRE>
On the other hand, a friend declaration seems to require this production,
<BLOCKQUOTE>An <I>elaborated-type-specifier</I> shall be used in a
friend declaration for a class.*

<P>[<I>Footnote:</I> The <I>class-key</I> of the
<I>elaborated-type-specifier</I> is required.
&#8212;<I>end footnote</I>]</P></BLOCKQUOTE>
And in 14.5.4 [temp.friend]
 we find the example
<BLOCKQUOTE>
[<I>Example:</I>
<PRE>
    template&lt;class T&gt; class task;
    template&lt;class T&gt; task&lt;T&gt;* preempt(task&lt;T&gt;*);

    template&lt;class T&gt; class task {
        // ...
        friend void next_time();
        friend void process(task&lt;T&gt;*);
        friend task&lt;T&gt;* preempt&lt;T&gt;(task&lt;T&gt;*);
        template&lt;class C&gt; friend int func(C);

        friend class task&lt;int&gt;;
        template&lt;class P&gt; friend class frd;
        // ...
    };
</PRE>
</BLOCKQUOTE>
Is there some special dispensation somewhere to allow the syntax in this
context?  Is there something I've missed about <I>elaborated-type-specifier</I>?
Is it just another bug in the standard?

<P>An additional problem was reported via <TT>comp.std.c++</TT>: the
grammar does not allow the following example:</P>

<PRE>
    namespace A{
      class B{};
    };

    namespace B{
      class A{};
      class C{
	friend class ::A::B;
      };
    };
</PRE>

<P><B>Proposed resolution (10/00):</B></P>

<P>Change the grammar in 7.1.6.3 [dcl.type.elab] to read<BR>
<UL><I>elaborated-type-specifier:</I>
<UL><I>class-key</I> <TT>::<SUB>opt</SUB></TT>
<I>nested-name-specifier<SUB>opt</SUB> identifier</I></UL>
<UL><I>class-key</I> <TT>::<SUB>opt</SUB></TT>
<I>nested-name-specifier<SUB>opt</SUB></I>
<TT>template<SUB>opt</SUB></TT> <I>template-id</I></UL>
<UL><TT>enum ::<SUB>opt</SUB></TT>
<I>nested-name-specifier<SUB>opt</SUB> identifier</I></UL>
<UL><TT>typename ::<SUB>opt</SUB></TT> <I>nested-name-specifier
identifier</I></UL>
<UL><TT>typename ::<SUB>opt</SUB></TT> <I>nested-name-specifier</I>
<TT>template<SUB>opt</SUB></TT> <I>template-id</I></UL>
</UL>

and change the forms allowed in paragraph 1 to
<UL>
<I>class-key identifier</I> <TT>;</TT><BR>
<TT>friend</TT> <I>class-key</I> <TT>::<SUB>opt</SUB></TT> <I>identifier</I>
<TT>;</TT><BR>
<TT>friend</TT> <I>class-key</I> <TT>::<SUB>opt</SUB></TT> <I>template-id</I>
<TT>;</TT><BR>
<TT>friend</TT> <I>class-key</I> <TT>::<SUB>opt</SUB></TT>
<I>nested-name-specifier identifier</I> <TT>;</TT><BR>
<TT>friend</TT> <I>class-key</I> <TT>::<SUB>opt</SUB></TT>
<I>nested-name-specifier</I> <TT>template<SUB>opt</SUB></TT>
<I>template-id</I> <TT>;</TT>
</UL>
</P>
<BR><BR><HR><A NAME="171"></A><H4>171.
  
Global namespace scope
</H4><B>Section: </B>7.3&#160; [basic.namespace]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Greg Lutz
 &#160;&#160;&#160;

 <B>Date: </B>19 Sep 1999<BR>



<P>7.3 [basic.namespace]
 paragraph 2 says:</P>

<BLOCKQUOTE>
A name declared outside all named namespaces, blocks
(6.3 [stmt.block]
) and
classes (clause 9 [class]
) has
global namespace scope
(3.3.6 [basic.scope.namespace]
).
</BLOCKQUOTE>

But 3.3.6 [basic.scope.namespace]

paragraph 3 says:

<BLOCKQUOTE>
A name declared outside all named or unnamed namespaces
(7.3 [basic.namespace]
),
blocks (6.3 [stmt.block]
),
function declarations
(8.3.5 [dcl.fct]
),
function definitions
(8.4 [dcl.fct.def]
) and classes
(clause 9 [class]
) has global
namespace scope (also called global scope).
</BLOCKQUOTE>

7.3 [basic.namespace]

should evidently be changed to match the wording in
3.3.6 [basic.scope.namespace]

&#8212; the unnamed namespace is <I>not</I> global scope.

<P><B>Proposed resolution (10/00):</B> </P>

<OL>

<LI><P>Replace the first sentence of 3.3.6 [basic.scope.namespace]
paragraph 3 with</P>

<BLOCKQUOTE>

The outermost declarative region of a translation unit is also a
namespace, called the <I>global namespace</I>.  A name declared in the
global namespace has <I>global namespace scope</I> (also called
<I>global scope</I>).

</BLOCKQUOTE>
</LI>

<LI><P>In the last sentence of the same paragraph, change "Names
declared in the global namespace scope" to "Names with global
namespace scope."</P></LI>

<LI><P>Replace 7.3 [basic.namespace] paragraph 2 with

<BLOCKQUOTE>

The outermost declarative region of a translation unit is a namespace;
see 3.3.6 [basic.scope.namespace].

</BLOCKQUOTE>
</P>
</LI>

</OL>

<BR><BR><HR><A NAME="166"></A><H4>166.
  
Friend declarations of <I>template-id</I>s
</H4><B>Section: </B>7.3.1.2&#160; [namespace.memdef]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>8 Sep 1999<BR>





<P><U>John Spicer</U>:
I believe the standard is not clear with respect to this example:</P>

<PRE>
    namespace N {
      template &lt;class T&gt; void f(T);
      namespace M {
        struct A {
          friend void f&lt;int&gt;(int);  // okay - refers to N::f
        };
      }
    }
</PRE>

At issue is whether the friend declaration refers to <TT>N::f</TT>, or
whether it is invalid.

<P>A note in
3.3.2 [basic.scope.pdecl]
 paragraph 6 says</P>

<BLOCKQUOTE>
friend declarations refer to functions or classes
that are members of the nearest enclosing namespace ...
</BLOCKQUOTE>

I believe it
is intended to mean <I>unqualified</I> friend declarations.  Certainly
<TT>friend void A::B()</TT> need not refer
to a member of the nearest enclosing
namespace.  Only when the declarator is unqualified (i.e., it is a declaration
and not a reference) does this rule need to apply.  The presence of an
explicit template argument list requires
that a previous declaration be visible and renders this a reference and not
a declaration that is subject to this rule.

<P><U>Mike Miller</U>:
7.3.1.2 [namespace.memdef]
 paragraph 3 says,</P>

<BLOCKQUOTE>
When looking for a prior declaration of a
class or a function declared as a friend, scopes outside the
innermost enclosing namespace scope are not considered.
</BLOCKQUOTE>

On the other hand, the friend declaration would be a syntax
error if <TT>f</TT> weren't declared as a template name; it would
seem very strange not to find the declaration that made the
friend declaration syntactically correct.

However, it also seems strange to treat this case differently
from ordinary functions and from templates:

<PRE>
    namespace N {
      template &lt;class T&gt; void f(T);
      void g();
      namespace M {
        struct A {
          friend void f&lt;int&gt;(int);               // N::f
          template &lt;class T&gt; friend void f(T);   // M::f
          friend void g();                       // M::g
        };
      }
    }
</PRE>

<P><U>John Spicer</U>:
This section refers to "looking for a prior declaration".  This
gets back to an earlier discussion we've had about the difference between
matching two declarations of the same name and doing name lookup.  I would
maintain that in <TT>f&lt;int&gt;</TT>
the <TT>f</TT> is looked up using a normal lookup.  In
practice, this is really how it has to be done because the declaration
could actually be <TT>f&lt;int&gt;::x</TT>.</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>In
7.3.1.2 [namespace.memdef]
 paragraph 3, change</P>

<BLOCKQUOTE>
When looking for a prior declaration of a class or a function declared
as a friend, scopes outside the innermost enclosing namespace scope are
not considered.
</BLOCKQUOTE>

to

<BLOCKQUOTE>
When looking for a prior declaration of a class or a function declared
as a friend, and when the name of the friend class or function is
neither a qualified name nor a <I>template-id</I>, scopes outside the
innermost enclosing namespace scope are not considered.
</BLOCKQUOTE>

Also, change the example in that paragraph as follows:

<PRE>
    void h(int);
    template &lt;class T&gt; void f2(T);
    namespace A {
        class X {
            friend void f(X);       // A::f(X) is a friend
            friend void f2&lt;&gt;(int);  // ::f2&lt;&gt;(int) is a friend
    ...
</PRE>

<P>(See also issues
<A HREF="
     cwg_closed.html#95">95</A>,
<A HREF="
     cwg_defects.html#136">136</A>,
<A HREF="
     cwg_active.html#138">138</A>,
<A HREF="
     cwg_defects.html#139">139</A>,
<A HREF="
     cwg_defects.html#143">143</A>, and
<A HREF="
     cwg_closed.html#165">165</A>.)</P>
<BR><BR><HR><A NAME="101"></A><H4>101.
  
Redeclaration of extern "C" names via using-declarations
</H4><B>Section: </B>7.3.3&#160; [namespace.udecl]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>10 Mar 1999<BR>





<P>Consider the following:</P>
<PRE>
    extern "C" void f();
    namespace N {
        extern "C" void f();
    }
    using N::f;
</PRE>
According to
7.3.3 [namespace.udecl]

paragraph 11, the <I>using-declaration</I> is an error:
<BLOCKQUOTE>
If a function declaration in namespace scope or block
scope has the same name and the same parameter types
as a function introduced by a <I>using-declaration</I>, the
program is ill-formed.
</BLOCKQUOTE>
Based on the context (7.3.3 [namespace.udecl]

paragraph 10 simply reiterates the requirements
of
3.3 [basic.scope]
), one might wonder if
the failure to exempt <TT>extern&#160;"C"</TT>
functions was intentional or an oversight.  After all, there is
only one function <TT>f()</TT> involved, because it's <TT>extern&#160;"C"</TT>, so
ambiguity is not a reason to prohibit the <I>using-declaration</I>.
<P>
This also breaks the relatively strong parallel between <TT>extern&#160;"C"</TT>
functions and typedefs established in our discussion of
<A HREF="
     cwg_closed.html#14">Core issue 14</A>
in Santa Cruz.  There the question was for <I>using-directives</I>:</P>
<PRE>
    typedef unsigned int size_t;
    extern "C" int f();
    namespace N {
        typedef unsigned int size_t;
        extern "C" int f();
    }
    using namespace N;
    int i = f();        // ambiguous "f"?
    size_t x;           // ambiguous "size_t"?
</PRE>
We decided for both that there was no ambiguity because each
pair of declarations declares the same entity.  (According to
3 [basic]

paragraph 3, a typedef name is not an entity, but a type is; thus the
declarations of <TT>size_t</TT> declare the same entity "<TT>unsigned int</TT>".)
<P>
In the context of <I>using-declaration</I>s, there is no explicit
extension of the restrictions in 3.3 [basic.scope]

paragraph 4 except as noted above for function declarations; thus the parallel
scenario for a typedef is not ill-formed:</P>
<PRE>
    typedef unsigned int size_t;
    namespace N {
        typedef unsigned int size_t;
    };
    using N::size_t;        // okay, both declarations
                            // refer to the same entity
</PRE>
I think the first sentence of
7.3.3 [namespace.udecl]

paragraph 11 ought to be rewritten as:
<BLOCKQUOTE>
If a function declaration in namespace scope or block
scope has the same name and the same parameter types
as a function introduced by a <I>using-declaration</I>,
<SPAN style="font-weight:bold;background-color:#A0FFA0">and the declarations do not declare the same function</SPAN>, the
program is ill-formed.
</BLOCKQUOTE>

<P><B>Proposed Resolution (10/99):</B>
As suggested.</P>
<BR><BR><HR><A NAME="103"></A><H4>103.
  
Is it <I>extended-namespace-definition</I> or <I>extension-namespace-definition</I> ?
</H4><B>Section: </B>7.3.4&#160; [namespace.udir]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Herb Sutter
 &#160;&#160;&#160;

 <B>Date: </B>20 Mar 1999<BR>





<P>
Section 7.3.4 [namespace.udir]

paragraph 3 uses the term <I>extended-namespace-definition</I> three times:</P>
<BLOCKQUOTE>
If a namespace is extended by an <I>extended-namespace-definition</I> after a
<I>using-directive</I> for that namespace is given, the additional members of
the extended namespace and the members of namespaces nominated by
<I>using-directive</I>s in the <I>extended-namespace-definition</I> can be used
after the <I>extended-namespace-definition</I>.
</BLOCKQUOTE>
I think the intent is clear, but unfortunately I cannot find any other
mention (or definition) of this term.
<P>
<U>Mike Miller</U>: True enough; in
Section 7.3.1 [namespace.def]

[the grammar] it's called an <I>extension-namespace-definition</I>.</P>

<P><B>Proposed Resolution (10/99):</B>
Systematically replace "extended-namespace-definition" by "extension-namespace-definition".</P>
<BR><BR><HR><A NAME="40"></A><H4>40.
  
Syntax of <I>declarator-id</I>
</H4><B>Section: </B>8.3&#160; [dcl.meaning]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>01 Sep 1998<BR>



<P>(From J16/99-0005 = WG21 N1182, "Proposed Resolutions for Core
Language Issues 6, 14, 20, 40, and 89")</P>

<P>There are two sub-issues. The first concerns the statement in
8.3 [dcl.meaning]


paragraph 1,</P>
<BLOCKQUOTE>The <I>id-expression</I> of a <I>declarator-id</I> shall be
a simple identifier except for the declaration of some special functions
(12.3 [class.conv]
,
12.4 [class.dtor]
,
13.5 [over.oper]
) and for the declaration
of template specializations or partial specializations
(14.7 [temp.spec]
).</BLOCKQUOTE>
The second sub-issue is regarding another statement in the same paragraph:
<BLOCKQUOTE>A <I>declarator-id</I> shall not be qualified except for the
definition of a member function (9.3 [class.mfct]
)
or static data member (9.4 [class.static]
)
or nested class (9.7 [class.nest]
) outside
of its class, the definition or explicit instantiation of a function, variable
or class member of a namespace outside of its namespace, or...</BLOCKQUOTE>
<U>Analysis</U>

<P>The problem in the first sub-issue is that the wrong syntactic non-terminal
is mentioned. The relevant portions of the grammar are:</P>
<UL><I>declarator-id </I>:
<UL><I>id-expression</I>
<BR><TT>::</TT><SUB>opt</SUB>&#160; <I>nested-name-specifier</I><SUB>opt</SUB>
<I>type-name</I></UL>
<I>id-expression </I>:
<UL><I>unqualified-id</I>
<BR><I>qualified-id</I></UL>
<I>unqualified-id </I>:
<UL><I>identifier</I>
<BR><I>operator-function-id</I>
<BR><I>conversion-function-id</I>
<BR>~ <I>class-name</I>
<BR><I>template-id</I></UL>
</UL>
The exceptions in the citation from
8.3 [dcl.meaning]


paragraph 1 are all the non-identifier cases of <I>unqualified-id</I>:
12.3 [class.conv]


is for <I>conversion-function-id</I>s,
12.4 [class.dtor]


is for destructors,
13.5 [over.oper]

 is
for overloaded operators, and
14.7 [temp.spec]


is for <I>template-id</I>s. If taken literally, this sentence would exclude
all <I>qualified-id</I>s, which it obviously is not intended to do. Instead,
the apparent intent is something along the lines of
<BLOCKQUOTE>If an <I>unqualified-id</I> is used as the <I>id-expression</I>
of a <I>declarator-id</I>, it shall be a simple identifier except...</BLOCKQUOTE>
However, it does not appear that this restriction has any meaning; all
of the possible cases of <I>unqualified-id</I>s are represented in the
list of exceptions! Rather than recasting the sentence into a correct but
useless form, it would be better to remove it altogether.

<P>The second sub-issue deals with the conditions under which a <I>qualified-id</I>
can be used in a declarator, including "the definition of a...nested class"
and "the definition or explicit instantiation of a...class member of a
namespace." However, the name in a class definition is not part of a declarator;
these constructs do not belong in a list of declarator contexts.</P>

<P><B>Proposed Resolution for sub-issue 1 (04/99):</B></P>
<P>The suggested resolution for the first sub-issue overlooked the
fact that the existing wording has the additional effect of prohibiting
the use of the non-identifier syntax for declaring other than the
listed entities.  Thus the proposed wording
for the first sub-issue is:</P>
<P>Change 8.3 [dcl.meaning]
 paragraph 1 from:</P>
<BLOCKQUOTE>The <I>id-expression</I> of a <I>declarator-id</I> shall be a simple <I>identifier</I> except...</BLOCKQUOTE>
to:
<BLOCKQUOTE>An <I>unqualified-id</I> occurring in a <I>declarator-id</I> shall be a simple <I>identifier</I> except...</BLOCKQUOTE>

<P><B>Proposed Resolution for sub-issue 2 (10/99):</B></P>

<P>Change 8.3 [dcl.meaning]
 paragraph 1 from:</P>
<BLOCKQUOTE>A <I>declarator-id</I> shall not be qualified except for the
definition of a member function (9.3 [class.mfct]
)
or static data member (9.4 [class.static]
)
or nested class (9.7 [class.nest]
) outside
of its class, the definition or explicit instantiation of a function, variable
or class member of a namespace outside of its namespace, or...</BLOCKQUOTE>

to

<BLOCKQUOTE>A <I>declarator-id</I> shall not be qualified except for the
definition of a member function (9.3 [class.mfct]
)
or static data member (9.4 [class.static]
)
outside
of its class, the definition or explicit instantiation of a function or
variable member of a namespace outside of its namespace, or...</BLOCKQUOTE>
<BR><BR><HR><A NAME="159"></A><H4>159.
  
Namespace qualification in declarators
</H4><B>Section: </B>8.3&#160; [dcl.meaning]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>23 Aug 1999<BR>



<P>8.3 [dcl.meaning]
 paragraph 1 says:</P>

<BLOCKQUOTE>
In the qualified <I>declarator-id</I> for a class or namespace member
definition that appears outside of the member's class or namespace,
the <I>nested-name-specifier</I> shall not name any of the namespaces that
enclose the member's definition.
</BLOCKQUOTE>

This results in the following behavior:

<PRE>
    namespace N {
        namespace M {
            void f();
            void g();
        }
        void M::f(){}     // okay
        void N::M::g(){}  // error
    }
</PRE>

I was very surprised when this rule was pointed out to me.  The change
appears to have been introduced around the time of the first Santa
Cruz meeting, but I don't recall discussion of it and could not find a
motion related to it.

<P>Regardless of where it came from, I also can't understand why it is there.
Certainly it shouldn't matter <I>how</I> you name a given class or namespace.</P>

<P>For example, the standard permits:</P>

<PRE>
    namespace N {
        namespace M {
            void f();
            void g();
        }
        namespace X = M;
        namespace Y = N::M;
        void X::f(){}  // okay
        void Y::g(){}  // okay
    }
</PRE>

So, it is okay to use an alias for <TT>N::M</TT>,
but not to use <TT>N::M</TT> directly. 
Note that it <I>is</I> okay to use <TT>N::M</TT>
in any other context at this point
in the program (i.e., the rule is a specific restriction on declarator
names, not a general rule on the use of qualified names).

<P>Does anyone recall the intent of this rule or any rationale for its
existence?</P>

<P><B>Notes from 04/00 meeting:</B></P>

<P>There was some question as to whether this issue actually
constituted a defect in the Standard.  John Spicer suggested that
machine-generated source code would be likely to run afoul of this
prohibition.  Francis Glassborow expressed support for a rule that
would allow full qualification, or qualification relative to the
namespace containing the definition, but not qualification relative to
a containing namespace.  There was no consensus for moving forward
with a DR at this point, so the issue was left in "review" status.</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>Remove the last sentence of
8.3 [dcl.meaning] paragraph 1 (cited above) and the example
that follows.</P>

<BR><BR><HR><A NAME="135"></A><H4>135.
  
Class type in in-class member function definitions
</H4><B>Section: </B>8.3.5&#160; [dcl.fct]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Gabriel Netterdag
 &#160;&#160;&#160;

 <B>Date: </B>1 July 1999<BR>





<P>3.2 [basic.def.odr]
 paragraph 4 and
8.3.5 [dcl.fct]
 paragraph 6 indicate that
the return type and parameter types must be complete in a function
definition.  However, when
9.2 [class.mem]
 paragraph 2 lists the
contexts in a class <I>member-specification</I> in which the class
is considered complete, the return type and parameter types of a
member function defined in the class definition are not included.
It thus appears that the following example is ill-formed:</P>

<PRE>
    struct S {
        S f() { return S(); }    // error: incomplete return type
        void g(S) { }            // error: incomplete parameter type
    };
</PRE>

<U>Jack Rouse</U>:
I suggest supplementing the text in 8.3.5p6 with something like:

<BLOCKQUOTE>
The type of a parameter or the return type for a function definition
shall not be an incomplete class type unless the function definition
is nested in the <I>member-specification</I> for that class (including
definitions in nested classes defined within the class).
</BLOCKQUOTE>

<P><B>Proposed resolution (10/00):</B> Replace the last sentence of
8.3.5 [dcl.fct]
 paragraph 6 with</P>
<BLOCKQUOTE>
The type of a parameter or the return type for a function definition
shall not be an incomplete class type (possibly cv-qualified) unless
the function definition is nested within the
<I>member-specification</I> for that class (including definitions in
nested classes defined within the class).
</BLOCKQUOTE>
<BR><BR><HR><A NAME="1"></A><H4>1.
  
What if two using-declarations refer to the same function but the declarations introduce different default-arguments?
</H4><B>Section: </B>8.3.6&#160; [dcl.fct.default]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Bill Gibbons
 &#160;&#160;&#160;

 <B>Date: </B>unknown<BR>





<P>3.3 [basic.scope]
 paragraph 4 says:</P>
<BLOCKQUOTE>
Given a set of declarations in a single declarative region, each of
which specifies the same unqualified name,
<UL><LI>
they shall all refer to the same entity, or all refer to functions ...
</LI></UL>
</BLOCKQUOTE>
8.3.6 [dcl.fct.default]
 paragraph 9 says:
<BLOCKQUOTE>When a declaration of a function is introduced by way of a
<I>using-declaration</I> (7.3.3 [namespace.udecl]),
any default argument information associated with the
declaration is imported as well.</BLOCKQUOTE>
This is not really clear regarding what happens in the following case:
<PRE>
    namespace A {
            extern "C" void f(int = 5);
    }
    namespace B {
            extern "C" void f(int = 7);
    }
     
    using A::f;
    using B::f;
     
    f(); // ???
</PRE>
<B>Proposed resolution (10/00):</B>

<P>Add the following at the end of 13.3.3 [over.match.best]:</P>

<BLOCKQUOTE>
If the best viable function resolves to a function for which
multiple declarations were found, and if at least two of these
declarations &#8212; or
the declarations they refer to in the case of
<I>using-declaration</I>s &#8212; specify
a default argument that made the function viable, the program is ill-formed.
[<I>Example:</I>
<BR><TT>&#160;&#160;&#160; namespace A {</TT>
<BR><TT>&#160;&#160;&#160;&#160;&#160;&#160; extern "C" void f(int = 5);</TT>
<BR><TT>&#160;&#160;&#160; }</TT>
<BR><TT>&#160;&#160;&#160; namespace B {</TT>
<BR><TT>&#160;&#160;&#160;&#160;&#160;&#160; extern "C" void f(int = 5);</TT>
<BR><TT>&#160;&#160;&#160; }</TT>
<P><TT>&#160;&#160;&#160; using A::f;</TT>
<BR><TT>&#160;&#160;&#160; using B::f;</TT></P>
<P><TT>&#160;&#160;&#160; void use() {</TT>
<BR><TT>&#160;&#160;&#160;&#160;&#160;&#160; f(3);&#160;&#160;&#160;&#160;&#160;&#160;
// OK, default argument was not used for viability</TT>
<BR><TT>&#160;&#160;&#160;&#160;&#160;&#160; f();&#160;&#160;&#160;&#160;&#160;&#160;&#160;
// Error: found default argument twice</TT>
<BR><TT>&#160;&#160;&#160; }</TT></P>
<P>&#160; &#8212;<I>end example</I>]</P></BLOCKQUOTE>

<BR><BR><HR><A NAME="65"></A><H4>65.
  
Typo in default argument example
</H4><B>Section: </B>8.3.6&#160; [dcl.fct.default]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>6 Oct 1998<BR>



<P><B>Proposed Resolution (04/99):</B>
Change the text in the example of section 8.3.6 [dcl.fct.default]
 paragraph 5
from:</P>
<BLOCKQUOTE>... <TT>g</TT> will be called with the value <TT>f(1)</TT>.</BLOCKQUOTE>
to:
<BLOCKQUOTE>... <TT>g</TT> will be called with the value <TT>f(2)</TT>.</BLOCKQUOTE>
<BR><BR><HR><A NAME="217"></A><H4>217.
  
Default arguments for non-template member functions of class templates
</H4><B>Section: </B>8.3.6&#160; [dcl.fct.default]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Martin Sebor
 &#160;&#160;&#160;

 <B>Date: </B>22 Mar 2000<BR>




<P>
According to 8.3.6 [dcl.fct.default] paragraphs 4 and 6,

<BLOCKQUOTE>

<P>For non-template functions, default arguments can be added in later
declarations of a function in the same scope.</P>

<P>The default arguments in a member function definition that appears
outside of the class definition are added to the set of default
arguments provided by the member function declaration in the class
definition.</P>

</BLOCKQUOTE>
</P>

<P>This would appear to allow the following example, in which a
default argument is added to a non-template member function of a class
template:</P>

<PRE>
    template &lt;class T&gt;
    struct S
    {
	void foo (int);
    };

    template &lt;class T&gt;
    void S&lt;T&gt;::foo (int = 0) { }
</PRE>

<P><U>John Spicer</U>:
The wording "non-template
functions" is somewhat unclear with respect to member functions of class
templates, but I know that this was intended to include them because it
originates from issue 3.13 of the template issues list that I maintained for
several years.</P>

<P>Having said that, the rationale for this restriction has since been made
obsolete, so this could (in theory) be changed in the standard if it is
problematic for users.</P>

<P>(See also <A HREF="
     cwg_active.html#205">issue 205</A>.)</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>In 8.3.6 [dcl.fct.default] paragraph 6, replace</P>

<BLOCKQUOTE>

The default arguments in a member function definition that appears
outside of the class definition are added to the set of default
arguments provided by the member function declaration in the class
definition.

</BLOCKQUOTE>

<P>with</P>

<BLOCKQUOTE>

Except for member functions of class templates, the default arguments
in a member function definition that appears outside of the class
definition are added to the set of default arguments provided by the
member function declaration in the class definition.  Default
arguments for a member function of a class template must be specified
on the initial declaration of the member function within the class
template.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="35"></A><H4>35.
  
Definition of default-initialization
</H4><B>Section: </B>8.5&#160; [dcl.init]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Andrew Koenig
 &#160;&#160;&#160;

 <B>Date: </B>29 Jul 1998<BR>





<P>Given:</P>
<PRE>
    struct S1 {
        int x;
    };
    
    struct S2 {
        int x;
        double y;
    };
    
    struct S3 {
        int x;
        double y;
        string s;
    };
</PRE>
Once upon a time, we went through a fairly protracted discussion to ensure
that <TT>S1().x</TT> would be guaranteed to be 0. Note that if we declare
<PRE>
    void f()
    {
        S1 s1;
    
        // ...
    }
</PRE>
there is no guarantee of the value of <TT>s1.x</TT>, and that is intentional.
But <TT>S1().x</TT> is different, because <TT>S1()</TT> is an rvalue, and
unless all of its members are defined, the effect of copying it is undefined.

<P>Similarly, <TT>S2().x</TT> and <TT>S2().y</TT> are also defined to be
equal to zero, and here it really matters for many implementations, because
if <TT>S2().y</TT> is just a bunch of random bits, it is entirely possible
that trying to copy <TT>S2().y</TT> will yield a floating-point trap.</P>

<P>However, rather to my surprise, the standard does not define the value
of <TT>S3().x</TT> or <TT>S3().y</TT>, because <TT>S3</TT> is not a POD.
It does define <TT>S3().s</TT> (by running the string constructor), but
once a structure is no longer a POD, the values of uninitialized members
are no longer guaranteed in expressions of the form T().</P>

<P>In my opinion, this definition is a mistake, and the committee's intention
was to zero-initialize all members that do not have an explicitly defined
constructor, whether or not the class is a POD.</P>

<P> See also paper J16/99-0014 = WG21 N1191.</P>

<P><I>[Note: this issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#178">issue 178</A>.]</I></P>
<BR><BR><HR><A NAME="151"></A><H4>151.
  
Terminology of zero-initialization
</H4><B>Section: </B>8.5&#160; [dcl.init]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Valentin Bonnard
 &#160;&#160;&#160;

 <B>Date: </B>4 August 1999<BR>



<P>In 3.6.2 [basic.start.init]
 paragraph 1 and
8.5 [dcl.init]
 paragraphs 5 and 6, the
terms "memory" and "storage" are used in connection with
zero-initialization.  This is inaccurate; it is the variables that are
zero-initialized, not the storage.  (An all-zero bit pattern in the
storage may, in fact, not correspond to the representation of zero
converted to the appropriate type, and it is the latter that is being
described.)</P>

<P>Suggested resolution: remove the words "storage" and "memory" in
these contexts.</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>
Delete the words "The storage for" from the first sentence of
3.6.2 [basic.start.init]
 paragraph 1.</P>

<P><I>[Note: Revised wording in 8.5 [dcl.init]
relating to this issue is also found
in <A HREF="
     cwg_defects.html#178">issue 178</A>.]</I></P>
<BR><BR><HR><A NAME="178"></A><H4>178.
  
More on value-initialization
</H4><B>Section: </B>8.5&#160; [dcl.init]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Andrew Koenig
 &#160;&#160;&#160;

 <B>Date: </B>25 Oct 1999<BR>



<P>When the Committee considered
<A HREF="
     cwg_defects.html#35">issue 35</A>, another context in which
value initialization might be relevant was overlooked:
<I>mem-initializer</I>s.  It would seem reasonable that if
<TT>T()</TT> as an expression invokes value initialization, that the
same syntactic construct in a <I>mem-initializer-list</I> would do the
same, and the usefulness of value initialization in that context is at
least as great as the standalone case.</P>

<P><B>Proposed resolution (10/00):</B></P>

<P><I>[Note: this resolution supersedes the resolution to
<A HREF="
     cwg_defects.html#35">issue 35</A>.]</I></P>

<P>In 5.2.3 [expr.type.conv] paragraph 2, replace "whose value
is determined by default-initialization" by "which is
value-initialized".
</P>

<P>In 5.3.4 [expr.new] paragraph 15,</P>

<UL>

<LI>In the first subitem of the first item, restore the missing
period at the end of the first sentence.</LI>

<LI>In the second item, replace the text after the comma by
"the item is value-initialized (8.5 [dcl.init])".</LI>

</UL>

<P>Replace 8.5 [dcl.init] paragraph 5 by:</P>

<BLOCKQUOTE>

<P>To <I>zero-initialize</I> an object of type <TT>T</TT> means:</P>

<UL>

<LI>if <TT>T</TT> is a scalar type (3.9 [basic.types]), the
object is set to the value of 0 (zero) converted to <TT>T</TT>;</LI>

<LI>if <TT>T</TT> is a non-union class type, each non-static data
member and each base-class subobject is zero-initialized;</LI>

<LI>if <TT>T</TT> is a union type, the object's first named data member
[<I>Footnote:</I> This member must not be <TT>static</TT>, by virtue
of the requirements in 9.5 [class.union]. <I>end
footnote</I>] is zero-initialized;</LI>

<LI>if <TT>T</TT> is an array type, each element is
zero-initialized;</LI>

<LI>if <TT>T</TT> is a reference type, no initialization is
performed.</LI>

</UL>

<P>To <I>default-initialize</I> an object of type <TT>T</TT> means:</P>

<UL>

<LI>if <TT>T</TT> is a non-POD class type (clause 9 [class]), the default constructor for <TT>T</TT> is called (and the
initialization is ill-formed if <TT>T</TT> has no accessible default
constructor);</LI>

<LI>if <TT>T</TT> is an array type, each element is
default-initialized;</LI>

<LI>otherwise, the object is zero-initialized.</LI>

</UL>

<P>To <I>value-initialize</I> an object of type <TT>T</TT> means: </P>

<UL>

<LI>if <TT>T</TT> is a class type (clause 9 [class])
with a user-declared constructor (12.1 [class.ctor]), then
the default constructor for <TT>T</TT> is called (and the
initialization is ill-formed if <TT>T</TT> has no accessible default
constructor);</LI>

<LI>if <TT>T</TT> is a non-union class type without a user-declared
constructor, then every non-static data member and base-class
component of <TT>T</TT> is value-initialized;</LI>

<LI>if <TT>T</TT> is an array type, then each element is
value-initialized; </LI>

<LI>otherwise, the object is zero-initialized. </LI>

</UL>

<P>A program that calls for default-initialization of an entity of
reference type is ill-formed.  If <TT>T</TT> is a cv-qualified type,
the cv-unqualified version of <TT>T</TT> is used for these definitions
of zero-initialization, default-initialization, and
value-initialization.</P>

</BLOCKQUOTE>

<P>In 8.5 [dcl.init] paragraph 6, change "The memory
occupied by any" to "Every".</P>


<P>In 8.5 [dcl.init] paragraph 7, replace
"default-initialized" by "value-initialized".</P>


<P>In 8.5.1 [dcl.init.aggr] paragraph 7, replace
"default-initialized" by "value-initialized".</P>


<P>In 12.3.1 [class.conv.ctor] paragraph 2, insert "or
value-initialization" after the first occurrence of
"default-initialization".</P>


<P>In 12.6 [class.init] paragraph 1, replace the note by "The
object is default-initialized if there is no initializer, or
value-initialized if the initializer is <TT>()</TT>" [i.e., replace
the non-normative note by different, normative text].</P>


<P>In 12.6.1 [class.expl.init] paragraph 2, replace
"default-initialized" by "value-initialized".</P>


<P>In 12.6.2 [class.base.init] paragraph 3, replace
"default-initialized" by "value-initialized" in the first bulleted
item.</P>

<P>In 12.6.2 [class.base.init] paragraph 4, replace
"default-initialized, nor initialized" by "default-initialized, nor
value-initialized, nor assigned".</P>

<BR><BR><HR><A NAME="304"></A><H4>304.
  
Value-initialization of a reference
</H4><B>Section: </B>8.5&#160; [dcl.init]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>25 Jul 2001<BR>




<P>Another glitch in the TC1/<A HREF="
     cwg_defects.html#178">core issue 178</A>
definition of value-initialization:
it's no longer an error to value-initialize a reference.  That makes an example
like
<PRE>
typedef struct { int &amp;r; } S;
int main() {
  S();  // Error in C++98, okay in TC1!
}
</PRE>
valid, which has got to be wrong.  See 8.5 [dcl.init] paragraph
5, where there is wording that forbids default-initialization of a
reference, but not value-initialization thereof. As noted in
<A HREF="
     cwg_defects.html#302">issue 302</A>, if
the default constructor were required to be generated when a
value-initialization is done, that would force an error.</P>

<P><B>Proposed resolution (10/01):</B></P>

<P>Add the indicated wording to the indicated sentence in
8.5 [dcl.init] paragraph 5:</P>
<BLOCKQUOTE>
A program that calls for default-initialization <SPAN style="font-weight:bold;background-color:#A0FFA0">or value-initialization</SPAN>
of an entity of reference type is ill-formed.
</BLOCKQUOTE>



<BR><BR><HR><A NAME="163"></A><H4>163.
  
Description of subaggregate initializer
</H4><B>Section: </B>8.5.1&#160; [dcl.init.aggr]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>12 Aug 1999<BR>



<P>8.5.1 [dcl.init.aggr]
 paragraph 2 says,</P>

<BLOCKQUOTE>
When an aggregate is initialized the <I>initializer</I> can be an
<I>initializer-clause</I> consisting of a brace-enclosed,
comma-separated list of <I>initializer</I>s for the members of the
aggregate.
</BLOCKQUOTE>

Neither of these uses of the syntactic nonterminal <I>initializer</I>
corresponds to the grammar:

<UL>
<I>initializer</I>:
<UL><TT>=</TT> <I>initializer-clause</I></UL>
<UL><TT>(</TT> <I>expression-list</I> <TT>)</TT></UL>
</UL>

<P><B>Proposed resolution (10/99):</B> replace the quoted words with:</P>

<BLOCKQUOTE>
When an aggregate is initialized the <I>initializer</I> can
<SPAN style="font-weight:bold;background-color:#A0FFA0">contain</SPAN> an <I>initializer-clause</I> consisting of a
brace-enclosed, comma-separated list of
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>initializer-clause</I>s</SPAN> for the members of the aggregate.
</BLOCKQUOTE>
<BR><BR><HR><A NAME="148"></A><H4>148.
  
POD classes and pointers to members
</H4><B>Section: </B>9&#160; [class]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Nathan Sidwell
 &#160;&#160;&#160;

 <B>Date: </B>31 Jul 1999<BR>



<P>3.9 [basic.types]
 paragraph 10
defines pointer to member types to be scalar types. It
also defines scalar types to be one of the POD types.</P>

<P>9 [class]
 paragraph 4
defines a POD struct as an aggregate class with no non-static data
members of type pointer to member.</P>

<P>It seems contradictory that a type can be POD,
yet a class containing that type
is non-POD.</P>

<P>Suggested resolution:
Alter 9 [class]
 paragraph 4
to allow pointer to member objects as non-static data members of POD
class.</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>In 9 [class] paragraph 4, remove all occurrences of
"pointer to member."</P>
<BR><BR><HR><A NAME="176"></A><H4>176.
  
Name injection and templates
</H4><B>Section: </B>9&#160; [class]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>21 February 1999<BR>



<P>There is some controversy about whether class name injection applies
to class templates.  If it does apply, what is injected?  Is a class
name injected or is the thing that is injected actually a template?</P>

<P>Clause 9 [class]
 paragraph 2 says,</P>
<BLOCKQUOTE>
The <I>class-name</I> is also inserted into the scope of the class
itself.
</BLOCKQUOTE>

In general, clause 9 applies to both classes and class templates, so I
would take this to mean that class name imjection does indeed apply to
class templates.  One problem with this is that clause 9 uses the
syntactic term <I>class-name</I>, which I would take to imply that the
inserted name is always a class.  This is clearly unacceptable for
class templates as it makes the template itself unusable from with the
template.  For example:

<PRE>
    template &lt;class T&gt; struct A {
        A&lt;T*&gt; ptr;    // Invalid: A refers to a class
    };
</PRE>

<P>Clearly the injected name must be usable as both a class and a
class template.  This kind of magic already exists in the standard.
In 14.6.1 [temp.local]
 it says,</P>

<BLOCKQUOTE>
Within the scope of a class template, when the name of the template is
neither qualified nor followed by <TT>&lt;</TT>, it is equivalent to
the name of the template followed by the
<I>template-parameter</I>s enclosed in &lt;&gt;.
</BLOCKQUOTE>

<P>The proposal here is that we clarify that name injection does
indeed apply to class templates, and that it is the injected name that
has the special property of being usable as both a class and a
template name (as described in
14.6.1 [temp.local]
).  This would eliminate
the need for special wording regarding the qualification of the name,
but would achieve the same result.  This would also make this
"special" name available to a derived class of a class template
&#8212; something which is necessary if the benefits of class name
injection are to be made uniformly available for class templates, too.</P>

<PRE>
    template &lt;class T&gt; struct Base {
        Base* p;
        Base&lt;T*&gt;* p2;
        ::Base* p3;    // Error: only injected name usable as class
    };

    template &lt;class T&gt; struct Derived: public Base&lt;T&gt; {
        Base* p;    // Now okay
        Base&lt;T*&gt;* p2;    // Still okay
        Derived::Base* p3;    // Now okay
</PRE>

Note that by giving the special attribute of being usable as both a
class and a template to the injected name it is now clear where this
attribute can and cannot be used.

<P>(See paper J16/99-0010 = WG21 N1187.)</P>

<P><B>Proposed resolution (10/00):</B></P>

<P><I>[Note: these changes depend on the resolution for <A HREF="
     cwg_defects.html#147">issue 147</A>.]</I></P>

<P>Replace 14.6.1 [temp.local] paragraphs 1 and 2 with the
following:</P>

<BLOCKQUOTE>

<P>Like normal (non-template) classes, class templates have an
injected-class-name (clause 9 [class]).  The
injected-class-name can be used with or without a
<I>template-argument-list</I>.  When it is used without a
<I>template-argument-list</I>, it is equivalent to the
injected-class-name followed by the <I>template-parameter</I>s of the
class template enclosed in <TT>&lt;&gt;</TT>.  When it is used with a
<I>template-argument-list</I>, it refers to the specified class
template specialization, which could be the current specialization or
another specialization.</P>

<P>Within the scope of a class template specialization or partial
specialization, when the injected-class-name is not followed by a
<TT>&lt;</TT>, it is equivalent to the injected-class-name followed by
the <I>template-argument</I>s of the class template specialization or
partial specialization enclosed in <TT>&lt;&gt;</TT>.
[<I>Example:</I></P>

<PRE>
    template&lt;class T&gt; class Y;
    template&lt;&gt; class Y&lt;int&gt; {
        Y* p;          // <I>meaning</I> Y&lt;int&gt;
        Y&lt;char&gt;* q;    // <I>meaning</I> Y&lt;char&gt;
    };
</PRE>

<P>&#8212;<I>end example</I>]</P>

<P>The injected-class-name of a class template or class template
specialization can be used either with or without a
<I>template-argument-list</I> wherever it is in scope.
[<I>Example:</I></P>

<PRE>
    template &lt;class T&gt; struct Base {
        Base* p;
    };

    template &lt;class T&gt; struct Derived: public Base&lt;T&gt; {
        typename Derived::Base* p;  // <I>meaning</I> Derived::Base&lt;T&gt;
    };
</PRE>

<P>&#8212;<I>end example</I>]</P>

<P>A lookup that finds an injected-class-name (10.2 [class.member.lookup]) can result in an ambiguity in certain cases (for
example, if it is found in more than one base class).  If all of the
injected-class-names that are found refer to specializations of the
same class template, and if the name is followed by a
<I>template-argument-list</I>, the reference refers to the class
template itself and not a specialization thereof, and is not
ambiguous.  [<I>Example:</I></P>

<PRE>
    template &lt;class T&gt; struct Base { };
    template &lt;class T&gt; struct Derived: Base&lt;int&gt;, Base&lt;char&gt; {
        typename Derived::Base b;            // <I>error: ambiguous</I>
        typename Derived::Base&lt;double&gt; d;    // <I>OK</I>
    };
</PRE>

<P>&#8212;<I>end example</I>]</P>

<P>When the normal name of the template (i.e., the name from the
enclosing scope, not the injected-class-name) is used without a
<I>template-argument-list</I>, it refers to the class template itself
and not a specialization of the template.  [<I>Example:</I></P>

<PRE>
    template &lt;class T&gt; class X {
        X* p;         // <I>meaning</I> X&lt;T&gt;
        X&lt;T&gt;* p2;
        X&lt;int&gt;* p3;
        ::X* p4;      // <I>error: missing template argument list</I>
                      // ::X <I>does not refer to the injected-class-name</I>
    };
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="75"></A><H4>75.
  
In-class initialized members must be const
</H4><B>Section: </B>9.2&#160; [class.mem]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Wiegley
 &#160;&#160;&#160;

 <B>Date: </B>29 Dec 1998<BR>





<P>The standard says, in
9.2 [class.mem]

paragraph 4:</P>
<BLOCKQUOTE>A <I>member-declarator</I> can contain a
<I>constant-initializer</I> only
if it declares a <TT>static</TT> member
(9.4 [class.static]
)
of integral or enumeration type, see
9.4.2 [class.static.data]
.</BLOCKQUOTE>
But later, in the section on static class data member initialization,
9.4.2 [class.static.data]

paragraph 4, it says:
<BLOCKQUOTE>
If a <TT>static</TT> data member is of <TT>const</TT> integral
or <TT>const</TT> enumeration
type, its declaration in the class definition can specify a
<I>constant-initializer</I> which shall be an integral constant expression
(5.19 [expr.const]
). In that case, the
member can appear in integral constant expressions within its scope.
</BLOCKQUOTE>
The first paragraph should be modified to make it clear that it is not possible
to initialize a static data member in-line with a constant-initializer if that
data member is of integral (or enumeration) type, and yet not const.

<P><B>Proposed Resolution (10/99):</B>
Change the sentence in 9.2 [class.mem]
 paragraph 4 to read:</P>
<BLOCKQUOTE>
A <I>member-declarator</I> can contain a <I>constant-initializer</I>
only if it declares a <TT>static</TT> member
(9.4 [class.static]
)
of <TT>const</TT> integral or <TT>const</TT> enumeration type,
see 9.4.2 [class.static.data]
.
</BLOCKQUOTE>
<BR><BR><HR><A NAME="80"></A><H4>80.
  
Class members with same name as class
</H4><B>Section: </B>9.2&#160; [class.mem]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>5 Dec 1998<BR>





<P>Between the May '96 and September '96 working papers, the text in
9.2 [class.mem]

paragraph 13:</P>
<BLOCKQUOTE>If <TT>T</TT> is the name of a class, then each of the following
shall have a name different from <TT>T</TT>:
<UL><LI>
every static data member of class <TT>T</TT>;</LI></UL></BLOCKQUOTE>
was changed by removing the word 'static'. Looking over the meeting
minutes from Stockholm, none of the proposals seem to include this
change, which breaks C compatibility and is not mentioned in the compatibility
annex. Was this change actually voted in by the committee?

<P>Specifically, this breaks <TT>/usr/include/netinet/in.h</TT> under Linux,
in which "<TT>struct ip_opts</TT>" shares its name with one of its members.</P>

<P><B>Proposed resolution (10/00):</B></P>
<OL>
<LI>
Change the first bullet of
9.2 [class.mem]
 paragraph 13 to say
<UL>
<LI>
every static data member of class <TT>T</TT>;</LI>
</UL>
<LI>
Add another paragraph before
9.2 [class.mem]
 paragraph 14, reading
<BLOCKQUOTE>
In addition, if class <TT>T</TT> has a user-declared constructor
(12.1 [class.ctor]
), every nonstatic
data member of class <TT>T</TT> shall have a name different from
<TT>T</TT>.
</BLOCKQUOTE>
</LI>
</LI>
</OL>
<BR><BR><HR><A NAME="190"></A><H4>190.
  
Layout-compatible POD-struct types
</H4><B>Section: </B>9.2&#160; [class.mem]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>20 Dec 1999<BR>





<P>The definition of layout-compatible POD-struct types in
9.2 [class.mem]
 paragraph 14 requires that
the two types</P>

<BLOCKQUOTE>
have the same number of members, and corresponding members (in order)
have layout-compatible types (3.9).
</BLOCKQUOTE>

There does not appear to be any reason for including member functions
and static data members in this requirement.  It would be more logical
to require only that the non-static data members of the two types must
match.

<P>The characteristics of layout-compatible types are not well
described in the current wording, either.  Apart from their use in
9.2 [class.mem]
 paragraph 16 to define the
term "common initial sequence," there appears to be nothing said about
which operations are possible between objects of layout-compatible types.
For example, 3.9 [basic.types]
 paragraphs
2-3 give certain guarantees regarding use of <TT>memcpy</TT> on
objects of the same type; it might be reasonable to assume that the
same kinds of guarantees might apply to objects of layout-compatible
types, but that is not said.  Similarly,
3.10 [basic.lval]
 paragraph 15 describes
permissible "type punning" but does not mention layout-compatible types.</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>In 9.2 [class.mem] paragraphs 14 and 15, change all
occurrences of "members" to "nonstatic data members."</P>
<BR><BR><HR><A NAME="67"></A><H4>67.
  
Evaluation of left side of object-expression
</H4><B>Section: </B>9.4&#160; [class.static]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>6 Oct 1998<BR>



<P>Paragraph 2 says that "the object-expression is always evaluated" when
the class member syntax is used to refer to a static member. This
presumably should say that the object expression is evaluated if the member
access is performed, i.e., not if the overall expression is the operand
of <TT>sizeof</TT> or the unevaluated branch of <TT>?:</TT>, <TT>||</TT>, or <TT>&amp;&amp;</TT>.</P>

<P><B>Proposed Resolution (10/99):</B>
Replace "is always evaluated" by "is evaluated" in
9.4 [class.static]
 paragraph 2.</P>
<BR><BR><HR><A NAME="48"></A><H4>48.
  
Definitions of unused static members
</H4><B>Section: </B>9.4.2&#160; [class.static.data]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Bill Gibbons
 &#160;&#160;&#160;

 <B>Date: </B>23 Nov 1997<BR>



<P>Also see section: 3.2 [basic.def.odr]
.</P>

<P>Originally, all static data members still had to be defined outside the
class whether they were used or not.</P>

<P>But that restriction was supposed to be lifted so that static
data members need not be defined outside the class unless they are used
in a manner which requires their definition,
in the same manner as namespace-scope
variables. In particular, if an integral/enum const static data member
is initialized within the class, and its address is never taken, we agreed
that no namespace-scope definition was required.</P>

<P>For example:</P>
<PRE>
    struct A {
        static const int size = 10;
        int array[size];
    };
    
    int main() {
        A a;
        return 0;
    }
</PRE>
However, 9.4.2 [class.static.data]
 paragraph 4 says:
<BLOCKQUOTE>The member shall still be defined in a namespace scope if it
is used in the program and the namespace scope definition shall not contain
an initializer.</BLOCKQUOTE>
A narrow interpreration of "used" in this rule would make the example ill-formed
because there is no namespace-scope definition of "<TT>size</TT>".
A better wording for this rule would be:
<BLOCKQUOTE>The member shall still be defined in a namespace scope if it
is used in the program in the manner described in 3.2 [basic.def.odr]
.
The namespace scope definition shall not contain an initializer.</BLOCKQUOTE>
Also, the wording in 3.2 [basic.def.odr]
 paragraph 2:
<BLOCKQUOTE>An expression is potentially evaluated unless either it is
the operand of the <TT>sizeof</TT> operator (5.3.3 [expr.sizeof]
), or it is the operand
of the <TT>typeid</TT> operator and does not designate an lvalue of polymorphic
class type (5.2.8 [expr.typeid]
).</BLOCKQUOTE>
is incomplete because it does not mention the use of a compile-time constant
as an array bound or template argument. It should say something like:
<BLOCKQUOTE>An expression is potentially evaluated unless it is the operand
of the sizeof operator (5.3.3 [expr.sizeof]
), the operand of the typeid operator,
<U>an <I>integral constant-expression</I> used as an array bound or an
<I>integral constant-expression</I> used as a <I>template-argument</I>
for a non-reference <I>template-parameter</I></U>; and the expression
does not designate an lvalue of polymorphic class type (5.2.8 [expr.typeid]
).</BLOCKQUOTE>

<P><B>Proposed Resolution (04/99):</B>
Change the first sentence of 3.2 [basic.def.odr]

paragraph 2 from:</P>
<BLOCKQUOTE>An expression is <I>potentially evaluated</I> unless either
it is the operand of the <TT>sizeof</TT> operator (5.3.3 [expr.sizeof]
), or it is the
operand of the <TT>typeid</TT> operator and does not designate an lvalue
of polymorphic class type (5.2.8 [expr.typeid]
).</BLOCKQUOTE>
to:
<BLOCKQUOTE>An expression is <I>potentially evaluated</I> unless <U>it
appears where an <I>integral constant expression</I> is required (see 5.19 [expr.const]
),
is
</U>the operand of the <TT>sizeof</TT> operator (5.3.3 [expr.sizeof]
), or
is the operand of the <TT>typeid</TT> operator and the expression does
not designate an lvalue of polymorphic class type (5.2.8 [expr.typeid]
).</BLOCKQUOTE>
<BR><BR><HR><A NAME="142"></A><H4>142.
  
Injection-related errors in access example
</H4><B>Section: </B>11.2&#160; [class.access.base]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>16 Jul 1999<BR>





<P>In the example in paragraph 3 of
11.2 [class.access.base]
, all the references
to <TT>B</TT> in <TT>DD::f()</TT> should be replaced by <TT>::B</TT>.
The reason is that the class name <TT>B</TT> is private in <TT>D</TT>
and thus inaccessible in <TT>DD</TT>.  (The example was probably not
updated when class name injection was added.)</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>Replace the example in
11.2 [class.access.base]
 paragraph 3 with:</P>
<PRE>
    class B {
    public:
        int mi;                 // nonstatic member
        static int si;          // static member
    };
    class D: private B {
    };
    class DD: public D {
        void f();
    };
    void DD::f() {
        mi = 3;                 // error: mi is private in D
        si = 3;                 // error: si is private in D
        ::B b;
        b.mi = 3;               // OK (b.mi is different from this-&gt;mi)
        b.si = 3;               // OK (b.si is different from this-&gt;si)
        ::B::si = 3;            // OK
        ::B* bp1 = this;        // error: B is a private base class
        ::B* bp2 = (::B*)this;  // OK with cast
        bp2-&gt;mi = 3;            // OK: access through a pointer to B
    }
</PRE>
<BR><BR><HR><A NAME="161"></A><H4>161.
  
Access to protected nested type
</H4><B>Section: </B>11.4&#160; [class.protected]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>26 Aug 1999<BR>



<P>11.4 [class.protected]
 paragraph 1 begins:</P>

<BLOCKQUOTE>
When a friend or a member function of a derived class references a
protected nonstatic member of a base class, an access check applies in
addition to those described earlier in clause
11 [class.access]
.
</BLOCKQUOTE>

<P>This was intended to refer to nonstatic member functions and
nonstatic data members.  However, a protected nested type declared
in a base class is, by
some definition of the word, a "nonstatic" member, and therefore subject
to this additional access check.</P>

<P><B>Proposed resolution (10/99):</B>
change "protected nonstatic member" in the above to
"protected nonstatic member function or protected nonstatic data member"
to make the intent clear.</P>
<BR><BR><HR><A NAME="194"></A><H4>194.
  
Identifying constructors
</H4><B>Section: </B>12.1&#160; [class.ctor]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jamie Schmeiser
 &#160;&#160;&#160;

 <B>Date: </B>11 Jan 2000<BR>





<P>According to 12.1 [class.ctor]
 paragraph
1, the syntax used in declaring a constructor allows at most one
<I>function-specifier</I>.  It is thus not permitted to declare a
constructor both <TT>inline</TT> and <TT>explicit</TT>.  This seems
overly restrictive.</P>

<P>On a related note, there doesn't seem to be any explicit
prohibition against member functions with the same name as the class.
(Such a prohibition might reasonably be expected to occur in
9.2 [class.mem]
 paragraph 13, but member
functions are not listed there.)</P>

<P>One possible interpretation would be that such member functions
would violate the restrictions in
3.3.7 [basic.scope.class]
 paragraph 1,
because the class name would refer to the class at some points in the
class scope and to the member function at others.  However, this seems
a bit tenuous.  Is an explicit prohibition needed?</P>

<P>(See also <A HREF="
     cwg_defects.html#147">issue 147</A>.)</P>

<P><B>Proposed resolution (10/00):</B></P>

<OL>
<LI><P>Add to 9.2 [class.mem] paragraph 13</P>

<BLOCKQUOTE>
<UL><LI>every member function of class <TT>T</TT> [<I>Note:</I> this
restriction does not apply to constructors, which do not have names
(12.1 [class.ctor]). ];</LI></UL>
</BLOCKQUOTE>

<P>immediately following the line</P>

<BLOCKQUOTE>
<UL><LI>every data member of class <TT>T</TT>;</LI></UL>
</BLOCKQUOTE>
</LI>

<LI><P>Change 12.1 [class.ctor] paragraph 1 from</P>

<BLOCKQUOTE>
A special declarator syntax using an optional
<I>function-specifier</I> (7.1.2 [dcl.fct.spec])...
</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>
A special declarator syntax using an optional sequence of
<I>function-specifier</I>s (7.1.2 [dcl.fct.spec])...
</BLOCKQUOTE>
</LI>
</OL>
<BR><BR><HR><A NAME="152"></A><H4>152.
  
<TT>explicit</TT> copy constructors
</H4><B>Section: </B>12.3.1&#160; [class.conv.ctor]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>4 August 1999<BR>





<P>Can a copy-constructor declared as <TT>explicit</TT> be used to
copy class values implicitly?  For example,</P>

<PRE>
   struct X {
      X();
      explicit X(const X&amp;);
   };
   void f(X);
   int main() { X x; f(x); }
</PRE>

According to 12.3.1 [class.conv.ctor]

paragraphs 2-3,

<BLOCKQUOTE>
An explicit constructor constructs objects just like non-explicit
constructors, but does so only where the direct-initialization syntax
(8.5 [dcl.init]
) or where casts
(5.2.9 [expr.static.cast]
,
5.4 [expr.cast]
) are explicitly used...
A copy-constructor (12.8 [class.copy]
) is a
converting constructor.  An implicitly-declared copy constructor is
not an explicit constructor; it may be called for implicit type
conversions.
</BLOCKQUOTE>

This passage would appear to indicate that the call in the example is
ill-formed, since it uses neither the direct-initialization syntax nor
an explicit cast.  The last sentences are especially interesting in
this regard, indicating that <TT>explicit</TT> and
non-<TT>explicit</TT> copy constructors are handled differently.

<P>On the other hand,
8.5 [dcl.init]
 paragraph 14, bullet 4,
sub-bullet 2 says,</P>

<BLOCKQUOTE>
If the initialization is direct-initialization, or if it is
copy-initialization where the cv-unqualified version of the source
type is the same class as, or a derived class of, the class of the
destination... [the] applicable constructors are enumerated
(13.3.1.3 [over.match.ctor]
)...
</BLOCKQUOTE>

The cited passage says that

<BLOCKQUOTE>
The candidate functions are all the constructors of the class of the
object being initialized.
</BLOCKQUOTE>

<P><B>Notes from 04/01 meeting:</B></P>

<P>After the issue was accepted as a DR with the proposed
resolution to change 13.3.1.3 [over.match.ctor] paragraph 1
as described below, it was noticed that 12.3.1 [class.conv.ctor]
paragraph 3 states that:</P>

<BLOCKQUOTE>

A copy-constructor (12.8 [class.copy]) is a converting
constructor.

</BLOCKQUOTE>

<P>In addition to making the proposed resolution for this issue
ineffectual, the wording of paragraph 3 also contradicts that of
paragraph 1:</P>

<BLOCKQUOTE>

A constructor declared without the <I>function-specifier</I>
<TT>explicit</TT> that can be called with a single parameter specifies
a conversion from the type of its first parameter to the type of its
class. Such a constructor is called a converting constructor.

</BLOCKQUOTE>

<P>These considerations led to the addition of the second point
of the proposed resolution.</P>

<P><B>Proposed resolution (04/01):</B></P>
<OL>
<LI>
<P>Change the first two sentences of
13.3.1.3 [over.match.ctor]
 paragraph 1 to</P>
<BLOCKQUOTE>
When objects of class type are direct-initialized
(8.5 [dcl.init]), or copy-initialized
from an expression of the same or a derived class type
(8.5 [dcl.init]), overload
resolution selects the constructor.  For direct-initialization, the
candidate functions are all the constructors of the class of the object
being initialized.  For copy-initialization, the candidate functions are
all the converting constructors
(12.3.1 [class.conv.ctor]
) of that class.
</BLOCKQUOTE>
</LI>

<LI><P>Change the first sentence of 12.3.1 [class.conv.ctor]
paragraph 3 to read:</P>

<BLOCKQUOTE>

A non-explicit copy constructor (12.8 [class.copy]) is a
converting constructor.

</BLOCKQUOTE>
</LI>
</OL>
<BR><BR><HR><A NAME="193"></A><H4>193.
  
Order of destruction of local automatics of destructor
</H4><B>Section: </B>12.4&#160; [class.dtor]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Gerhard Menzl
 &#160;&#160;&#160;

 <B>Date: </B>7 Jan 2000<BR>



<P>The Standard is not clear whether automatic objects in a destructor
are destroyed before or after the destruction of the class's base and
member subobjects.  That is, given</P>

<PRE>
    struct S { ~S(); };

    struct T {
        S x;
        ~T() {
            S y;
        };
    };
</PRE>

<P>which will be destroyed first, <TT>x</TT> or <TT>y</TT>?</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>In 12.4 [class.dtor] paragraph 6, change

<BLOCKQUOTE>
A destructor for class <TT>X</TT> calls the destructors for
<TT>X</TT>'s direct members, ...
</BLOCKQUOTE>

to

<BLOCKQUOTE>
After executing the body of the destructor and destroying any
automatic objects allocated within the body, a destructor for class
<TT>X</TT> calls the destructors for <TT>X</TT>'s direct members, ...
</BLOCKQUOTE>
</P>
<BR><BR><HR><A NAME="235"></A><H4>235.
  
Assignment vs initialization
</H4><B>Section: </B>12.6.2&#160; [class.base.init]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>16 Sep 2000<BR>


<P>In 12.6.2 [class.base.init] paragraph 4 we read:</P>

<BLOCKQUOTE>

After the call to a constructor for class <TT>X</TT> has completed, if
a member of <TT>X</TT> is neither specified in the constructor's
<I>mem-initializer</I>s, nor default-initialized, nor initialized
during execution of the body of the constructor, the member has
indeterminate value.

</BLOCKQUOTE>

<P>Using the term "initialized" to describe setting the value of a
member inside the body of a constructor is a misuse of the term: only
by use of a placement <TT>new</TT> expression can a member be
<I>initialized</I> "during the execution of the body of the
constructor."</P>

<P><B>Suggested resolution:</B> Change "initialized" to "given a
value."</P>

<P><B>Proposed resolution (10/00):</B> As suggested.</P>

<BR><BR><HR><A NAME="20"></A><H4>20.
  
Some clarifications needed for 12.8 para 15
</H4><B>Section: </B>12.8&#160; [class.copy]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>unknown
 &#160;&#160;&#160;

 <B>Date: </B>unknown<BR>





<P><B><U>Issue 1</U></B></P>

<P>12.8 [class.copy]


(From J16/99-0005 = WG21 N1182, "Proposed Resolutions for Core
Language Issues 6, 14, 20, 40, and 89")</P>

<P>There are three related sub-issues in this issue, all dealing with the
elision of copy constructors as described in
12.8 [class.copy]

paragraph 15:</P>
<OL>
<LI>
The text should make clear that the requirement that the copy constructor
be accessible and unambiguous is not relaxed in cases where a call to a
copy constructor is elided.</LI>

<LI>
It is not clear from the text that the two optimizations described can
be applied transitively, and, if so, the implications for the order of
destruction are not spelled out.</LI>

<LI>
The text should exclude applying the function-return optimization if the
expression names a static or volatile local object.</LI>
</OL>
<U>Analysis</U>

<P>After discussion in Santa Cruz, the core group decided that sub-issue
#1 required no change; the necessity of an accessible and unambiguous copy
constructor is made clear in
12.2 [class.temporary]

paragraph 1 and need not be repeated in this text. The remaining two sub-issues
appear to be valid criticisms and should be addressed.</P>

<P><B>Proposed Resolution (10/99):</B></P>

<P><I>[Note: a small portion of this wording is superseded by the
resolution of <A HREF="
     cwg_defects.html#185">issue 185</A>.]</I></P>

<P>The paragraph in question should be rewritten as follows.
In addition,
references to this section should be added to the index under "temporary,
elimination of," "elimination of temporary," and "copy, constructor elision."</P>
<UL>When certain criteria are met, an implementation is allowed to omit
the copy construction of a class object, even if the copy constructor
and/or destructor
for the object have side effects. In such cases, the implementation treats
the source and target of the omitted copy operation as simply two different
ways of referring to the same object, and the destruction of that object
occurs at the later of the times when the two objects would have been destroyed
without the optimization [<I>footnote:</I> Because only one object is destroyed
instead of two, and one copy constructor is not executed, there is still
one object destroyed for each one constructed. <I>end footnote</I>].
This elision
of copy operations is permitted in the following circumstances (which may
be combined to eliminate multiple copies):
<BR>
<UL>
<LI>
<P>in a return statement in a function with a class return type, where the
expression is the name of a non-volatile automatic object with the same
cv-unqualified type as the function return type, the copy operation can
be omitted by constructing the automatic object directly into the function's
return value</P></LI>
</UL>
</UL>

<UL>
<UL>
<LI>
when a temporary class object 
(12.2 [class.temporary]
)
would be copied to a class object with the same cv-unqualified type,
the copy operation can be omitted by constructing the temporary object
directly into the target of the omitted copy</LI>
</UL>
</UL>

<UL>[<I>Example:</I></UL>

<UL>
<PRE>
    class Thing {
    public:
        Thing();
        ~Thing();
        Thing(const Thing&amp;);
    };
    
    Thing f() {
        Thing t;
        return t;
    }
    
    Thing t2 = f();
</PRE>
</UL>
Here the criteria for elision can be combined to eliminate two calls to
the copy constructor of class <TT>Thing</TT>: the copying of the local
automatic object <TT>t</TT> into the temporary object for the return value
of function <TT>f()</TT> and the copying of that temporary object into
object <TT>t2</TT>. Effectively, the construction of the local object <TT>t</TT>
can be viewed as directly initializing the global object <TT>t2</TT>, and
that object's destruction will occur at program exit.
&#8212;<I>end example</I>]
<BR><BR><HR><A NAME="185"></A><H4>185.
  
"Named" temporaries and copy elision
</H4><B>Section: </B>12.8&#160; [class.copy]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Bill Wade
 &#160;&#160;&#160;

 <B>Date: </B>11 Nov 1999<BR>



<P>12.8 [class.copy]
 paragraph 15 refers only
to "temporary class objects."  It needs to be made clear that these
provisions do <B>not</B> apply to temporaries that have been bound to
references.  For instance,</P>

<PRE>
    struct A {
        mutable int value;
        explicit A(int i) : value(i) {}
        void mutate(int i) const { value = i; }
    };

    int foo() {
        A const&amp; t = A(1);
        A n(t);          // can this copy be elided?
        t.mutate(2);
        return n.value;  // can this return 2?
    }
</PRE>

The current wording seems to allow an implementation not to perform
the copy in <TT>A N(t)</TT> because the source object is a temporary
(created explicitly by <TT>A(1)</TT>).

<P><B>Proposed resolution (10/00):</B></P>

<P>Change the wording proposed in the resolution of <A HREF="
     cwg_defects.html#20">issue 20</A> from</P>

<BLOCKQUOTE>
<UL><LI>when a temporary class object (12.2 [class.temporary])
would be copied to a class object...</LI></UL>
</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>
<UL><LI>when a temporary class object that has not been bound to a
reference (12.2 [class.temporary]) would be copied to a class
object...</LI></UL>
</BLOCKQUOTE>

<BR><BR><HR><A NAME="59"></A><H4>59.
  
Clarification of overloading and UDC to reference type
</H4><B>Section: </B>13.3.1.4&#160; [over.match.copy]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>13 Oct 1998<BR>



<P>Sections
13.3.1.4 [over.match.copy]

 and
13.3.1.5 [over.match.conv]


should be clarified regarding the treatment of conversion functions which
return reference types.</P>

<P><B>Proposed resolution (10/99):</B></P>

<P>In
13.3.1.4 [over.match.copy]

 paragraph
1, change</P>
<BLOCKQUOTE>Conversion functions that return "reference to <TT>T</TT>"
return lvalues
of type <TT>T</TT> and are therefore considered to yield <TT>T</TT>
for this process of selecting
candidate functions.</BLOCKQUOTE>
to
<BLOCKQUOTE>Conversion functions that return "reference to <TT>X</TT>"
return lvalues
of type <TT>X</TT> and are therefore considered to yield <TT>X</TT>
for this process of selecting
candidate functions.</BLOCKQUOTE>
In
13.3.1.5 [over.match.conv]

 paragraph 1,
change
<BLOCKQUOTE>Conversion functions that return "reference to <TT>T</TT>"
return lvalues
of type <TT>T</TT> and are therefore considered to yield <TT>T</TT>
for this process of selecting
candidate functions.</BLOCKQUOTE>
to
<BLOCKQUOTE>Conversion functions that return "reference to
<I>cv2</I> <TT>X</TT>"
return lvalues of type "<I>cv2</I> <TT>X</TT>" and are therefore
considered to yield
<TT>X</TT> for this process of selecting candidate functions.</BLOCKQUOTE>
<BR><BR><HR><A NAME="51"></A><H4>51.
  
Overloading and user-defined conversions
</H4><B>Section: </B>13.3.3&#160; [over.match.best]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>13 Oct 1998<BR>



<P>In 13.3.3 [over.match.best]
 paragraph 1,
bullet 4 of the second set of bullets, there is a cross-reference
to 8.5 [dcl.init]
 and
13.3.1.5 [over.match.conv]
. I believe it should also
reference 13.3.1.6 [over.match.ref]
.
I think the phrase "initialization by user-defined
conversion" was intended to refer to all initializations using user-defined
conversions, and not just the case in 
13.3.1.5 [over.match.conv]
. Referring to only
13.3.1.5 [over.match.conv]
 suggests a narrower
meaning of the phrase.</P>

<P>13.3.1.4 [over.match.copy]
,
although it does deal with initialization by user-defined
conversion, does not need to be referenced because it deals with class
&#8212;&gt; class cases, and therefore there are no standard conversions involved
that could be compared.</P>

<BR><BR><HR><A NAME="84"></A><H4>84.
  
Overloading and conversion loophole used by <TT>auto_ptr</TT>
</H4><B>Section: </B>13.3.3.1&#160; [over.best.ics]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>10 Dec 1998<BR>



<P>By the letter of the standard, the conversions required to
make <TT>auto_ptr</TT> work should be accepted.</P>

<P>However, there's good reason to wonder if there isn't a bug in the standard
here. Here's the issue: line 16 in the example below comes down to
<BLOCKQUOTE>copy-initialize an <TT>auto_ptr&lt;Base&gt;</TT> from
an <TT>auto_ptr&lt;Derived&gt;</TT> rvalue</BLOCKQUOTE>
To do that, we first look to see whether we can convert
an <TT>auto_ptr&lt;Derived&gt;</TT>
to an <TT>auto_ptr&lt;Base&gt;</TT>, by enumerating the
constructors of <TT>auto_ptr&lt;Base&gt;</TT>
and the conversion functions of <TT>auto_ptr&lt;Derived&gt;</TT>.
There's a single possible way to do the conversion, namely the conversion
function</P>
<PRE>
    auto_ptr&lt;Derived&gt;::operator auto_ptr&lt;Base&gt;()
</PRE>
(generated from the template).  (The constructor 
<TT>auto_ptr&lt;Base&gt;(auto_ptr_ref&lt;Base&gt;)</TT>
doesn't work because it requires a  user-defined conversion on the
argument.)
    
<P>So far, so good.  Now, we do the copy step:</P>
<BLOCKQUOTE>direct-initialize an <TT>auto_ptr&lt;Base&gt;</TT>
from an <TT>auto_ptr&lt;Base&gt;</TT>
rvalue</BLOCKQUOTE>
This, as we've gone to great lengths to set up, is done by calling 
the conversion function
<PRE>
    auto_ptr&lt;Base&gt;::operator auto_ptr_ref&lt;Base&gt;()
</PRE>
(generated from the template), and then the constructor
<PRE>
    auto_ptr&lt;Base&gt;(auto_ptr_ref&lt;Base&gt;)
</PRE>
(generated from the template).
    
<P>The problem with this interpretation is that it violates the long-standing 
common-law rule that only a single user-defined conversion will be called 
to do an implicit conversion.  I find that pretty disturbing. 
(In fact, the full operation involves two conversion functions and two
constructors, but "copy" constructors are generally considered not to be
conversions.)</P>
    
<P>The direct-initialization second step of a copy-initialization was intended
to be a simple copy &#8212; you've made a temporary, and now you use a copy
constructor to copy it.  Because it is defined in terms of direct
initialization, however, it can exploit the loophole that auto_ptr
is based on.</P>
    
<P>To switch to personal opinion for a second, I think it's bad enough
that auto_ptr has to exploit a really arcane loophole of overload resolution,
but in this case it seems like it's exploiting a loophole on a loophole.</P>
<PRE>
    struct Base {                             //  2
       static void sink(auto_ptr&lt;Base&gt;);      //  3
    };                                        //  4

    struct Derived : Base {                   //  5
       static void sink(auto_ptr&lt;Derived&gt;);   //  6
    };                                        //  7

    auto_ptr&lt;Derived&gt; source() {              //  8
       auto_ptr&lt;Derived&gt; p(source());         //  9
       auto_ptr&lt;Derived&gt; pp(p);               // 10
       Derived::sink(source());               // 11
       p = pp;                                // 12
       p = source();                          // 13
       auto_ptr&lt;Base&gt; q(source());            // 14
       auto_ptr&lt;Base&gt; qp(p);                  // 15
       Base::sink(source());                  // 16
       q = pp;                                // 17
       q = source();                          // 18
       return p;                              // 19
       return source();
    }
</PRE>

<U>Derek Inglis</U>:



<P>It seems clear to me that the result of this direct initilization
must be the second standard conversion sequence in a user defined
conversion sequence.  Otherwise the resulting conversion sequence is
not an implicit conversion sequence.  By the letter of the standard,
the sequence of conversions making up a copy-initialization must be an
implicit conversion sequence.</P>

<P>Paragraph 3 of clause 4 [conv]:</P>

<BLOCKQUOTE>

An expression <TT>e</TT> can be <I>implicitly converted</I> to a type
<TT>T</TT> if and only if the declaration "<TT>T t=e;</TT>" is
well-formed, for some invented temporary variable <TT>t</TT>
(8.5 [dcl.init]).

</BLOCKQUOTE>

<P>Paragraph 1 of 13.3.3.1 [over.best.ics]:</P>

<BLOCKQUOTE>

An <I>implicit conversion sequence</I> is a sequence of conversions
used to convert an argument in a function call to the type of the
corresponding parameter of the function being called.  The sequence of
conversions is an implicit conversion as defined in clause
4 [conv], which means it is governed by the rules for
initialization of an object or reference by a single expression
(8.5 [dcl.init], 8.5.3 [dcl.init.ref]).

</BLOCKQUOTE>

Sentence 1 of paragraph 12 of 8.5 [dcl.init]:

<BLOCKQUOTE>

The initialization that occurs in argument passing ...
is  called <I>copy-initialization</I> and is equivalent to  the form

<PRE>
     T x = a;
</PRE>

</BLOCKQUOTE>

<P>For me, these sentences imply that all sequences of conversions
permitted on a function argument must be valid implicit conversion
sequences.</P>

<P>The 'loophole' can be closed by adding a sentence (or note) to the
section describing the 'direct initialization second step of a copy
initialization' stating that the copy initialization is ill-formed if
the conversion sequence resulting from the direct initialization is
not a standard conversion sequence.</P>

<P>(See also <A HREF="
     cwg_defects.html#177">issue 177</A> and paper
J16/00-0009 = WG21 N1232.)</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>Change 13.3.3.1 [over.best.ics] paragraphs 3 and 4 from</P>

<BLOCKQUOTE>

<P>Except in the context of an initialization by user-defined
conversion (13.3.1.4 [over.match.copy],
13.3.1.5 [over.match.conv]), a well-formed implicit conversion
sequence is one of the following forms:</P>

<UL>

<LI>a <I>standard conversion sequence</I>
(13.3.3.1.1 [over.ics.scs]),</LI>

<LI>a <I>user-defined conversion sequence</I>
(13.3.3.1.2 [over.ics.user]), or</LI>

<LI>an <I>ellipsis conversion sequence
(13.3.3.1.3 [over.ics.ellipsis])</I></LI>

</UL>

<P>In the context of an initialization by user-defined conversion (i.e.,
when considering the argument of a user-defined conversion function;
see 13.3.1.4 [over.match.copy], 13.3.1.5 [over.match.conv]),
only standard conversion sequences and
ellipsis conversion sequences are allowed.</P>

</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>

<P>A well-formed implicit conversion
sequence is one of the following forms:</P>

<UL>

<LI>a <I>standard conversion sequence</I>
(13.3.3.1.1 [over.ics.scs]),</LI>

<LI>a <I>user-defined conversion sequence</I>
(13.3.3.1.2 [over.ics.user]), or</LI>

<LI>an <I>ellipsis conversion sequence</I>
(13.3.3.1.3 [over.ics.ellipsis])</LI>

</UL>

<P>However, when considering the argument of a user-defined conversion
function that is a candidate by 13.3.1.3 [over.match.ctor]
when invoked for the copying
of the temporary in the second step of a class copy-initialization, or
by 13.3.1.4 [over.match.copy], 13.3.1.5 [over.match.conv],
or 13.3.1.6 [over.match.ref] in all cases, only standard
conversion sequences and ellipsis conversion sequences are
allowed.</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="83"></A><H4>83.
  
Overloading and deprecated conversion of string literal
</H4><B>Section: </B>13.3.3.2&#160; [over.ics.rank]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>24 Jan 1999<BR>



<P>In
13.3.3.2 [over.ics.rank]
, we have</P>
<UL><LI><TT>S1</TT> and <TT>S2</TT> differ only in their
qualification conversion and
yield similar types <TT>T1</TT> and <TT>T2</TT>
(4.4 [conv.qual]
),
respectively, and the cv-qualification signature of type <TT>T1</TT>
is a proper
subset of the cv-qualification signature of type <TT>T2</TT>,
[<I>Example:</I>
<PRE>
    int f(const int *);
    int f(int *); 
    int i;
    int j = f(&amp;i); // <I>Calls</I> f(int *)
</PRE>
&#8212;<I>end example</I>] or, if not that,</LI></UL>
This does not work right with respect to the deprecated conversion from
string literal to "<TT>char *</TT>". Consider
<PRE>
    void f(char *);
    void f(const char *);
    
    f("abc");
</PRE>
The two conversion sequences differ only in their qualification conversions,
and the destination types are similar. The cv-qualification signature of
"<TT>char *</TT>", is a proper subset of the cv-qualification signature
of "<TT>const char *</TT>", so <TT>f(char *)</TT> is chosen, which is wrong.
The rule should be like the one for conversion to bool &#8212; the deprecated
conversion should be worse than another exact match that is not the deprecated
conversion.

<P><B>Proposed resolution (10/00):</B></P>

<P>Change
13.3.3.2 [over.ics.rank]
 paragraph 3 bullet 1
sub-bullet 3 from</P>
<BLOCKQUOTE>
<TT>S1</TT> and <TT>S2</TT> differ only in their qualification
conversion and yield similar types <TT>T1</TT> and <TT>T2</TT>
(4.4 [conv.qual]
), respectively, and the
cv-qualification signature of type <TT>T1</TT> is a proper subset of
the cv-qualification signature of type <TT>T2</TT>.
</BLOCKQUOTE>
to
<BLOCKQUOTE>
<TT>S1</TT> and <TT>S2</TT> differ only in their qualification
conversion and yield similar types <TT>T1</TT> and <TT>T2</TT>
(4.4 [conv.qual]
), respectively, and the
cv-qualification signature of type <TT>T1</TT> is a proper subset of
the cv-qualification signature of type <TT>T2</TT>, and <TT>S1</TT> is
not the deprecated string literal array-to-pointer conversion
(4.2 [conv.array]
).
</BLOCKQUOTE>
<BR><BR><HR><A NAME="153"></A><H4>153.
  
Misleading wording (rank of conversion)
</H4><B>Section: </B>13.3.3.2&#160; [over.ics.rank]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Valentin Bonnard
 &#160;&#160;&#160;

 <B>Date: </B>6 Aug 1999<BR>



<P>13.3.3.2 [over.ics.rank]
 paragraph 3 bullet 1
sub-bullet 2 says,</P>

<BLOCKQUOTE>
the rank of <TT>S1</TT> is better than the rank of <TT>S2</TT> (by the
rules defined below)...
</BLOCKQUOTE>

This wording is confusing.  The word "below" refers to paragraph 4
(which may not be clear), and the bulk of paragraph 4 deals with
comparing conversion sequences whose "rank" is the same.

<P><B>Proposed resolution (10/00):</B></P>

<P>In
13.3.3.2 [over.ics.rank]
 paragraph 3, change</P>
<BLOCKQUOTE>
the rank of <TT>S1</TT> is better than the rank of <TT>S2</TT> (by the
rules defined below)
</BLOCKQUOTE>
to
<BLOCKQUOTE>
the rank of <TT>S1</TT> is better than the rank of <TT>S2</TT>, or
<TT>S1</TT> and <TT>S2</TT> have the same rank and are distinguishable
by the rules in the paragraph below
</BLOCKQUOTE>
<BR><BR><HR><A NAME="202"></A><H4>202.
  
Use of overloaded function name
</H4><B>Section: </B>13.4&#160; [over.over]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Clamage
 &#160;&#160;&#160;

 <B>Date: </B>2 Feb 2000<BR>





<P>13.4 [over.over]
 paragraph 1 contains a
supposedly exhaustive list of contexts in which the name of an
overloaded function can be used without an argument list ("...shall
not be used without arguments in contexts other than those listed").
However, 14.3.2 [temp.arg.nontype]
 paragraph 5,
bullet 4 gives another context: as a template nontype argument.</P>

<P><B>Suggested resolution:</B> Add the missing case to
13.4 [over.over].</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>Add as the final bullet in 13.4 [over.over] paragraph 1:</P>

<BLOCKQUOTE>
<UL><LI>a non-type template-parameter (14.3.2 [temp.arg.nontype]).</LI></UL>
</BLOCKQUOTE>

<P>and adjust the "or" and final period on the preceding
two bullets.</P>

<BR><BR><HR><A NAME="250"></A><H4>250.
  
Address of function template specialization with non-deduced template arguments
</H4><B>Section: </B>13.4&#160; [over.over]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Nikolas Kauer
 &#160;&#160;&#160;

 <B>Date: </B>10 Oct 2000<BR>


<P>13.4 [over.over] paragraph 2 says,</P>

<BLOCKQUOTE>

If the name is a function template, template argument deduction is
done (14.8.2.2 [temp.deduct.funcaddr]), and if the argument
deduction succeeds, the deduced template arguments are used to
generate a single template function, which is added to the set of
overloaded functions considered.

</BLOCKQUOTE>

<P>It is not clear whether this formulation allows explicit
specification of non-deduced template arguments.  For instance,</P>

<PRE>
    template &lt;int I&gt; void f(double x[]);
    typedef void (*FPtr)(double x[]);
    FPtr fp = &amp;f&lt;3&gt;;
</PRE>

<P>If only deduced arguments can be used, this example is
ill-formed.</P>

<P><B>Suggested resolution:</B> Clarify 13.4 [over.over]
paragraph 2 to allow both deduced and explicitly-specified
template arguments to be used to determine the function template
specialization to be added to the overload set.</P>

<P>(See also issues <A HREF="
     cwg_defects.html#115">115</A> and
<A HREF="
     cwg_defects.html#214">214</A>.)</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>In 13.4 [over.over] paragraph 2, change</P>

<BLOCKQUOTE>

...if the argument deduction succeeds, the deduced template arguments
are used to generate a single template function...

</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>

...if the argument deduction succeeds, the resulting template
argument list is used to generate a single function template
specialization...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="32"></A><H4>32.
  
Clarification of explicit instantiation of non-exported templates
</H4><B>Section: </B>14&#160; [temp]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>10 Jul 1998<BR>





<P>Section 14 [temp]
 paragraph 8 says:
<BLOCKQUOTE>A non-exported template that is neither explicitly specialized
<U>nor explicitly instantiated</U> must be defined in every translation
unit in which it is implicitly instantiated (14.7.1 [temp.inst]
) or <U>explicitly
instantiated</U> (14.7.2 [temp.explicit]
); no diagnostic is required.</BLOCKQUOTE>
Shouldn't the first underlined phrase be omitted to avoid conflict with
the second underlined phrase?</P>

<P><U>From John Spicer:</U></P>

<P>The first "explicitly instantiated" is intended to mean "explicitly instantiated
in some other translation unit".</P>

<P><B>Proposed Resolution (04/99):</B>
Change the text in 14 [temp]
 paragraph 8 from:</P>
<BLOCKQUOTE>A non-exported template that is neither explicitly specialized
nor explicitly instantiated must be defined in every translation unit in
which it is implicitly instantiated (14.7.1 [temp.inst]
) or explicitly instantiated
(14.7.2 [temp.explicit]
); no diagnostic is required.</BLOCKQUOTE>
to:
<BLOCKQUOTE>A non-exported template must be defined in every translation
unit in which it is implicitly instantiated (14.7.1 [temp.inst]
), unless the corresponding
specialization is explicitly instantiated (14.7.2 [temp.explicit]
) in some translation
unit; no diagnostic is required. [<I>Note:</I> See also 14.7.2 [temp.explicit]
]</BLOCKQUOTE>
<BR><BR><HR><A NAME="105"></A><H4>105.
  
Meaning of "template function"
</H4><B>Section: </B>14&#160; [temp]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>16 Apr 1999<BR>



<P>The phrase "template function" is sometimes used to refer to a
template (e.g., in 14 [temp]
 paragraph 8)
and sometimes to refer to a function generated from a template (e.g.,
13.4 [over.over]
 paragraph 4).</P>

<P><B>Suggested Resolution:</B></P>

<P>The phrase should mean "a function generated from a template"
(or might perhaps include explicit specializations).</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>In 1.3 [intro.defs] &#8220;<SPAN style="font-weight:bold;background-color:#A0FFA0">signature</SPAN>,&#8221;
replace "template function specialization"
by "function template specialization".
</P>

<P>In 9.3 [class.mfct] paragraph 2, replace "template
member functions" by "member functions of class templates and
member function templates."</P>

<P>In 13.3.1 [over.match.funcs] paragraph 7 and footnote, replace
all instances of "template functions" by "function template
specializations."</P>

<P>In 13.3.3 [over.match.best] paragraph 1, fourth bullet (counting all
bullets in that paragraph), replace "template function specialization" by
"function template specialization".  In the fifth bullet, replace
"template functions" by "function template specializations."
</P>

<P>In 13.4 [over.over] paragraph 2, replace "template
function" by "function template specialization."</P>

<P>Change 13.4 [over.over] paragraph 4 from:
<BLOCKQUOTE>If more than one function is selected, any template functions
in the set are eliminated if the set also contains a non-template function,
and any given template function is eliminated if the set contains a second
template function that is more specialized than the first according to
the partial ordering rules of 14.5.6.2 [temp.func.order]. After such eliminations, if any,
there shall remain exactly one selected function.</BLOCKQUOTE>
to:
<BLOCKQUOTE>If more than one function is selected, any function
template specializations
in the set are eliminated if the set also contains a non-template function,
and any given function template specialization <TT>F1</TT> is eliminated if the set contains a
second function template specialization whose function template is more specialized than
the function template of <TT>F1</TT> according to the partial ordering rules of
14.5.6.2 [temp.func.order]. After such eliminations, if any, there shall remain exactly one
selected function.</BLOCKQUOTE>
</P><P>Change text in section 14 [temp] paragraph 8 from:
<BLOCKQUOTE>A template function declared both exported and inline is just
inline and not exported.</BLOCKQUOTE>
to:
<BLOCKQUOTE>A function template declared both exported and inline is just
inline and not exported.</BLOCKQUOTE>
</P>

<P>In 14.5.4 [temp.friend] paragraph 1, third bullet, replace
"template function" by "function template" and "function
specialization" by "function template specialization."</P>

<P>In footnote 130 (14.5.6 [temp.fct] paragraph 2),
replace "template functions" by "function template specializations."</P>

<P>In 14.5.6.2 [temp.func.order] paragraph 1, third bullet change "template
function specialization" to "function template specialization".
</P><P>In 14.8.2 [temp.deduct] paragraph 1, change "template function specialization"
to "function template specialization".
</P><P>In 17.3 [definitions] &#8220;<B>component</B>&#8221;
change "non-member template functions that
operate" to "non-member function templates that operate".
</P><P>In 17.3 [definitions] &#8220;<B>traits class&#8221;</B>
change "template classes and template functions"
to "class templates and function templates".
</P><P>In 20.2 [utility] paragraph 1 change:
<BLOCKQUOTE>This subclause contains some basic template functions and classes
that are used throughout the rest of the library.</BLOCKQUOTE>
to:
<BLOCKQUOTE>This subclause contains some basic function and class templates
that are used throughout the rest of the library.</BLOCKQUOTE>
</P><P>In 20.3 [pairs] paragrah 1 change "template function" to "function
template".
</P><P>In footnote 215 (_N3225_.20.8.11 [function.pointer.adaptors] paragraph 6)
change "template functions" to "function templates".
</P><P>In 22.3.1 [locale] paragraph 4 change "template function" to "function
template".
</P><P>In 24.2 [iterator.requirements] paragraph 2 change "template function"
to "function template".
</P>

<P>In 24.4.3 [std.iterator.tags] paragraph 1, change "template
function" to "function template specialization."</P>

<P>In 24.4.4 [iterator.operations] paragraph 1 change "template function"
to "function template", and "These functions use" to "These function templates
use".
</P><P>In the section heading of 27.7.3.6.4 [ostream.inserters.character]
change "template functions" to "function templates".
</P><P>In 17.5.1.3 [structure.requirements] paragraph 2 change "template
class name <TT>char_traits</TT>" to "class template <TT>char_traits</TT>".
</P><P>In the section heading of 18.3.2.3 [numeric.limits] change "Template
class" to "Class template".
</P><P>In 17.6.3.5 [allocator.requirements] paragraph 3 change "template
class member <TT>rebind</TT>" to "member class template <TT>rebind</TT>"
and change "template typedef" to "typedef template".
</P><P>In the section heading of D.9.1 [depr.lib.binder.1st] change "Template
class" to "Class template".
</P><P>In the section heading of D.9.3 [depr.lib.binder.2nd] change "Template
class" to "Class template".
</P><P>In the section heading of D.10.1 [auto.ptr] change "Template class"
to "Class template".
</P><P>In the section heading of 21.4 [basic.string] change "Template
class" to "Class template".
</P><P>In 21.4 [basic.string] paragraphs 1 and 2 change "template class
<TT>basic_string</TT>"
to "class template <TT>basic_string</TT>".
</P><P>In the section heading of 22.4.1.1 [locale.ctype] change "Template
class" to "Class template".
</P><P>In the section heading of 22.4.1.2 [locale.ctype.byname] change
"Template class" to "Class template".
</P><P>In the section heading of 22.4.1.4 [locale.codecvt] change "Template
class" to "Class template".
</P><P>In the section heading of 22.4.1.5 [locale.codecvt.byname] change
"Template class" to "Class template".
</P><P>In the section heading of 22.4.2.1 [locale.num.get] change "Template
class" to "Class template".
</P><P>In the section heading of 22.4.2.2 [locale.nm.put] change "Template
class" to "Class template".
</P><P>In the section heading of 22.4.3.1 [locale.numpunct] change "Template
class" to "Class template".
</P><P>In the section heading of 22.4.3.2 [locale.numpunct.byname] change
"Template class" to "Class template".
</P><P>In the section heading of 22.4.4.1 [locale.collate] change "Template
class" to "Class template".
</P><P>In the section heading of 22.4.4.2 [locale.collate.byname] change
"Template class" to "Class template".
</P><P>In the section heading of 22.4.5.1 [locale.time.get] change "Template
class" to "Class template".
</P><P>In the section heading of 22.4.5.2 [locale.time.get.byname] change
"Template class" to "Class template".
</P><P>In the section heading of 22.4.5.3 [locale.time.put] change "Template
class" to "Class template".
</P><P>In the section heading of 22.4.5.4 [locale.time.put.byname] change
"Template class" to "Class template".
</P><P>In the section heading of 22.4.6.1 [locale.money.get] change "Template
class" to "Class template".
</P><P>In the section heading of 22.4.6.2 [locale.money.put] change "Template
class" to "Class template".
</P><P>In the section heading of 22.4.6.3 [locale.moneypunct] change "Template
class" to "Class template".
</P><P>In the section heading of 22.4.6.4 [locale.moneypunct.byname] change
"Template class" to "Class template".
</P><P>In the section heading of 22.4.7.1 [locale.messages] change "Template
class" to "Class template".
</P><P>In the section heading of 22.4.7.2 [locale.messages.byname] change
"Template class" to "Class template".
</P><P>In the section heading of 23.3.3 [deque] change "Template class"
to "Class template".
</P><P>In the section heading of 23.3.6 [list] change "Template class"
to "Class template".
</P><P>In the section heading of 23.6.3 [queue] change "Template class"
to "Class template".
</P><P>In the section heading of 23.6.4 [priority.queue] change "Template
class" to "Class template".
</P><P>In the section heading of 23.6.5 [stack] change "Template class"
to "Class template".
</P><P>In the section heading of 23.3.7 [vector] change "Template class"
to "Class template".
</P><P>In the section heading of 23.4.4 [map] change "Template class"
to "Class template".
</P><P>In the section heading of 23.4.5 [multimap] change "Template class"
to "Class template".
</P><P>In the section heading of 23.4.6 [set] change "Template class"
to "Class template".
</P><P>In the section heading of 23.4.7 [multiset] change "Template class"
to "Class template".
</P><P>In the section heading of 20.7 [template.bitset] change "Template
class" to "Class template".
</P><P>In 20.7 [template.bitset] paragraph 1, change "template class"
to "class template".
</P><P>In the section heading of 24.5.1.1 [reverse.iterator] change "Template
class" to "Class template".
</P><P>In the section heading of 24.5.2.1 [back.insert.iterator] change
"Template class" to "Class template".
</P><P>In the section heading of 24.5.2.3 [front.insert.iterator] change
"Template class" to "Class template".
</P><P>In the section heading of 24.5.2.5 [insert.iterator] change "Template
class" to "Class template".
</P><P>In 24.6 [stream.iterators] paragraph 1, change "template classes"
to "class templates".
</P><P>In the section heading of 24.6.1 [istream.iterator] change "Template
class" to "Class template".
</P><P>In the section heading of 24.6.2 [ostream.iterator] [lib.ostream.iterator] change "Template
class" to "Class template".
</P><P>In the section heading of 24.6.3 [istreambuf.iterator] change "Template
class" to "Class template".
</P><P>In 24.6.3 [istreambuf.iterator] paragraph 1, change "template class"
to "class template".
</P><P>In the section heading of 24.6.3.1 [istreambuf.iterator::proxy]
change "Template class" to "Class template".
</P><P>In the section heading of 24.6.4 [ostreambuf.iterator] change "Template
class" to "Class template".
</P><P>In 24.6.4 [ostreambuf.iterator] paragraph 1, change "template class"
to "class template".
</P><P>In 26.4 [complex.numbers] paragraph 1, change "template class"
to "class template".
</P><P>In the section heading of 26.4.2 [complex] change "Template class"
to "Class template".
</P><P>In _N2798_.26.5.1 [valarray.synopsis] paragraph 1, change "template classes"
to "class templates" and change "function signatures" to "function templates".
</P><P>In the section heading of 26.6.2 [template.valarray] change "Template
class" to "Class template".
</P><P>In the section heading of 26.6.5 [template.slice.array] change
"Template class" to "Class template".
</P><P>In the section heading of 26.6.7 [template.gslice.array] change
"Template class" to "Class template".
</P><P>In the section heading of 26.6.8 [template.mask.array] change "Template
class" to "Class template".
</P><P>In the section heading of 26.6.9 [template.indirect.array] change
"Template class" to "Class template".
</P><P>In 27.3 [iostream.forward] [lib.iostream.forward] paragraphs 3 to 7, change "template
classes" to "class templates".
<I>[Note: Some editorial changes were made in paragraphs 2 to 8 when these
changes were applied in September 2001.]</I>
</P><P>In the section heading of 27.5.4 [fpos] change "Template class"
to "Class template".
</P><P>In the section heading of 27.5.5 [ios] change "Template class"
to "Class template".
</P><P>In the section heading of 27.6.3 [streambuf] change "Template class"
to "Class template".
</P><P>In 27.6.3 [streambuf] paragraphs 2 and 3, change "template class"
to "class template".
</P><P>In the section heading of 27.7.2.1 [istream] change "Template class"
to "Class template".
</P><P>In the section heading of 27.7.2.5 [iostreamclass] change "Template
class" to "Class template".
</P><P>In the section heading of 27.7.3.1 [ostream] change "Template class"
to "Class template".
</P><P>In 27.8 [string.streams] paragraph 1 change "template classes"
to "class templates".
</P><P>In the section heading of 27.8.2 [stringbuf] change "Template class"
to "Class template".
</P><P>In the section heading of 27.8.3 [istringstream] change "Template
class" to "Class template".
</P><P>In the section heading of 27.8.5 [stringstream] change "Template
class" to "Class template".
</P><P>In the section heading of 27.9.1.1 [filebuf] change "Template class"
to "Class template".
</P><P>In the section heading of 27.9.1.6 [ifstream] change "Template
class" to "Class template".
</P><P>In the section heading of 27.9.1.10 [ofstream] change "Template
class" to "Class template".
</P><P>In the section heading of 27.9.1.14 [fstream] change "Template
class" to "Class template".</P>

<BR><BR><HR><A NAME="134"></A><H4>134.
  
Template classes and <I>declarator-id</I>s
</H4><B>Section: </B>14&#160; [temp]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>17 June 1999<BR>





<P>14 [temp]
 paragraph 2 says,</P>

<BLOCKQUOTE>
[<I>Note:</I> in a class template declaration, if the
<I>declarator-id</I> is a <I>template-id</I>, the declaration
declares a class template partial specialization
(14.5.5 [temp.class.spec]
). ]
</BLOCKQUOTE>

There is no <I>declarator-id</I> in a class template declaration
(cf paragraph 3).

<P><B>Proposed resolution (10/00):</B></P>

<P>Replace the phrase "if the
<I>declarator-id</I> is a <I>template-id</I>" with "if the class name
is a <I>template-id</I>."</P>
<BR><BR><HR><A NAME="21"></A><H4>21.
  
Can a default argument for a template parameter appear in a friend declaration?
</H4><B>Section: </B>14.1&#160; [temp.param]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>unknown
 &#160;&#160;&#160;

 <B>Date: </B>unknown<BR>





<P>14.1 [temp.param]
 paragraph 10 says:</P>
<BLOCKQUOTE>The set of default template-arguments available for use with
a template declaration or definition is obtained by merging the default
arguments from the definition (if in scope) and all declarations in scope
in the same way as default function arguments are (8.3.6 [dcl.fct.default]
)."</BLOCKQUOTE>
Can a default argument for a template argument appear in a friend declaration?
If so, when is this default argument considered for template instantiations?

<P>For example,</P>
<PRE>
    template&lt;class T1, class T2 = int&gt; class A;
 
    class B {
        template&lt;class T1 = int, class T2&gt; friend class A;
    };
</PRE>
Is this well-formed? If it is, should the IS say when the default argument
for <TT>T1</TT> is considered for instantiations of class <TT>A</TT>?

<P><B>Proposed resolution (10/00):</B> Add to the end of
14.1 [temp.param]
 paragraph 9,</P>

<BLOCKQUOTE>
A default <I>template-argument</I> shall not be specified in a friend
template declaration.
</BLOCKQUOTE>
<P>(See also <A HREF="
     cwg_defects.html#136">issue 136</A>.)</P>
<BR><BR><HR><A NAME="49"></A><H4>49.
  
Restriction on non-type, non-value template arguments
</H4><B>Section: </B>14.1&#160; [temp.param]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>16 Oct 1998<BR>



<P>The example in
14.1 [temp.param]

 paragraph
8 is:</P>
<PRE>
    template&lt;int* a&gt; struct R { /*...*/ };
    int* p;
    R&lt;p&gt; w;
</PRE>
There was a French comment was that this is an error, and there was general
agreement with that.

<P>I've been looking for the verbiage that specifies that this is an error
and haven't found it. In particular, nothing in 14.1 [temp.param]
 ("Template parameters")
nor 14.3.2 [temp.arg.nontype]
 ("Template non-type arguments") appears to rule out this case.
(14.3.2 [temp.arg.nontype]
 paragraph 1 allows an argument to be "the name of an object or function with
external linkage," with no limitation on the kinds of parameters such a
name can match; "p" is, in fact, such a name.)</P>

<P>Should the resolution of the French comment include beefing up one or
both of these sections to cover the applicable rules explicitly?</P>

<P><B>Proposed Resolution (04/99):</B>
Change the example in 14.1 [temp.param]

paragraph 8 from:</P>
<PRE>
    template&lt;int *a&gt; struct R { /* ... */ };
    template&lt;int b[5]&gt; struct S { /* ... */ };
    int *p;
    R&lt;p&gt; w; // <I>OK</I>
    S&lt;p&gt; x; // <I>OK due to parameter adjustment</I>
    int v[5];
    R&lt;v&gt; y; // <I>OK due to implicit argument conversion</I>
    S&lt;v&gt; z; // <I>OK due to both adjustment and conversion</I>
</PRE>
to:
<PRE>
    template&lt;int *a&gt; struct R { /* ... */ };
    template&lt;int b[5]&gt; struct S { /* ... */ };
    int p;
    R&lt;&amp;p&gt; w; // <I>OK</I>
    S&lt;&amp;p&gt; x; // <I>OK due to parameter adjustment</I>
    int v[5];
    R&lt;v&gt; y; // <I>OK due to implicit argument conversion</I>
    S&lt;v&gt; z; // <I>OK due to both adjustment and conversion</I>
</PRE>
Furthermore, in 14.3.2 [temp.arg.nontype]
 paragraph 1:
<UL>
<LI>the fourth bullet item should be changed from "...where the &amp; is optional
if the name refers to a function or array;" to "...where the &amp; is optional
if the name refers to a function or array, or if
the corresponding <I>template-parameter</I> is a reference;"</LI>

<LI>the third bullet item should be removed.</LI>
</UL>
<BR><BR><HR><A NAME="187"></A><H4>187.
  
Scope of template parameter names
</H4><B>Section: </B>14.1&#160; [temp.param]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>15 Nov 1999<BR>





<P>At the Dublin meeting (04/99), the Committee proposed to resolve
<A HREF="
     cwg_defects.html#22">issue 22</A> by simply changing the
wording to make clear that a template parameter cannot be used in its
own default argument.  This creates a third treatment of this kind of
situation, in addition to
3.3.2 [basic.scope.pdecl]
 paragraph 1, where
declarators are in scope and can be used in their initializers, and
paragraph 3, where an enumerator is not in scope until after its
complete <I>enumerator-definition</I>.  The Dublin resolution is for
the template parameter to be in scope in its default argument but not
usable.  It would be more consistent to treat template parameters like
enumerators: simply not in scope until the entire
<I>template-parameter</I> declaration is seen.</P>

<P>On a related note,
14.1 [temp.param]
 paragraph 14 should be
rewritten to connect the prohibition with visibility rules; otherwise,
it sounds as if the following example is not permitted:</P>

<PRE>
    const int Z = 1;
    template &lt;int X = Z, int Z&gt; class A {};
</PRE>

<P><B>Notes from 04/00 meeting:</B></P>

<P>The core working group did not reach consensus on the suggested
approach to <A HREF="
     cwg_defects.html#22">issue 22</A>.  However, it was
agreed that the intent expressed in the earlier resolution would be
better served by different wording.</P>

<P><B>Proposed resolution (10/00):</B></P>

<P><I>[Note: This resolution supersedes the resolution to
<A HREF="
     cwg_defects.html#22">issue 22</A>.]</I></P>

<P>Replace 14.1 [temp.param] paragraph 14 as follows:</P>

<BLOCKQUOTE>
A template parameter shall not be used in its own default argument.
</BLOCKQUOTE>

<BR><BR><HR><A NAME="30"></A><H4>30.
  
Valid uses of "<TT>::template</TT>"
</H4><B>Section: </B>14.2&#160; [temp.names]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>28 May 1998<BR>





<P>I have a request for clarification regarding a issue similar to John
Wiegley's, but wrt. the <TT>::template</TT> syntax. More precisely, where
is</P>
<PRE>
    X::template Y
</PRE>
allowed? (It is required for dependent <TT>X</TT> where <TT>Y</TT> is a
<I>template-id</I>, I believe, but it doesn't seem to be disallowed elsewhere.)
    
<P>The question also holds for '<TT>.template</TT>' and '<TT>-&gt;template</TT>'.</P>
    
<P><B>Proposed Resolution (04/99):</B>
Append to 14.2 [temp.names]
 paragraph 5:</P>
<BLOCKQUOTE>Furthermore, names of member templates shall not be prefixed
by the keyword <TT>template</TT> if the <I>postfix-expression</I> or <I>qualified-id</I>
does not appear in the scope of a template. [<I>Note:</I> just as is the case
with the <TT>typename</TT> prefix, the <TT>template</TT> prefix is allowed
in cases where it is not strictly necessary; i.e., when the expression
on the left of the <TT>-&gt;</TT> or <TT>.</TT>, or the <I>nested-name-specifier</I>
is not dependent on a <I>template-parameter</I>. ]</BLOCKQUOTE>
<BR><BR><HR><A NAME="38"></A><H4>38.
  
Explicit template arguments and operator functions
</H4><B>Section: </B>14.2&#160; [temp.names]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Wiegley
 &#160;&#160;&#160;

 <B>Date: </B>17 Aug 1998<BR>





<P>It appears from the grammar that explicit template arguments cannot
be specified for overloaded operator names. Does this mean that
template operators can never be friends?</P>
 
<P>But assuming that I read things wrong, then I should be able to
specify a global template '<TT>operator +</TT>' by writing:</P>

<PRE>
    friend A::B operator + &lt;&gt;(char&amp;);
</PRE>
<U>John Spicer:</U>

<P>You <B>should</B> be able to have explicit template arguments on operator
functions, but the grammar does seem to prohibit it (unless I'm reading
it incorrectly). This is an error in the grammar, they should be permitted.</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>Change the grammar specified in 13.5 [over.oper]
paragraph 1 from <BR>

<UL>
<I>operator-function-id:</I>
<UL><TT>operator</TT> <I>operator</I></UL>
</UL>

to<BR>

<UL>
<I>operator-function-id:</I>
<UL><TT>operator</TT> <I>operator</I><BR>
<TT>operator</TT> <I>operator</I> <TT>&lt;</TT>
<I>template-argument-list<SUB>opt</SUB></I> <TT>&gt;</TT>
</UL>
</UL>
</P>
<BR><BR><HR><A NAME="100"></A><H4>100.
  
Clarify why string literals are not allowed as template arguments
</H4><B>Section: </B>14.3.2&#160; [temp.arg.nontype]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>9 Mar 1999<BR>



<P>The explanation in
14.3.2 [temp.arg.nontype]

paragraph 2 of why a string literal cannot be
used as a template argument leaves something to be desired:</P>
<BLOCKQUOTE>
...because a string literal is an object with internal linkage.
</BLOCKQUOTE>
I can't find anything that says that a string literal has
internal linkage.  In fact, I'd be pretty surprised if I did,
since linkage is defined (in
3.5 [basic.link]
) strictly in terms of
names, and a string literal doesn't have a name.

Actually, I think that it's the namelessness of a string literal
that prevents it from being a template argument; only the
third and fourth bullets of
14.3.2 [temp.arg.nontype]

paragraph 1 could conceivably apply,
and both of those require that the entity have a name (i.e.,
that they be given as an <I>id-expression</I>).

<P><B>Proposed Resolution (10/99):</B>
In 14.3.2 [temp.arg.nontype]
 paragraph 2, change</P>

<BLOCKQUOTE>
[<I>Note:</I> a string literal
(2.14.5 [lex.string]
) is not an acceptable
<I>template-argument</I> because a string literal is an object
with internal linkage.
</BLOCKQUOTE>

to

<BLOCKQUOTE>
[<I>Note:</I> a string literal
(2.14.5 [lex.string]
) does not satisfy the
requirements of  any of these categories and thus is not an
acceptable <I>template-argument</I>.
</BLOCKQUOTE>
<BR><BR><HR><A NAME="249"></A><H4>249.
  
What is a member function template?
</H4><B>Section: </B>14.5.1.1&#160; [temp.mem.func]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>David Thornley
 &#160;&#160;&#160;

 <B>Date: </B>11 Oct 2000<BR>


<P>The phrase "member function template" is used in
3.2 [basic.def.odr] paragraph 5 in the list of entities whose
definitions can appear more than once in a program, with a
cross-reference to 14.5.1.1 [temp.mem.func].  The title of
that section is "Member functions of class templates," and paragraph 1
of that section says,</P>

<BLOCKQUOTE>

A member function template may be defined outside of the class
template in which it is declared.

</BLOCKQUOTE>

<P>The example in that paragraph shows a non-template member function
of a class template being defined.  This gives the impression that the
phrase "member function template" is intended to refer to a member
function of a class template.</P>

<P>If this usage were intended, much of the rest of the Standard
would be unintelligible: objects of class template specializations
could not be copied (12.8 [class.copy] paragraph 3),
member functions of class templates could not be declared
<TT>virtual</TT> (14.5.2 [temp.mem] paragraph 3),
etc.</P>

<P><B>Suggested resolution:</B></P>

<P>Change "member function template" to "member function of a class
template" in both 3.2 [basic.def.odr] paragraph 5 and
14.5.1.1 [temp.mem.func] paragraph 1.</P>

<P>(See also <A HREF="
     cwg_active.html#205">issue 205</A>.)</P>

<P><B>Proposed resolution (10/00):</B> As suggested.</P>

<BR><BR><HR><A NAME="116"></A><H4>116.
  
Equivalent and functionally-equivalent function templates
</H4><B>Section: </B>14.5.6.1&#160; [temp.over.link]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>11 May 1999<BR>





<P>14.5.6.1 [temp.over.link]
, paragraphs 5 and 6,
describes equivalence and
functional equivalence for expressions involving template
parameters.  As a note in paragraph 5 points out, such
expressions may involve type parameters as well as non-type
parameters.</P>

<P>Paragraph 7, however, describes the equivalence of function
templates only with respect to non-type template parameters.
It appears to be unspecified how to determine the equivalence
of template functions whose types involve expressions that
use template type parameters.</P>

<PRE>
    template &lt;int I&gt; struct S { };

    // The following two declarations are equivalent:
    template &lt;int I&gt; void f(S&lt;I&gt;);
    template &lt;int J&gt; void f(S&lt;J&gt;);

    // The IS doesn't say whether these are equivalent:
    template &lt;class T&gt; void f(S&lt;sizeof(T)&gt;);
    template &lt;class T&gt; void f(S&lt;sizeof(T)&gt;);
</PRE>

<P><B>Proposed resolution (10/99):</B>
Remove the three uses of the words "non-type" in
14.5.6.1 [temp.over.link]
 paragraph 7.</P>
<BR><BR><HR><A NAME="120"></A><H4>120.
  
Nonexistent non-terminal <I>qualified-name</I>
</H4><B>Section: </B>14.6&#160; [temp.res]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Bill Gibbons
 &#160;&#160;&#160;

 <B>Date: </B>28 May 1999<BR>



<P>In 14.6 [temp.res]
, references to the
nonexistent syntactic non-terminal <I>qualified-name</I> occur twice
in paragraph 3, twice in paragraph 4, and once in paragraph 5.  There
is also a reference in
14.1 [temp.param]
 paragraph 2.</P>

<P><B>Proposed resolution (10/99):</B> Change
the reference in all these cases to <I>qualified-id</I>.</P>
<BR><BR><HR><A NAME="121"></A><H4>121.
  
Dependent type names with non-dependent <I>nested-name-specifier</I>s
</H4><B>Section: </B>14.6&#160; [temp.res]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Bill Gibbons
 &#160;&#160;&#160;

 <B>Date: </B>28 May 1999<BR>



<P>The wording in
14.6 [temp.res]
 paragraph 3:</P>
<BLOCKQUOTE>
A <I>qualified-name</I> that refers to a type and that depends on a
<I>template-parameter</I>
(14.6.2 [temp.dep]
) shall be prefixed by the keyword
<TT>typename</TT>
to indicate that the <I>qualified-name</I> denotes a type, forming an
elaborated-type-specifier
(7.1.6.3 [dcl.type.elab]
).
</BLOCKQUOTE>

was intended to say:
<BLOCKQUOTE>
A <I>qualified-id</I> that refers to a type and in which the
<I>nested-name-specifier</I> depends on a <I>template-parameter</I>
(14.6.2 [temp.dep]
) shall ...
</BLOCKQUOTE>

in much the same vein as
14.6.2.1 [temp.dep.type], second bullet, first half.

<P><B>Proposed resolution (10/00):</B> As suggested.</P>
<BR><BR><HR><A NAME="183"></A><H4>183.
  
<TT>typename</TT> in explicit specializations
</H4><B>Section: </B>14.6&#160; [temp.res]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>9 Nov 1999<BR>





<P><U>John Spicer</U>:
In 14.6 [temp.res]
 paragraph 5, 
the standard says</P>

<BLOCKQUOTE>
The keyword <TT>typename</TT> shall only be used in
template declarations and definitions...
</BLOCKQUOTE>

My understanding of the intent of this restriction is to say that
<TT>typename</TT> is only allowed in contexts in which template
dependent names can be found, but the wording leaves open to
interpretation whether <TT>typename</TT> is allowed in an explicit
specialization, such as:

<PRE>
    template &lt;class T&gt; struct A {};
    template &lt;class T&gt; struct B { typedef int X; };
    template &lt;&gt; struct A&lt;int&gt; {
        typename B&lt;int&gt;::X x;
    };
</PRE>

My understanding is that such usage is not permitted.
This should be clarified one way or the other.

<P><U>Mike Miller</U>:
I agree with your understanding that you are not allowed to
use <TT>typename</TT> in an explicit specialization.  However, I think
the standard already says that &#8212; an explicit specialization
is not a template declaration.  According to the grammar in
14 [temp]
 paragraph 1, a
<I>template-declaration</I> must have a non-empty
<I>template-parameter-list</I>.</P>

<P><U>Nathan Myers</U>:
Is there any actual reason for this restriction?  Its only apparent
effect is to make it harder to specialize templates, with no
corresponding benefit.</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>In 14.6 [temp.res] paragraph 5, replace</P>

<BLOCKQUOTE>

The keyword <TT>typename</TT> shall only be applied to qualified
names, but those names need not be dependent.

</BLOCKQUOTE>

<P>with</P>

<BLOCKQUOTE>

The keyword <TT>typename</TT> shall be applied only to qualified
names, but those names need not be dependent.  The keyword
<TT>typename</TT> shall be used only in contexts in which dependent
names can be used.  This includes template declarations and
definitions but excludes explicit specialization declarations and
explicit instantiation declarations.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="213"></A><H4>213.
  
Lookup in dependent base classes
</H4><B>Section: </B>14.6.2&#160; [temp.dep]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>10 Mar 2000<BR>




<P>Paragraphs 3-4 of 14.6.2 [temp.dep] say, in part,</P>

<BLOCKQUOTE>

if a base class of [a class] template depends on a
<I>template-parameter</I>, the base class scope is not examined during
name lookup until the class template is instantiated...  If a base
class is a dependent type, a member of that class cannot hide a name
declared within a template, or a name from the template's enclosing
scope.

</BLOCKQUOTE>

<P><U>John Spicer</U>: The wording in paragraph 4 seems particularly
odd to me.  It essentially changes the order in which scopes are
considered.  If a scope outside of the template declares a given name,
that declaration hides entities of the same name from template
dependent base classes (but not from nondependent base classes).</P>

<P>In the following example, the calls of <TT>f</TT> and <TT>g</TT>
are handled differently because <TT>B::f</TT> cannot hide
<TT>::f</TT>, but <TT>B::g</TT> doesn't try to hide anything, so it
can be called.</P>

<PRE>
    extern "C" int printf(char *, ...);
    template &lt;class T&gt; struct A : T {
        void h(T t) {
            f(t);  // calls ::f(B)
            g(t);  // calls B::g
        }
    };

    struct B {
        void f(B){printf("%s", "in B::f\n");}
        void g(B){printf("%s", "in B::g\n");}
    };

    void f(B){printf("%s", "in ::f\n");}

    int main()
    {
        A&lt;B&gt; ab;
        B b;
        ab.h(b);
    }
</PRE>

<P>I don't think the current wording in the standard provides a useful
facility.  The author of class <TT>A</TT> can't be sure that a given
call is going to call a base class function unless the base class is
explicitly specified.  Adding a new global function could cause the
program to suddenly change meaning.</P>

<P>What I <I>thought</I> the rule was is, "If a base class is a
dependent type a member of that class is not found by unqualified
lookup".</P>

<P><U>Derek Inglis:</U> My understanding is the same except that I'd
remove the word "qualified" from your sentence.</P>

<P><U>Erwin Unruh</U>: My interpretation is based on 14.6.4 [temp.dep.res] and especially 14.6.4.2 [temp.dep.candidate] (and
largely on my memory of the discussions). For all unqualified names
you do something like the following algorithm:</P>

<OL>
<LI>check whether it is a dependent function call</LI>
<LI>Do a lookup in the definition context and remember what you found there</LI>
<LI>Do a Koenig-Lookup at instantiation time</LI>
<LI>perform overloading if necessary</LI>
</OL>

<P>Regarding names from base classes you cannot find them in 2) because you
don't know what base class you have. You cannot find them in 3) because
members of classes are not found by Koenig lookup (only namespaces are
considered). So you don't find them at all (for unqualified names).</P>

<P>For a qualified name, you start lookup for each 'part' of the qualification.
Once you reach a dependent part, you stop and continue lookup at the
instantiation point. For example:</P>

<PRE>
    namespace A {
      namepace B {
	template &lt;class T&gt; class C {
	  template &lt;class U&gt; class D {
	    typedef int E;
	    // ...
	  };
	};
      };
    };

    template &lt;class T&gt; class F : public T {
      typename A::B::C&lt;int&gt;::D&lt;T&gt;::E var1;
      typename A::B::C&lt;T&gt;::D&lt;int&gt;::E var2;
      typename F::T::X var3;
    }
</PRE>

<P>For <TT>var1</TT> you do lookup for <TT>A::B::C&lt;int&gt;::D</TT>
at definition time, for <TT>var2</TT> you only do lookup for
<TT>A::B::C</TT>. The rest of the lookup is done at instantiation time
since specialisations could change part of the lookup. Similarly the
lookup for <TT>var3</TT> stops after <TT>F::T</TT> at definition
time.</P>

<P>My impression was that an unqualified name never refers to a name
in a dependent base class.</P>

<P>(See also <A HREF="
     cwg_defects.html#197">issue 197</A>.)</P>

<P><B>Proposed resolution (10/00):</B></P>

<OL>

<LI>

<P>In 14.6.2 [temp.dep] paragraph 3, replace</P>

<BLOCKQUOTE>

In the definition of a class template or in the definition of a member
of such a template that appears outside of the template definition, if
a base class of this template depends on a <I>template-parameter</I>,
the base class scope is not examined during name lookup until the
class template is instantiated.

</BLOCKQUOTE>

<P>with</P>

<BLOCKQUOTE>

In the definition of a class template or a member of a class template,
if a base class of the class template depends on a
<I>template-parameter</I>, the base class scope is not examined during
unqualified name lookup either at the point of definition of the class
template or member or during an instantiation of the class template or
member.

</BLOCKQUOTE>

</LI>

<LI>

<P>Remove from 14.6.2 [temp.dep] paragraph 4:</P>

<BLOCKQUOTE>

If a base class is a dependent type, a member of that class cannot
hide a name declared within a template, or a name from the template's
enclosing scopes.

</BLOCKQUOTE>

</LI>

</OL>

<BR><BR><HR><A NAME="108"></A><H4>108.
  
Are classes nested in templates dependent?
</H4><B>Section: </B>14.6.2.1&#160; [temp.dep.type]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mark Mitchell
 &#160;&#160;&#160;

 <B>Date: </B>14 Apr 1999<BR>





<P><U>Mark Mitchell (via John Spicer):</U> Given:</P>
<PRE>
  template &lt;class T&gt; struct S {
     struct I1 {
       typedef int X;
     };
     struct I2 : public I1 {
        X x;
     };
  };
</PRE>
<P>Is this legal?  The question really boils down to asking whether or
not <TT>I1</TT> is a dependent type.  On the one hand, it doesn't seem to fit
any of the qualifications in 14.6.2.1 [temp.dep.type]
.
On the other, 14.7.3 [temp.expl.spec]
 allows
explicit specialization of a member class of a class template, so something
like:</P>
<PRE>
  template &lt;&gt; 
  struct S&lt;double&gt;::I1 {
     int X;
  };
</PRE>
<P>is apparently legal.  But, then, `X' no longer refers to a type name.
So, it seems like `I1' should be classified as dependent.  What am I
missing?</P>

<P><U>Erwin Unruh:</U> I wrote that particular piece of text and I just
missed the problem above. It is intended to be a dependent type. The
reasoning is that <TT>I1</TT> is just a shorthand for
<TT>S&lt;T&gt;::I1</TT> which clearly is
dependent.</P>

<P><B>Suggested Resolution:</B> (Erwin Unruh)</P>
<P>I think the list of what is a dependent type should be extended to cover
"a type declared and used within the same template" modulo of
phrasing.</P>

<P>(See also paper J16/00-0009 = WG21 N1231.  This issue is also
somewhat related to <A HREF="
     cwg_active.html#205">issue 205</A>: classes
nested inside template classes are, in some sense, "templates," just
as non-template member functions of class templates and static data
members of class templates are "templates.")</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>Add after 14.6.1 [temp.local] paragraph 2:</P>

<BLOCKQUOTE>

Within the scope of a class template, when the unqualified name of a
nested class of the class template is referred to, it is equivalent to
the name of the nested class qualified by the name of the enclosing
class template. [<I>Example:</I>

<PRE>
    template &lt;class T&gt; struct A {
	class B {};
	// B is equivalent to A::B, which is equivalent to A&lt;T&gt;::B,
	// which is dependent.
	class C : B { };
    };
</PRE>

&#8212;<I>end example</I>] 

</BLOCKQUOTE>

<BR><BR><HR><A NAME="206"></A><H4>206.
  
Semantic constraints on non-dependent names
</H4><B>Section: </B>14.6.3&#160; [temp.nondep]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>23 Feb 2000<BR>


<P>At what point are semantic constraints applied to uses of
non-dependent names in template definitions?  According to
14.6.3 [temp.nondep]
, such names are looked up
and bound at the point at which they are used, i.e., the point of
definition and not the point of instantiation.  However, the text does
not mention the checking of semantic constraints.</P>

<P>Contrast this omission with the treatment of names in default
argument expressions given in
8.3.6 [dcl.fct.default]
 paragraph 5, where
the treatment of semantic constraints is explicit:</P>

<BLOCKQUOTE>
The names in the expression are bound, and the semantic constraints
are checked, at the point where the default argument expression
appears.
</BLOCKQUOTE>

The following code is an example of where this distinction matters:

<PRE>
    struct S;

    template &lt;class T&gt; struct Q {
        S s;    // incomplete type if semantic constraints
                // are applied in the definition context
    };

    struct S { };

    // Point of instantiation of Q&lt;int&gt;; S is complete here

    Q&lt;int&gt; si;        
</PRE>

There is real-world code that depends on late checking of semantic
constraints.  The Standard should be explicit about whether this code
is broken or not.

<P><B>Proposed resolution (10/00):</B></P>

<P>In 14.6 [temp.res] paragraph 7, add the following
immediately preceding the note:</P>

<BLOCKQUOTE>

If a type used in a non-dependent name is incomplete at the point at
which a template is defined but is complete at the point at which an
instantiation is done, and if the completeness of that type affects
whether or not the program is well-formed or affects the semantics of
the program, the program is ill-formed; no diagnostic is required.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="22"></A><H4>22.
  
Template parameter with a default argument that refers to itself
</H4><B>Section: </B>14.6.4&#160; [temp.dep.res]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>unknown
 &#160;&#160;&#160;

 <B>Date: </B>unknown<BR>





<P>14.1 [temp.param]
 paragraph 13 says:</P>
<BLOCKQUOTE>The scope of a <I>template-parameter</I> extends from its point of
declaration until the end of its template. In particular, a <I>template-parameter</I>
can be used in the declaration of subsequent <I>template-parameter</I>s and their
default arguments.</BLOCKQUOTE>
Is the following well-formed?
<PRE>
    template&lt;class U = U&gt; class X { ... };
</PRE>

<P><I>[Note: this issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#187">issue 187</A>.]</I></P>
<BR><BR><HR><A NAME="24"></A><H4>24.
  
Errors in examples in 14.7.3
</H4><B>Section: </B>14.7.3&#160; [temp.expl.spec]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>unknown
 &#160;&#160;&#160;

 <B>Date: </B>unknown<BR>





<P><B>Problem Description:</B>
At least four of the examples in 14.7.3 [temp.expl.spec]
 have errors. </P>

<P><B>Proposed Resolution (10/99):</B></P>

<P>1. Change the example in paragraph 8 from: </P>
<BLOCKQUOTE>
[<I>Example:</I>
<PRE>
    // <I>file #1 </I>
    #include &lt;vector&gt; 
    // <I>Primary class template</I> vector
    export template&lt;class T&gt; void f(t) { 
        vector&lt;T&gt; vec;         // <I>should match the specialization</I>
        /* ... */ 
    } 

    // <I>file #2 </I>
    #include &lt;vector&gt; 
    class B { }; 
    // <I>Explicit specialization of </I>vector<I> for </I>vector&lt;B&gt;
    template&lt;class T&gt; class vector&lt;B&gt; { /* ... */ } 
    template&lt;class T&gt; void f(T); 
    void g(B b) { 
        f(b);                   // <I>ill formed: </I>
                                // f&lt;B&gt; <I>should refer to </I>vector&lt;B&gt;<I>, but the </I>
                                // <I>specialization was not declared with the </I>
                                // <I>definition of </I>f<I> in file #1 </I>
    } 
</PRE>
<I>&#8212;end example</I>]
</BLOCKQUOTE>
to: 
<BLOCKQUOTE>
[<I>Example: </I>
<PRE>
    // <I>file #1 </I>
    #include &lt;vector&gt; 
    // <I>Primary class template</I> vector
    export template&lt;class T&gt; void f(T) { 
        std::vector&lt;T&gt; vec;     // <I>should match the specialization </I>
        /* ... */ 
    }; 

    // <I>file #2 </I>
    #include &lt;vector&gt; 
    class B { }; 
    // <I>Explicit specialization of </I>vector<I> for </I>vector&lt;B&gt;
    namespace std { 
        template&lt;&gt; class vector&lt;B&gt; { /* ... */ }; 
    } 
    template&lt;class T&gt; void f(T); 
    void g(B b) { 
        f(b);                   // <I>ill formed: </I>
                                // f&lt;B&gt; <I>should refer to </I>vector&lt;B&gt;<I>, but the </I>
                                // <I>specialization was not declared with the </I>
                                // <I>definition of </I>f<I> in file #1 </I>
    } 
</PRE>
    <I>&#8212;end example</I>] 
</BLOCKQUOTE>

<P>2. The example in paragraph 16 as it appears in the IS: </P>
<BLOCKQUOTE>
[<I>Example: </I>
<PRE>
    template&lt;class T&gt; struct A { 
        void f(T); 
        template&lt;class X&gt; void g(T, X); 
        void h(T) { } 
    }; 

    // <I>specialization </I>
    template&lt;&gt; void A&lt;int&gt;::f(int); 

    // <I>out of class member template definition </I>
    template&lt;class T&gt; template&lt;class X&gt; void A&lt;T&gt;::g(T,X) { } 

    // <I>member template partial specialization </I>
    template&lt;&gt; template&lt;class X&gt; void A&lt;int&gt;::g(int, X); 

    // <I>member template specialization </I>
    template&lt;&gt; template&lt;&gt; 
        void A&lt;int&gt;::g(int, char);        // X <I>deduced as</I> char
    template&lt;&gt; template&lt;&gt; 
        void A&lt;int&gt;::g&lt;char&gt;(int, char);  // X <I>specified as</I> char

    // <I>member specialization even if defined in class definition </I>
    template&lt;&gt; void A&lt;int&gt;::h(int) { } 
</PRE>
&#8212;<I>end example</I>] 
</BLOCKQUOTE>

The word 'partial' in the third comment in the example
should be removed because this example does not illustrate partial
specialization.  Also, the two specializations of <TT>template&lt;&gt;
template&lt;&gt; void A&lt;int&gt;::g(int, char);</TT> violate
14.7 [temp.spec]
, paragraph 5, which reads:

<BLOCKQUOTE>
No program shall explicitly instantiate any template more than once,
both explicitly instantiate and explicitly specialize a template, or
specialize a template more than once for a given set of
<I>template-argument</I>s.  An implementation is not required
to diagnose a violation of this rule.
</BLOCKQUOTE>

<B>Proposed resolution (10/99): </B>
<BLOCKQUOTE>
[<I>Example: </I>
<PRE>
    template&lt;class T&gt; struct A { 
        void f(T); 
        template&lt;class X1&gt; void g1(T, X1); 
        template&lt;class X2&gt; void g2(T, X2); 
        void h(T) { } 
    }; 

    // <I>specialization </I>
    template&lt;&gt; void A&lt;int&gt;::f(int); 

    // <I>out of class member template definition </I>
    template&lt;class T&gt; template&lt;class X1&gt; void A&lt;T&gt;::g1(T,X1) { } 

    // <I>member template specialization </I>
    template&lt;&gt; template&lt;class X1&gt; void A&lt;int&gt;::g1(int, X1); 

    // <I>member template specialization </I>
    template&lt;&gt; template&lt;&gt; 
        void A&lt;int&gt;::g1(int, char);        // X1 <I>deduced as</I> char 
    template&lt;&gt; template&lt;&gt; 
        void A&lt;int&gt;::g2&lt;char&gt;(int, char);  // X2 <I>specified as</I> char 

    // <I>member specialization even if defined in class definition </I>
    template&lt;&gt; void A&lt;int&gt;::h(int) { } 
</PRE>
&#8212;<I>end example</I>] 
</BLOCKQUOTE>

<P>3. Remove the spurious semicolon (or the curly brackets) from the
end of the last line in the example in paragraph 17.  This is the
example as it appears in the IS:</P>

<BLOCKQUOTE>
[<I>Example: </I>
<PRE>
    template&lt;class T1&gt; class A { 
        template&lt;class T2&gt; class B { 
            void mf(); 
        };
    };
    template&lt;&gt; template&lt;&gt; A&lt;int&gt;::B&lt;double&gt; { };
    template&lt;&gt; template&lt;&gt; void A&lt;char&gt;::B&lt;char&gt;::mf() {};
</PRE>
&#8212;<I>end example</I>]
</BLOCKQUOTE>

<B>Proposed resolution (10/99):</B>

<BLOCKQUOTE>
[<I>Example: </I>
<PRE>
    template&lt;class T1&gt; class A { 
        template&lt;class T2&gt; class B { 
            void mf(); 
        };
    };
    template&lt;&gt; template&lt;&gt; A&lt;int&gt;::B&lt;double&gt;;
    template&lt;&gt; template&lt;&gt; void A&lt;char&gt;::B&lt;char&gt;::mf();
</PRE>
&#8212;<I>end example</I>]
</BLOCKQUOTE>
<P><I>Note (Steve Adamczyk, March 2002): that's still incorrect.  The missing
"<TT>class</TT>" was added editorially when TC1 was prepared.</I></P>

<P>4. Remove spurious semicolons (or curly brackets) from the
specializations of <TT>mf1</TT> and <TT>mf2</TT> in the example in
paragraph 18.  This is the text of the example as it appears in the
IS:</P>

<BLOCKQUOTE>
[<I>Example: </I>
<PRE>
    template&lt;class T1&gt; class A { 
        template&lt;class T2&gt; class B { 
            template&lt;class T3&gt; void mf1(T3); 
            void mf2(); 
        }; 
    }; 
    template&lt;&gt; template&lt;class X&gt; 
        class A&lt;int&gt;::B { }; 
    template&lt;&gt; template&lt;&gt; template&lt;class T&gt; 
        void A&lt;int&gt;::B&lt;double&gt;::mf1(T t) { }; 
    template&lt;class Y&gt; template&lt;&gt; 
        void A&lt;Y&gt;::B&lt;double&gt;::mf2() { }; // <I>ill-formed; </I>B&lt;double&gt;<I> is specialized but </I>
                                         // <I>its enclosing class template </I>A<I> is not </I>
</PRE>
&#8212;<I>end example</I>] 
</BLOCKQUOTE>

<B>Proposed resolution (10/99):</B>
<BLOCKQUOTE>
[<I>Example: </I>
<PRE>
    template&lt;class T1&gt; class A { 
        template&lt;class T2&gt; class B { 
            template&lt;class T3&gt; void mf1(T3); 
            void mf2(); 
        }; 
    }; 
    template&lt;&gt; template&lt;class X&gt; 
        class A&lt;int&gt;::B { }; 
    template&lt;&gt; template&lt;&gt; template&lt;class T&gt; 
        void A&lt;int&gt;::B&lt;double&gt;::mf1(T t) { }
    template&lt;class Y&gt; template&lt;&gt; 
        void A&lt;Y&gt;::B&lt;double&gt;::mf2() { } // <I>ill-formed; </I>B&lt;double&gt;<I> is specialized but </I>
                                         // <I>its enclosing class template </I>A<I> is not </I>
</PRE>
&#8212;<I>end example</I>] 
</BLOCKQUOTE>
<P><I>Note (Steve Adamczyk, March 2002): that's still incorrect.
See <A HREF="
     cwg_defects.html#336">issue 336</A>.</I></P>
<BR><BR><HR><A NAME="64"></A><H4>64.
  
Partial ordering to disambiguate explicit specialization
</H4><B>Section: </B>14.7.3&#160; [temp.expl.spec]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>13 Oct 1998<BR>



<P>Paragraph 12 should address partial ordering. It wasn't updated
when that change was made and conflicts with
14.5.6.2 [temp.func.order]
 paragraph 1.</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>Remove
14.7.3 [temp.expl.spec]
 paragraph 12 and the
example that follows.</P>
<BR><BR><HR><A NAME="241"></A><H4>241.
  
Error in example in 14.8.1
</H4><B>Section: </B>14.8.1&#160; [temp.arg.explicit]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>9 Aug 2000<BR>


<P>14.8.1 [temp.arg.explicit] paragraph 6 contains the following
example:</P>

<PRE>
    namespace A {
        struct B { };
        template&lt;int X&gt; void f();
    }
    namespace C {
        template&lt;class T&gt; void f(T t);
    }
    void g(A::B b) {
        f&lt;3&gt;(b);    // ill-formed: not a function call
        A::f&lt;3&gt;(b); // well-formed
        C::f&lt;3&gt;(b); // ill-formed; argument dependent lookup
                    // only applies to unqualified names
        using C::f;
        f&lt;3&gt;(b);    // well-formed because C::f is visible; then
                    // A::f is found by argument dependent lookup
    }
</PRE>

<P><TT>A::f()</TT> should have a parameter of type <TT>A::B</TT>.</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>In the example in 14.8.1 [temp.arg.explicit] paragraph 6,
change the third line from</P>

<PRE>
        template &lt;int X&gt; void f();
</PRE>

<P>to</P>

<PRE>
        template &lt;int X&gt; void f(B);
</PRE>

<BR><BR><HR><A NAME="181"></A><H4>181.
  
Errors in template <I>template-parameter</I> example
</H4><B>Section: </B>14.8.2.5&#160; [temp.deduct.type]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>4 Nov 1999<BR>





<P>14.8.2.5 [temp.deduct.type]
 paragraph 18 uses
incorrect syntax.  Instead of</P>

<PRE>
    template &lt;template X&lt;class T&gt; &gt; struct A { };
    template &lt;template X&lt;class T&gt; &gt; void f(A&lt;X&gt;) { }
</PRE>

it should be

<PRE>
    template &lt;template &lt;class T&gt; class X&gt; struct A { };
    template &lt;template &lt;class T&gt; class X&gt; void f(A&lt;X&gt;) { }
</PRE>

<P><B>Proposed resolution (10/00):</B> As suggested.</P>

<P><I>[Note: this section was numbered 14.8.2.4 in ISO/IEC 14882:2003.]</I></P>
<BR><BR><HR><A NAME="98"></A><H4>98.
  
Branching into try block
</H4><B>Section: </B>15&#160; [except]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Jack Rouse
 &#160;&#160;&#160;

 <B>Date: </B>23 Feb 1999<BR>



<P>At the top of clause 15, in paragraph 2, it says:</P>
<BLOCKQUOTE>
A <TT>goto</TT>, <TT>break</TT>, <TT>return</TT>, or <TT>continue</TT> statement can be used to transfer
control out of a try block or handler, but not into one.
</BLOCKQUOTE>
What about <TT>switch</TT> statements?
<PRE>
    switch ( f() )
    {
    case 1:
         try {
             g();
    case 2:
             h();
         }
         catch (...)
         {
             // handler
         }
    break;
    }
</PRE>

<B>Daveed Vandevoorde:</B>

<P>Consider:</P>
<PRE>
    void f() {
        try {
        label:
            ;
        } catch(...) {
            goto label;
        }
    }
</PRE>

Now the phrase "try block" (without a hyphen) is used in paragraph
1 in a way that causes me to think that it is not intended to
include the corresponding handlers. On the other hand, the grammar
entity "<I>try-block</I>" (with hyphen) does include the handlers.

So is the intent to prohibit the above or not?

<P><B>Proposed resolution (10/00:</B></P>

<P>Change text in 15 [except] paragraph 2 from:</P>

<BLOCKQUOTE>A <TT>goto</TT>, <TT>break</TT>, <TT>return</TT>, or
<TT>continue</TT> statement
can be used to transfer control out of a try block or handler, but not
into one.
</BLOCKQUOTE>
to:
<BLOCKQUOTE>
A <TT>goto</TT> or <TT>switch</TT> statement shall not be used
to transfer control into a try block or into a handler.
<BR>[ <I>Example:</I>
<BLOCKQUOTE><TT>void f() {</TT>
<BR><TT>&#160; goto l1;&#160; // Ill-formed</TT>
<BR><TT>&#160; goto l2;&#160; // Ill-formed</TT>
<BR><TT>&#160; try {</TT>
<BR><TT>&#160;&#160;&#160; goto l1;&#160; // OK</TT>
<BR><TT>&#160;&#160;&#160; goto l2;&#160; // Ill-formed</TT>
<BR><TT>&#160;&#160;&#160; l1: ;</TT>
<BR><TT>&#160; } catch (...) {</TT>
<BR><TT>&#160;&#160;&#160; l2: ;</TT>
<BR><TT>&#160;&#160;&#160; goto l1;&#160; // Ill-formed</TT>
<BR><TT>&#160;&#160;&#160; goto l2;&#160; // OK</TT>
<BR><TT>&#160; }</TT>
<BR><TT>}</TT>
</BLOCKQUOTE>
&#8212;<I>end example</I> ]
<BR>A <TT>goto</TT>, <TT>break</TT>, <TT>return</TT>, or <TT>continue</TT>
statement can be used to transfer control out of a try block or handler.
</BLOCKQUOTE>

<P>(See also <A HREF="
     cwg_defects.html#246">issue 246</A>.)</P>

<BR><BR><HR><A NAME="210"></A><H4>210.
  
What is the type matched by an exception handler?
</H4><B>Section: </B>15.3&#160; [except.handle]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Scott Douglass
 &#160;&#160;&#160;

 <B>Date: </B>6 Mar 2000<BR>



<P>15.3 [except.handle] paragraph 3 says,</P>

<BLOCKQUOTE>

A <I>handler</I> is a match for a <I>throw-expression</I> with an
object of type <TT>E</TT>...

</BLOCKQUOTE>

<P>This wording leaves it unclear whether it is the dynamic type of the
object being thrown or the static type of the expression that
determines whether a handler is a match for a given exception.  For
instance,</P>

<PRE>
    struct B { B(); virtual ~B(); };
    struct D : B { D(); };
    void toss(const B* b) { throw *b; }
    void f() { const D d; toss(&amp;d); }
</PRE>

<P>In this code, presumably the type to be matched is <TT>B</TT> and not
<TT>const D</TT> (15.1 [except.throw]).</P>

<P><B>Suggested resolution:</B> Replace the cited wording as follows:</P>

<BLOCKQUOTE>

A <I>handler</I> is a match for a <I>throw-expression</I> which
initialized a temporary (15.1 [except.throw]) of type
<TT>E</TT>...

</BLOCKQUOTE>

<P><B>Proposed resolution (10/00):</B></P>

<OL>

<LI><P>Change 15.1 [except.throw] paragraph 3 from</P>

<BLOCKQUOTE>

A <I>throw-expression</I> initializes a temporary object, the type of
which is determined...

</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>

A <I>throw-expression</I> initializes a temporary object, called the
<I>exception object</I>, the type of which is determined...

</BLOCKQUOTE>
</LI>

<LI><P>Change 15.3 [except.handle] paragraph 3 from</P>

<BLOCKQUOTE>

A <I>handler</I> is a match for a <I>throw-expression</I> with an
object of type <TT>E</TT> if...

</BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>

A <I>handler</I> is a match for an exception object of type <TT>E</TT>
if...

</BLOCKQUOTE>
</LI>
</OL>

<BR><BR><HR><A NAME="25"></A><H4>25.
  
Exception specifications and pointers to members
</H4><B>Section: </B>15.4&#160; [except.spec]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>unknown
 &#160;&#160;&#160;

 <B>Date: </B>unknown<BR>





<P>15.4 [except.spec]
 paragraph 3 should say what
happens when two pointers to members with
different exception specifications are assigned to each other, initialized
with one another, etc.</P>

<P><B>Proposed Resolution (04/99):</B>
Change the text in 15.4 [except.spec]
 paragraph 3 from:</P>
<BLOCKQUOTE>Similarly, any function or pointer to function assigned to,
or initializing, a pointer to function shall only allow exceptions that
are allowed by the pointer or function being assigned to or initialized.</BLOCKQUOTE>
to:
<BLOCKQUOTE>A similar restriction applies to assignment to and initialization
of pointers to functions, pointers to member functions, and references
to functions: the target entity shall allow at least the exceptions allowed
by the source value in the assignment or initialization.</BLOCKQUOTE>
<BR><BR><HR><A NAME="126"></A><H4>126.
  
Exception specifications and <TT>const</TT>
</H4><B>Section: </B>15.4&#160; [except.spec]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Martin von Loewis
 &#160;&#160;&#160;

 <B>Date: </B>8 June 1999<BR>



<P>The standard is inconsistent about constness inside exception
specifications.</P>

<PRE>
    struct X {};
    struct Y:X {};

    const Y bar() {return Y();}

    void foo()throw(const X)
    {
      throw bar();
    }
</PRE>

It is unclear whether calling <TT>foo</TT> will result in a call
to <TT>std::unexpected</TT>.  According to
15.4 [except.spec]
 paragraph 7,
only two cases are treated
specially with regard to inheritance: If "class X" appears in the
<I>type-id-list</I>, or if "class X*" appears in the
<I>type-id-list</I>. Neither is
the case here, so <TT>foo</TT> only allows exceptions of the same type
(<TT>const X</TT>). As a result, <TT>std::unexpected</TT> should be called.

<P>On the other hand, the intent of exception specification appears to
allow an implementation of this example as</P>

<PRE>
    void foo()
    try{
      throw bar();
    }catch(const X){
      throw;
    }catch(...){
      std::unexpected();
    }
</PRE>

According to
15.3 [except.handle]
,
this replacement code would catch the exception, so
<TT>std::unexpected</TT> would not be called.

<P>Suggested resolution: Change
15.4 [except.spec]
 paragraph 7 to read</P>

<BLOCKQUOTE>
A function is said to <I>allow</I> all exception objects of all
types <TT>E</TT> for which one of the types <TT>T</TT>
in the <I>type-id-list</I> would be a handler, according to
15.3 [except.handle]
.
</BLOCKQUOTE>

<P><B>Proposed resolution (10/00):</B></P>

<P>Replace 15.4 [except.spec] paragraph 7 with the
following:</P>

<BLOCKQUOTE>

A function is said to <I>allow</I> an exception of type <TT>E</TT> if
its <I>exception-specification</I> contains a type <TT>T</TT> for
which a handler of type <TT>T</TT> would be a match (15.3 [except.handle]) for an exception of type <TT>E</TT>.

</BLOCKQUOTE>
<BR><BR><HR><A NAME="145"></A><H4>145.
  
Deprecation of prefix <TT>++</TT>
</H4><B>Section: </B>D.1&#160; [depr.incr.bool]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>23 Jul 1999<BR>



<P>D.1 [depr.incr.bool]

indicates that use of the postfix <TT>++</TT> with a <TT>bool</TT>
operand is
deprecated.
Annex D [depr]

says nothing about prefix <TT>++</TT>.  However, this
use of prefix <TT>++</TT> is also deprecated, according to
5.3.2 [expr.pre.incr]
 paragraph 1.
Presumably D.1 [depr.incr.bool]

should be expanded to cover prefix <TT>++</TT>, or another
section should be added to Annex
D [depr].</P>

<P><B>Proposed resolution (10/00):</B></P>

<P>Change the entire section
D.1 [depr.incr.bool], including its heading, to read as
follows:</P>

<BLOCKQUOTE>

<TABLE CELLSPACING="0" CELLPADDING="0" FRAME="VOID" RULES="NONE" WIDTH="85%">
 <TR>
  <TD>
   <B>D.1 Increment operator with <TT>bool</TT> operand</B>
  </TD>
  <TD ALIGN="RIGHT">
   <B>[depr.incr.bool]</B>
  </TD>
 </TR>
</TABLE>

<P>The use of an operand of type <TT>bool</TT> with the <TT>++</TT>
operator is deprecated (see 5.3.2 [expr.pre.incr] and
5.2.6 [expr.post.incr]).</P>

</BLOCKQUOTE>
<BR><BR><BR><BR><HR><A NAME="FDIS Status"></A><H3>Issues with "FDIS" Status</H3>
<HR><A NAME="248"></A><H4>248.
  
Identifier characters
</H4><B>Section: </B>_N2691_.E&#160; [extendid]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>6 Oct 2000<BR>


<P>[Voted into the WP at the November, 2010 meeting as paper N3146.]</P>



<P>The list of identifier characters specified in the C++ standard
annex _N2691_.E [extendid] and the C99 standard annex D are
different.  The C99 standard includes more characters.</P>

<P>The C++ standard says that the characters are from "ISO/IEC PDTR
10176" while the C99 standard says "ISO/IEC TR 10176".  I'm guessing
that the PDTR is an earlier draft of the TR.</P>

<P>Should the list in the C++ standard be updated?</P>

<P><U>Tom Plum</U>: In my opinion, the "identifier character" issue
has not been resolved with certainty within SC22.</P>

<P>One critical difference in C99 was the decision to allow a compiler
to accept more characters than are given in the annex.  This allows
for future expansion.</P>

<P>The broader issue concerns the venue in which the "identifier
character" issue will receive ongoing resolution.</P>

<P><B>Notes from 10/00 meeting:</B></P>

<P>The core language working group expressed a strong preference
(13/0/5 in favor/opposed/abstaining) that the list of identifier
characters should be extensible, as is the case in C99.  However,
the fact that this topic is under active discussion by other bodies
was deemed sufficient reason to defer any changes to the C++
specification until the situation is more stable.</P>

<P><B>Notes from October, 2005 meeting:</B></P>

<P>The working group expressed interest in the kind of approach taken by
<A href="http://www.w3.org/TR/2004/REC-xml11-20040204/#NT-NameStartChar">
XML 1.1</A>, in which the definition of an identifier character is done
by excluding large ranges of the Unicode character set and accepting any
character outside those ranges, rather than by affirmatively designating
each identifier character in each language.  As noted above, 
consideration of this issue was previously deferred pending other
related standardization efforts.  Clark Nelson will investigate whether
these have reached a point at which progress on this issue in C++ is now
possible.</P>

<P><B>Additional note (May, 2008):</B></P>

<P><A HREF="
     cwg_defects.html#663">Issue 663</A> also deals with this
appendix, and the proposed resolution there is to update the
table to reflect the newest available technical report, ISO/IEC
TR 10176:2003.  That resolution might be seen as sufficient for
this issue, as well.  However, that approach does not address
several of the concerns mentioned in the discussion above:
coordination with WG14, the extensibility of the list of
identifiers, the alternative approach used in the XML
specification, etc.</P>

<BR><BR><HR><A NAME="1063"></A><H4>1063.
  
<TT>[[hiding]]</TT> with non-attribute declarations
</H4><B>Section: </B>_N3225_.7.6.5&#160; [dcl.attr.override]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>2010-03-23<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3272.]</P>



<P>There are some kinds of declarations that can appear in a derived
class and hide names from a base class, but for which the syntax does
not permit a <TT>[[hiding]]</TT> attribute.  For example:</P>

<PRE>
    struct B1 {
        int N;
        int M;
    };
    struct B2 {
        int M;
    };
    struct [[base_check]] D: B1, B2 {
        enum { N };    // hides B1::N but cannot take an attribute
        using B1::M;   // hides B2::M but cannot take an attribute
    };
</PRE>

<P><B>Additional note (October, 2010):</B></P>

<P><I>alias-declaration</I>s should also be considered in this
regard. </P>

<P><B>Notes from the November, 2010 meeting:</B></P>

<P>Paper N3206 did not address these cases; in fact, it introduced
additional member declarations that cannot be annotated as hiding a
base class member (<I>function-definition</I>s and
<I>template-declaration</I>s), because the <TT>new</TT>
<I>virt-specifier</I> applies to a <I>member-declarator</I> and none
of these <I>member-declaration</I>s uses a <I>member-declarator</I>.</P>

<P><B>Additional note (November, 2010):</B></P>

<P>The injected-class-name can also hide a name from a base class
but cannot be annotated with <TT>new</TT>.</P>

<BR><BR><HR><A NAME="1065"></A><H4>1065.
  
<TT>[[hiding]]</TT> with <TT>[[override]]</TT>
</H4><B>Section: </B>_N3225_.7.6.5&#160; [dcl.attr.override]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>2010-03-24<BR>


<P>[Voted into the WP at the November, 2010 meeting as part of paper
N3206.]</P>



<P>The meaning of the <TT>[[base_check]]</TT> and
<TT>[[hiding]]</TT> attributes is defined in terms of hiding as
described in 3.3.10 [basic.scope.hiding].  In that section,
however, hiding is orthogonal to overriding: practically by
definition, a function that overrides a base class virtual
function also hides it.  According to the current specification,
the <TT>[[override]]</TT> and <TT>[[hiding]]</TT> attributes
would always need to be specified together on every overriding
function in a <TT>[[base_check]]</TT> class.  This is presumably
unintended, so the current wording should be amended so that
<TT>[[override]]</TT> implies <TT>[[hiding]]</TT> or some
such.</P>

<BR><BR><HR><A NAME="1133"></A><H4>1133.
  
Keywords vs attributes for control of hiding and overriding
</H4><B>Section: </B>_N3225_.7.6.5&#160; [dcl.attr.override]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting in paper N3206.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US44">N3092 comment
  US&#160;44<BR></A>

<P>The facility for checking hiding and overriding of base class members
should not use the attribute syntax but should use keywords instead.
Concerns about breaking code by changing current identifiers into
keywords can be addressed by using contextual keywords, i.e., by putting
the keywords into syntactic locations where identifiers cannot appear
and thus continuing to allow their use as ordinary identifiers in other
contexts.</P>

<P><B>Notes from the August, 2010 meeting:</B></P>

<P>CWG expressed a preference for non-contextual keywords for these
features.</P>

<BR><BR><HR><A NAME="1144"></A><H4>1144.
  
Remove access declarations
</H4><B>Section: </B>_N3225_.11.3&#160; [class.access.dcl]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-03<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US56">N3092 comment
  US&#160;56<BR></A>

<P>Access declarations were deprecated in the 1998 standard
and have no benefits over <I>using-declaration</I>s. They should be
removed in C++0x.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<OL><LI><P>Delete _N3225_.11.3 [class.access.dcl].</P></LI>

<LI><P>Delete _N3225_.D.3 [depr.access.dcl].</P></LI>

<LI><P>Delete the following production from the grammar in
9.2 [class.mem] paragraph 1:</P></LI>

<UL><I>member-declaration:</I>
<UL>...</UL>
<UL><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>::</TT><I><SUB>opt</SUB> nested-name-specifier</I> <TT>template</TT><I><SUB>opt</SUB> unqualified-id</I> <TT>;</TT></SPAN></UL>
<UL>...</UL>
</UL>

<LI>Change 9.2 [class.mem] paragraph 1 as follows:</LI>

<BLOCKQUOTE>

...Except when used to declare friends (11.4) or to
introduce the name of a member of a base class into a
derived class (7.3.3<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, 11.3</SPAN>), <I>member-declaration</I>s
declare members of the class...

</BLOCKQUOTE>

<LI><P>Delete 7.3.3 [namespace.udecl] paragraph 19:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">[<I>Note:</I> use of <I>access-declaration</I>s
(_N3225_.11.3 [class.access.dcl]) is deprecated; member
<I>using-declaration</I>s provide a better
alternative. &#8212;<I>end note</I>]</SPAN>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="784"></A><H4>784.
  
List of incompatibilities with the previous Standard
</H4><B>Section: </B>1.5&#160; [intro.structure]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>UK
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<P>[Voted into the WP at the March, 2011 meeting as document N3288.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK6">N2800 comment
  UK&#160;6<BR></A>

<P>There should be a list of incompatibilities between the current
and previous Standards, as in ISO/IEC TR 10176 4.1.1 paragraph 9.</P>

<P>(See document N2733 for an initial list of this information.)</P>

<BR><BR><HR><A NAME="1189"></A><H4>1189.
  
Address of distinct base class subobjects
</H4><B>Section: </B>1.8&#160; [intro.object]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Gabriel Dos Reis
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-31<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>1.8 [intro.object] paragraph 6 says,</P>

<BLOCKQUOTE>

Two distinct objects that are neither bit-fields nor base class
subobjects of zero size shall have distinct addresses.

</BLOCKQUOTE>

<P>This formulation leaves open the possibility that two base
class subobjects of the same type could have the same address
(because one or both might be zero-length base class
subobjects).</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change 1.8 [intro.object] paragraph 6 as follows:</P>

<BLOCKQUOTE>

Unless an object is a bit-field or a base class subobject of zero
size, the address of that object is the address of the first byte it
occupies. Two distinct objects that are <SPAN style="text-decoration:line-through;background-color:#FFA0A0">neither</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">not</SPAN> bit-fields <SPAN style="text-decoration:line-through;background-color:#FFA0A0">nor base class subobjects of zero
size</SPAN> shall have distinct addresses<SPAN style="font-weight:bold;background-color:#A0FFA0">, if both have the same
type or if not both are base class subobjects of zero size</SPAN>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1102"></A><H4>1102.
  
Better example of undefined behavior
</H4><B>Section: </B>1.9&#160; [intro.execution]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>GB
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#GB6">N3092 comment
  GB&#160;6<BR></A>

<P>There are core issues surrounding the undefined behavior
of dereferencing a null pointer. It appears the intent is
that dereferencing <I>is</I> well defined, but using the result
of the dereference will yield undefined behavior. This topic
is too confused to be the reference example of undefined
behavior, or should be stated more precisely if it is to be
retained.</P>

<P>(See also <A HREF="
     cwg_active.html#232">issue 232</A>.)</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<P>Change 1.9 [intro.execution] paragraph 4 as follows:</P>

<BLOCKQUOTE>

Certain other operations are described in this International Standard
as undefined (for example, the effect of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">dereferencing the null
pointer</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">attempting to modify a <TT>const</TT>
object</SPAN>). [<I>Note:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1173"></A><H4>1173.
  
Unclear specification of effects of signal handling
</H4><B>Section: </B>1.9&#160; [intro.execution]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>GB
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-06<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#GB7">N3092 comment
  GB&#160;7<BR></A>

<P>The current wording of 1.9 [intro.execution] paragraph 6 could
be read as saying that any signal would leave the program in an
unspecified state after completing.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change 1.9 [intro.execution] paragraph 6 as follows:</P>

<BLOCKQUOTE>

<P>When the processing of the abstract machine is
interrupted by receipt of a signal, the values of objects
which are neither</P>

<UL><LI><P>of type <TT>volatile std::sig_atomic_t</TT> nor</P></LI>

<LI><P>lock-free atomic objects (29.4 [atomics.lockfree])</P></LI>

</UL>

<P>are unspecified <SPAN style="font-weight:bold;background-color:#A0FFA0">during the execution of the signal
handler</SPAN>, and the value of any object not in either of
these two categories that is modified by the handler becomes
undefined.</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1176"></A><H4>1176.
  
Definition of release sequence
</H4><B>Section: </B>1.10&#160; [intro.multithread]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>CA, GB
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-10<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting as part of paper
N3196.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#CA12">N3092 comment
  CA&#160;12<BR></A>
<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#GB9">N3092 comment
  GB&#160;9<BR></A>

<P>The current wording of the standard suggests
that release sequences are maximal with respect to
sequence inclusion, i.e. that if there are two release
operations in the modification order,</P>

<PRE>
mod       mod
rel1-----&gt;rel2-----&gt;w
</PRE>

<P>then <TT>[rel1;rel2;w]</TT> is the only release sequence, as the
other candidate <TT>[rel2;w]</TT> is included in it. This
interpretation precludes synchronizing with releases which have other
releases sequenced-before them. We believe that the intention is
actually to define the maximal release sequence from a particular
release operation, which would admit both <TT>[rel1;rel2;w]</TT> and
<TT>[rel2;w]</TT>.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change 1.10 [intro.multithread] paragraph 6 as follows:</P>

<BLOCKQUOTE>

<P>A <I>release sequence</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">from a release operation
<I>A</I></SPAN> on an atomic object <I>M</I> is a maximal contiguous
sub-sequence of side effects in the modification order of
<I>M</I>, where the first operation is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a release</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>A</I></SPAN>, and every subsequent operation</P>

<UL><LI><P>is performed by the same thread that performed the release,
or</P></LI>

<LI><P>is an atomic read-modify-write operation.</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1177"></A><H4>1177.
  
Intra-thread dependency-ordered-before
</H4><B>Section: </B>1.10&#160; [intro.multithread]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>CA
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-10<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting as part of paper
N3196.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#CA15">N3092 comment
  CA&#160;15<BR></A>

<P>The current draft has release/acquire synchronize-with
edges only between a release on one thread and an
acquire on a <I>different</I> thread, whereas the definition of
dependency-ordered-before permits the release and
consume to be on the same thread; it seems odd to permit
the latter. (At the moment function arguments can't race or
sync with each other, but they can be dependency
ordered before each other.)</P>

<P>We don't currently have an example in which this makes a real
difference, but for symmetry could suggest changing the definition of
dependency-ordered-before in 1.10 [intro.multithread].</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change 1.10 [intro.multithread] paragraph 9 as follows:</P>

<BLOCKQUOTE>

<P>An evaluation <I>A</I> is <I>dependency-ordered before</I> an
evaluation <I>B</I> if</P>

<UL><LI><P><I>A</I> performs a release operation on an atomic object
<I>M</I>, and<SPAN style="font-weight:bold;background-color:#A0FFA0">, on another thread,</SPAN> <I>B</I> performs a
consume operation on <I>M</I> and reads a value written by any side
effect in the release sequence headed by <I>A</I>, or</P></LI>

<LI><P>for some evaluation <I>X</I>, <I>A</I> is dependency-ordered
before <I>X</I> and <I>X</I> carries a dependency to
<I>B</I>.</P></LI>

</UL>

<P>[<I>Note:</I>...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1103"></A><H4>1103.
  
Reversion of phase 1 and 2 transformations in raw string literals
</H4><B>Section: </B>2.2&#160; [lex.phases]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US13">N3092 comment
  US&#160;13<BR></A>
<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US14">N3092 comment
  US&#160;14<BR></A>

<P>&#8220;Raw&#8221; strings are still only Pittsburgh-rare
strings: the reversion in phase 3 only applies to an
<I>r-char-sequence</I>.  It should apply to the entire raw
string literal.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<OL><LI><P>Change 2.2 [lex.phases] paragraph 1 phase 1
as follows:</P></LI>

<BLOCKQUOTE>

...(An implementation may use any internal encoding, so long
as an actual extended character encountered in the source
file, and the same extended character expressed in the
source file as a universal-character-name (i.e., using the
<TT>\uXXXX</TT> notation), are handled equivalently
<SPAN style="font-weight:bold;background-color:#A0FFA0">except where this replacement is reverted in a raw
string literal.)</SPAN>.)

</BLOCKQUOTE>

<LI><P>Change 2.2 [lex.phases] paragraph 1 phase 3
as follows:</P></LI>

<BLOCKQUOTE>

...[<I>Example:</I> see the handling of <TT>&lt;</TT> within
a <TT>#include</TT> preprocessing directive. &#8212;<I>end
example</I>] <SPAN style="text-decoration:line-through;background-color:#FFA0A0">Within the r-char-sequence of a raw string
literal, any transformations performed in phases 1 and 2
(trigraphs, universal-character-names, and line splicing)
are reverted.</SPAN>

</BLOCKQUOTE>

<LI><P>Change 2.2 [lex.phases] paragraph 1 phase 5
as follows:</P></LI>

<BLOCKQUOTE>

Each source character set member <SPAN style="text-decoration:line-through;background-color:#FFA0A0">and
universal-character-name</SPAN> in a character literal or a
string literal, as well as each escape sequence <SPAN style="font-weight:bold;background-color:#A0FFA0">and
universal-character-name</SPAN> in a character literal or a
non-raw string literal, is converted to the corresponding
member of the execution character set (2.14.3 [lex.ccon], 2.14.5 [lex.string]); if there is no
corresponding member, it is converted to an
implementation-defined member other than the null (wide)
character.

</BLOCKQUOTE>

<LI><P>Change 2.3 [lex.charset] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

...Additionally, if the hexadecimal value for a
universal-character-name outside the <I>c-char-sequence</I>,
<I>s-char-sequence</I>, or <I>r-char-sequence</I> of a character or string
literal corresponds to a control character (in either of the
ranges 0x000x1F or 0x7F0x9F, both inclusive) or to a
character in the basic source character set, the program is
ill-formed. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Footnote:</I> A sequence of characters
resembling a universal-character-name in an <I>r-char-sequence</I>
(2.14.5 [lex.string]) does not form a
universal-character-name. &#8212;<I>end footnote</I>]</SPAN>

</BLOCKQUOTE>

<LI><P>Change 2.5 [lex.pptoken] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

If the input stream has been parsed into preprocessing
tokens up to a given character:

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">if</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">If</SPAN> the next character
begins a sequence of characters that could be the prefix and
initial double quote of a raw string literal, such as
<TT>R"</TT>, the next preprocessing token shall be a raw
string literal<SPAN style="text-decoration:line-through;background-color:#FFA0A0">;</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">. Between the initial and
final double quote characters of the raw string, any
transformations performed in phases 1 and 2 (trigraphs,
universal-character-names, and line splicing) are reverted;
this reversion shall apply before any
<I>d-char</I>, <I>r-char</I>, or delimiting parenthesis is
identified. The raw string literal is defined as the
shortest sequence of characters that matches the
raw-string pattern</SPAN></P></LI>

<UL><I>encoding-prefix<SUB>opt</SUB></I> <TT>R</TT> <I>raw-string</I></UL>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">otherwise</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Otherwise</SPAN>, the next
preprocessing token is the longest sequence of characters
that could constitute a preprocessing token, even if that
would cause further lexical analysis to fail.</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Delete footnote 24 in 2.14.5 [lex.string] paragraph 2:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Use of characters with trigraph equivalents in a
<I>d-char-sequence</I> may produce unintended results.</SPAN>

</BLOCKQUOTE>

<LI><P>Insert the following examples after 2.14.5 [lex.string] paragraph 4:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Example:</I> The raw string</SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  R"a(
  )\
  a"
  )a"</SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">is equivalent to <TT>"\n)\\\na\"\n"</TT>.  The raw string</SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  R"(??)"</SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">is equivalent to <TT>"\?\?"</TT>.  The raw string</SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  R"#(
  )??="
  )#"</SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">is equivalent to <TT>"\n)\?\?=\"\n"</TT>. &#8212;<I>end
example</I>]</SPAN></P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="985"></A><H4>985.
  
Alternative tokens and user-defined literals
</H4><B>Section: </B>2.6&#160; [lex.digraph]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Michael Wong
 &#160;&#160;&#160;

 <B>Date: </B>19 October, 2009<BR>


<P>2.12 [lex.key] paragraph 2 says,</P>

<BLOCKQUOTE>

Furthermore, the alternative representations shown in Table 4 for
certain operators and punctuators (2.6 [lex.digraph]) are
reserved and shall not be used otherwise:

</BLOCKQUOTE>

<P>Also, 2.6 [lex.digraph] paragraph 2 says,</P>

<BLOCKQUOTE>

In all respects of the language, each alternative token
behaves the same, respectively, as its primary token, except
for its spelling.

</BLOCKQUOTE>

<P>It is not clear whether the following example is well-formed:</P>

<PRE>
    #define STR2(x)  #x
    #define STR(x)   STR2(x)
    int main() {
        return sizeof STR('\0'bitor 0) - sizeof STR('\0'bitor 0);
    }
</PRE>

<P>In this example, <TT>bitor</TT> is not the <TT>|</TT> operator but
the <I>identifier</I> in a <I>user-defined-character-literal</I>.
Does this violate the restrictions of 2.12 [lex.key] and
2.6 [lex.digraph]?</P>

<P><B>Proposed resolution (March, 2011):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#1239">issue 1239</A> in document N3262, since
literal suffix identifiers must begin with an underscore.</P>

<BR><BR><HR><A NAME="1104"></A><H4>1104.
  
Global-scope template arguments vs the <TT>&lt;:</TT> digraph
</H4><B>Section: </B>2.6&#160; [lex.digraph]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US15">N3092 comment
  US&#160;15<BR></A>

<P>Passing a name qualified by the global scope operator <TT>::</TT> as
a template argument can inadvertently trigger recognition of the
<TT>&lt;:</TT> digraph, causing a syntax error.  This should be
handled by a lexical rule similar to the special treament given to
<TT>&gt;&gt;</TT> so that <TT>&lt;::</TT> would be recognized as an
open angle-bracket followed by the scope-resolution operator.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Insert a bullet into the list in 2.5 [lex.pptoken] paragraph
3 as follows:</P>

<BLOCKQUOTE>

If the input stream has been parsed into preprocessing tokens up to a
given character:

<UL><LI><P>if the next character begins a sequence of characters that
could be the prefix and initial double quote of a raw string literal,
such as <TT>R"</TT>, the next preprocessing token shall be a raw string
literal;</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">otherwise, if the next three characters are
<TT>&lt;::</TT> and the subsequent character is neither <TT>:</TT> nor
<TT>&gt;</TT>, the <TT>&lt;</TT> is treated as a preprocessor token by
itself (and not as the first character of the alternative token
<TT>&lt;:</TT>);</SPAN></P></LI>

<LI><P>otherwise, the next preprocessing token is the longest
sequence...</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1105"></A><H4>1105.
  
Issues relating to TR 10176:2003
</H4><B>Section: </B>2.11&#160; [lex.name]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>CA
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting as paper N3146.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#CA24">N3092 comment
  CA&#160;24<BR></A>

<OL>
<LI><P>&#8220;Combining characters should not appear as the first
character of an identifier.&#8221;
[Reference: ISO/IEC TR 10176:2003 (Annex A)]
This is not reflected in FCD.</P></LI>

<LI><P>Restrictions on the first character of an identifier are not
observed as recommended in TR 10176:2003. The inclusion of digits
(outside of those in the basic character set) under
<I>identifer-nondigit</I> is implied by FCD.</P></LI>

<LI><P>It is implied that only the &#8220;main listing&#8221; from
Annex A is included for C++.  That is, the list ends with the Special
Characters section.  This is not made explicit in FCD. Existing
practice in C++03 as well as WG 14 (C, as of N1425) and WG 4 (COBOL,
as of N4315) is to include a list in a normative Annex.</P></LI>

<LI><P>Specify width sensitivity as implied by C++03: <TT>\uFF21</TT>
is not the same as A.  Case sensitivity is already stated in
2.11 [lex.name].</P></LI>

</OL>

<P><B>Notes from the August, 2010 meeting:</B></P>

<P>CWG expressed interest in an approach by which all characters
except for those in specifically-excluded categories would be
acceptable identifier characters.  This suggestion will be
brought up with WG14 as a liaison matter in hopes of agreeing
on a uniform approach between C and C++.</P>

<BR><BR><HR><A NAME="1106"></A><H4>1106.
  
Need more detail in <TT>nullptr</TT> keyword description
</H4><B>Section: </B>2.14.7&#160; [lex.nullptr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>DE
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#DE3">N3092 comment
  DE&#160;3<BR></A>

<P>It is not sufficiently clear that <TT>std::nullptr_t</TT> is a
distinct type and neither a pointer type nor a pointer-to-member type.
Add a note in 2.14.7 [lex.nullptr] stating that, preferably
with cross-references to the normative statements in 3.9 [basic.types].
</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<P>Change 2.14.7 [lex.nullptr] paragraph 1 as follows:</P>

<BLOCKQUOTE>

The pointer literal is the keyword <TT>nullptr</TT>. It is a prvalue
of type <TT>std::nullptr_t</TT>. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I>
<TT>std::nullptr_t</TT> is a distinct type that is neither a pointer
type nor a pointer to member type; rather, a prvalue of this type is a
null pointer constant and can be converted to a null pointer value or
null member pointer value.  See 4.10 [conv.ptr] and
4.11 [conv.mem]. &#8212;<I>end note</I>]</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1107"></A><H4>1107.
  
Overload resolution for user-defined integer literals
</H4><B>Section: </B>2.14.8&#160; [lex.ext]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US17">N3092 comment
  US&#160;17<BR></A>

<P>In general, the parameter type of a literal operator must be
the same as the argument passed to it. That is not the
case for a <I>user-defined-character-literal</I>, where the
argument could inadvertently match a literal operator
intended for use with <I>user-defined-integer-literal</I>s:</P>

<PRE>
    typedef unsigned long long ULL;
    int operator "" X(ULL);
    int i = 'c'X; // operator"" X(ULL('c'))
</PRE>

<P><U>Suggested resolution</U>:
Add the following phrase to the description in
paragraph 6:</P>

<BLOCKQUOTE>

<I>S</I> shall contain a literal operator whose parameter
type is the same as the type of <I>ch</I>.

</BLOCKQUOTE>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change 2.14.8 [lex.ext] paragraph 6 as follows:</P>

<BLOCKQUOTE>

If <I>L</I> is a <I>user-defined-character-literal</I>, let <I>ch</I>
be the literal without its <I>ud-suffix</I>. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>S</I> shall contain a literal operator (13.5.8 [over.literal]) whose only parameter has the type of <I>ch</I> and
the</SPAN> literal <I>L</I> is treated as a call of the form

<PRE>
    operator "" X (<SPAN style="font-family:Times;font-style:italic">ch</SPAN><SPAN style="text-decoration:line-through;background-color:#FFA0A0"> </SPAN>)
</PRE>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1175"></A><H4>1175.
  
Disambiguating user-defined literals
</H4><B>Section: </B>2.14.8&#160; [lex.ext]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Sebastian Gesemann
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-10<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>A user-defined literal like <TT>0x123DZ</TT> could be
parsed either as a <I>hexadecimal-literal</I> of <TT>0x123</TT> and a
<I>ud-suffix</I> of <TT>DZ</TT> or as a <I>hexadecimal-literal</I> of
<TT>0x123D</TT> and a <I>ud-suffix</I> of <TT>Z</TT>.  There does not
appear to be a rule that disambiguates the two possible parses.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change 2.14.8 [lex.ext] paragraph 1 as follows:</P>

<BLOCKQUOTE>

If a token matches both <I>user-defined-literal</I> and another
literal kind, it is treated as the latter.  [<I>Example:</I>
<TT>123_km</TT>, <TT>1.2LL</TT>, <TT>"Hello"s</TT> are all
<I>user-defined-literal</I>s, but <TT>12LL</TT> is an
<I>integer-literal</I>.  &#8212;<I>end example</I>] <SPAN style="font-weight:bold;background-color:#A0FFA0">The syntactic
nonterminal preceding the <I>ud-suffix</I> in a
<I>user-defined-literal</I> is taken to be the longest sequence of
characters that could match that nonterminal. [<I>Example:</I> The
<I>ud-suffix</I> in <TT>1.0e0X</TT> is <TT>X</TT>, not <TT>e0X</TT>;
in <TT>0x1DZ</TT>, the <I>ud-suffix</I> is <TT>Z</TT>, not
<TT>DZ</TT>. &#8212;<I>end example</I>]</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1239"></A><H4>1239.
  
Hexadecimal floating-point literals vs user-defined literals
</H4><B>Section: </B>2.14.8&#160; [lex.ext]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Howard Hinnant
 &#160;&#160;&#160;

 <B>Date: </B>2011-01-28<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>2.11 [lex.name] paragraph 3 says,</P>

<BLOCKQUOTE>

In addition, some identifiers are reserved for use by C++
implementations and standard libraries (17.6.4.3.2 [global.names]) and shall not be used otherwise; no diagnostic is
required.

</BLOCKQUOTE>

<P>There is no corresponding mention in 2.14.8 [lex.ext]
of the restrictions on user-defined literal suffixes in
17.6.4.3.5 [usrlit.suffix].  Furthermore, considering the
likelihood of adding hexadecimal floating-point literals, whose
syntax overlaps that of user-defined literals except for that
restriction, it would be a good idea to require a diagnostic for
a violation of that rule.</P>

<BR><BR><HR><A NAME="676"></A><H4>676.
  
<I>static_assert-declaration</I>s and general requirements for declarations
</H4><B>Section: </B>3.1&#160; [basic.def]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>12 February, 2008<BR>


<P>[Voted into WP at August, 21010 meeting.]</P>

<P>3.1 [basic.def] makes statements about declarations that do
not appear to apply to <I>static_assert-declaration</I>s.  For example,
paragraph 1 says,</P>

<BLOCKQUOTE>

A declaration (clause 7 [dcl.dcl]) introduces names into a
translation unit or redeclares names introduced by previous
declarations.  A declaration specifies the interpretation and
attributes of these names.

</BLOCKQUOTE>

<P>What name is being declared or described by
a <I>static_assert-declaration</I>?</P>

<P>Also, paragraph 2 lists the kinds of declarations that are not
definitions, and a <I>static_assert-declaration</I> is not among them.
Is it intentional that <I>static_assert-declaration</I>s are
definitions?</P>

<P><B>Proposed resolution (March, 2010):</B></P>

<P>Change 3.1 [basic.def] paragraphs 1-2 as follows:</P>

<BLOCKQUOTE>

<P>A declaration (Clause 7 [dcl.dcl]) <SPAN style="font-weight:bold;background-color:#A0FFA0">may</SPAN>
introduce<SPAN style="text-decoration:line-through;background-color:#FFA0A0">s</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">one or more</SPAN> names into a
translation unit or redeclare<SPAN style="text-decoration:line-through;background-color:#FFA0A0">s</SPAN> names introduced by
previous declarations. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">A</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">If so, the</SPAN>
declaration specifies the interpretation and attributes of these
names.  <SPAN style="font-weight:bold;background-color:#A0FFA0">A declaration may also have effects
including</SPAN></P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">a static assertion (Clause 7 [dcl.dcl]),</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">controlling template instantiation (14.7.2 [temp.explicit],</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">use of attributes (Clause 7 [dcl.dcl], or</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">nothing (in the case of an
<I>empty-declaration</I>).</SPAN></P></LI>

</UL>

<P>A declaration is a definition unless it declares a function
without specifying the function's body (8.4 [dcl.fct.def]), it contains the <TT>extern</TT> specifier
(7.1.1 [dcl.stc]) or a
<I>linkage-specification</I><SUP>25</SUP> (7.5 [dcl.link]) and neither an <I>initializer</I> nor a
<I>function-body</I>, it declares a static data member in a class
definition (9.4 [class.static]), it is a class name
declaration (9.1 [class.name]), it is an
<I>opaque-enum-declaration</I> (7.2 [dcl.enum]), or it
is a <TT>typedef</TT> declaration (7.1.3 [dcl.typedef]), a
<I>using-declaration</I> (7.3.3 [namespace.udecl]), <SPAN style="font-weight:bold;background-color:#A0FFA0">a
<I>static_assert-declaration</I> (Clause 7 [dcl.dcl]),
an <I>attribute-declaration</I> (Clause 7 [dcl.dcl]),
an <I>empty-declaration</I> (Clause 7 [dcl.dcl]),</SPAN> or a <I>using-directive</I> (7.3.4 [namespace.udir]). [<I>Example:</I>...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="758"></A><H4>758.
  
Missing cases of declarations that are not definitions
</H4><B>Section: </B>3.1&#160; [basic.def]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Bjarne Stroustrup
 &#160;&#160;&#160;

 <B>Date: </B>22 January, 2009<BR><BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK23">N2800 comment
  UK&#160;23<BR></A>
<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK24">N2800 comment
  UK&#160;24<BR></A>



<P>The list of declarations that are not definitions given in
3.1 [basic.def] paragraph 2 does not mention several plausible
candidates: parameter declarations in non-defining function declarations,
non-static data members, and template parameters.  It might be argued
that none of these are <I>declaration</I>s (paragraph 1 does not use the
syntactic non-terminal <I>declaration</I> but does explicitly refer to
clause 7 [dcl.dcl], where that non-terminal is defined).
However, the list in paragraph 2 does mention static member declarations,
which also are not <I>declaration</I>s, so the intent is not clear.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change 3.1 [basic.def] paragraph 2 as follows:</P>

<BLOCKQUOTE>

A declaration is a <I>definition</I> unless it declares a function
without specifying the function's body (8.4 [dcl.fct.def]), it
contains the <TT>extern</TT> specifier (7.1.1 [dcl.stc]) or
a <I>linkage-specification</I><SUP>25</SUP> (7.5 [dcl.link])
and neither an <I>initializer</I> nor a <I>function-body</I>, it
declares a static data member in a class definition (<SPAN style="font-weight:bold;background-color:#A0FFA0">9.2 [class.mem],</SPAN> 9.4 [class.static]), it is a class name
declaration (9.1 [class.name]), it is an
<I>opaque-enum-declaration</I> (7.2 [dcl.enum]), <SPAN style="font-weight:bold;background-color:#A0FFA0">it
is a <I>template-parameter</I> (14.1 [temp.param]), it is a
<I>parameter-declaration</I> (8.3.5 [dcl.fct]) in a
function declaration that is not a definition,</SPAN> or it is a
<TT>typedef</TT> declaration (7.1.3 [dcl.typedef]), <SPAN style="font-weight:bold;background-color:#A0FFA0">an
<I>alias-declaration (7.1.3 [dcl.typedef]),</I></SPAN> a
<I>using-declaration</I> (7.3.3 [namespace.udecl]), a
<I>static_assert-declaration</I> (Clause 7 [dcl.dcl]), an
<I>attribute-declaration</I> (Clause 7 [dcl.dcl]), an
<I>empty-declaration</I> (Clause 7 [dcl.dcl]), or a
<I>using-directive</I> (7.3.4 [namespace.udir]).

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1201"></A><H4>1201.
  
Are deleted and defaulted functions definitions?
</H4><B>Section: </B>3.1&#160; [basic.def]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2010-09-20<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>



<P>According to 3.2 [basic.def.odr] paragraph 2,</P>

<BLOCKQUOTE>

A declaration is a <I>definition</I> unless it declares a function
without specifying the function's body (8.4 [dcl.fct.def]), it
contains the <TT>extern</TT> specifier (7.1.1 [dcl.stc]) or a
<I>linkage-specification</I><SUP>25</SUP> (7.5 [dcl.link])
and neither an <I>initializer</I> nor a <I>function-body</I>...

</BLOCKQUOTE>

<P>Because <TT>= delete</TT> and <TT>= default</TT> are not forms
of <I>function-body</I>, this description does not cover defaulted
and deleted functions, even though these declarations are elsewhere
referred to as being definitions.</P>

<P><B>Proposed resolution (January, 2011):</B></P>

<P>Change the grammar in 8.4.1 [dcl.fct.def.general] paragraph 1
as follows:</P>

<UL><I>function-definition:</I>
<UL><I>attribute-specifier-seq<SUB>opt</SUB> decl-specifier-seq<SU>opt</SU> declarator function-body</I></UL>
<UL><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>attribute-specifier-seq<SUB>opt</SUB> decl-specifier-seq<SU>opt</SU> declarator </I><TT>= default ;</TT></SPAN></UL>
<UL><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>attribute-specifier-seq<SUB>opt</SUB> decl-specifier-seq<SU>opt</SU> declarator </I><TT>= delete ;</TT></SPAN></UL>

</UL>

<UL><I>function-body:</I>
<UL><I>ctor-initializer<SUB>opt</SUB> compound-statement</I></UL>
<UL><I>function-try-block</I></UL>
<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>= default ;</TT></SPAN></UL>
<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>= delete ;</TT></SPAN></UL>

</UL>

<BR><BR><HR><A NAME="678"></A><H4>678.
  
Language linkage of member function parameter types and the ODR
</H4><B>Section: </B>3.2&#160; [basic.def.odr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>James Widman
 &#160;&#160;&#160;

 <B>Date: </B>15 February, 2008<BR>


<P>[Voted into WP at August, 21010 meeting.]</P>



<P>I thought this case would result in undefined behavior according to
3.2 [basic.def.odr]:</P>

<PRE>
    // t.h:
    struct A { void (*p)(); };

    // t1.cpp:
    #include "t.h" // A::p<SPAN style="font-family:Times;font-style:italic"> is a pointer to C++ func</SPAN>

    // t2.cpp:
    extern "C" {
    #include "t.h" // A::p<SPAN style="font-family:Times;font-style:italic"> is a pointer to C func</SPAN>
    }
</PRE>

<P>...but I don't see how any of the bullets in the list in paragraph
5 apply.</P>

<P><B>Proposed resolution (March, 2010):</B></P>

<P>Add a new bullet following 3.2 [basic.def.odr] paragraph 5,
second bullet:</P>

<BLOCKQUOTE>

<P>...Given such an entity named <TT>D</TT> defined in more than one
translation unit, then</P>

<UL><LI><P>each definition of <TT>D</TT> shall consist of the
same sequence of tokens; and</P></LI>

<LI><P>in each definition of <TT>D</TT>, corresponding names,
looked up according to 3.4 [basic.lookup], shall refer to
an entity defined within the definition of <TT>D</TT>, or shall
refer to the same entity, after overload resolution (13.3 [over.match]) and after matching of partial template
specialization (14.8.3 [temp.over]), except that a name
can refer to a const object with internal or no linkage if the
object has the same literal type in all definitions of
<TT>D</TT>, and the object is initialized with a constant
expression (5.19 [expr.const]), and the value (but not
the address) of the object is used, and the object has the same
value in all definitions of <TT>D</TT>; and</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">in each definition of <TT>D</TT>, corresponding
entities shall have the same language linkage; and</SPAN></P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1109"></A><H4>1109.
  
When is &#8220;use&#8221; a reference to the ODR meaning?
</H4><B>Section: </B>3.2&#160; [basic.def.odr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting as paper N3214.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US19">N3092 comment
  US&#160;19<BR></A>

<P>It is not always clear when an occurrence of the word &#8220;use&#8221;
is intended as an implicit reference to 3.2 [basic.def.odr] and
when it is simply the ordinary English meaning.  This could be addressed
by:</P>

<OL><LI><P>Replacing all the non-technical appearances of the word
&#8220;use&#8221; with synonyms such as &#8220;occurrence&#8221; or
&#8220;appearance&#8221; or &#8220;reference to.&#8221;</P></LI>

<LI><P>Following each occurrence of the word &#8220;use&#8221; that
is intended in the technical sense with a cross-reference to
3.2 [basic.def.odr].</P></LI>

<LI><P>Replacing all the technical occurrences of the word
&#8220;use&#8221; with a different word or phrase, such as
&#8220;odr-use,&#8221; that would unambiguously indicate the
intent.</P></LI>

</OL>

<BR><BR><HR><A NAME="1174"></A><H4>1174.
  
When is a pure virtual function &#8220;used?&#8221;
</H4><B>Section: </B>3.2&#160; [basic.def.odr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-07<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>According to 3.2 [basic.def.odr] paragraph 2,</P>

<BLOCKQUOTE>

A variable or non-overloaded function whose name appears as a
potentially-evaluated expression is <I>used</I>... A virtual member
function is used if it is not pure.

</BLOCKQUOTE>

<P>However, that does not adequately address when a pure virtual
function is used or not used.  For example,</P>

<PRE>
    struct S {
      virtual void pure1() = 0;
      virtual void pure2() = 0;
    };
    void f(S* p) {
      p-&gt;pure1();
      p-&gt;S::pure2();
    };
</PRE>

<P>Both <TT>pure1</TT> and <TT>pure2</TT> satisfy the criterion that
their name appears in a potentially-evaluated expression, but
<TT>pure1</TT> should not be considered &#8220;used&#8221; (which
would require that it be defined); <TT>pure2</TT> <I>is</I>
&#8220;used&#8221; and must be defined.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change 3.2 [basic.def.odr] paragraph 2 as follows:</P>

<BLOCKQUOTE>

...A variable <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or non-overloaded function</SPAN> whose name appears
as a potentially-evaluated expression is odr-used unless it is an
object that satisfies the requirements for appearing in a constant
expression (5.19 [expr.const]) and the lvalue-to-rvalue
conversion (4.1 [conv.lval]) is immediately applied...  A
virtual member function is odr-used if it is not pure.  A
<SPAN style="font-weight:bold;background-color:#A0FFA0">non-overloaded function whose name appears as a
potentially-evaluated expression or a</SPAN> member of a set of
candidate functions <SPAN style="text-decoration:line-through;background-color:#FFA0A0">is odr-used</SPAN> if <SPAN style="text-decoration:line-through;background-color:#FFA0A0">it is</SPAN>
selected by overload resolution when referred to from a
potentially-evaluated expression<SPAN style="font-weight:bold;background-color:#A0FFA0">, are odr-used, unless the
function is pure and its name is not explicitly
qualified</SPAN>. [<I>Note:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1192"></A><H4>1192.
  
Inadvertent change to ODR and templates
</H4><B>Section: </B>3.2&#160; [basic.def.odr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2010-09-03<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P><A HREF="
     cwg_defects.html#678">Issue 678</A> added a bullet to the list
in 3.2 [basic.def.odr] paragraph 5, inadvertently removing the
second bullet from the reach of the part of that paragraph that
reads,</P>

<BLOCKQUOTE>

If <TT>D</TT> is a template and is defined in more than one translation unit,
then the last four requirements from the list above shall apply to
names from the template's enclosing scope used in the template
definition (14.6.3 [temp.nondep]),

</BLOCKQUOTE>

<P>In fixing this error, the wording should be recast to be more
robust in the face of possible further edits to the list (i.e., not
just changing &#8220;four&#8221; to &#8220;five&#8221;).</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change 3.2 [basic.def.odr] paragraph 5 as follows:</P>

<BLOCKQUOTE>

...If <TT>D</TT> is a template and is defined in more than one
translation unit, then the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">last four</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">preceding</SPAN>
requirements <SPAN style="text-decoration:line-through;background-color:#FFA0A0">from the list above</SPAN> shall apply
<SPAN style="font-weight:bold;background-color:#A0FFA0">both</SPAN> to names from the template's enclosing scope used in
the template definition (14.6.3 [temp.nondep]), and also to
dependent names at the point of instantiation (14.6.2 [temp.dep])...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1044"></A><H4>1044.
  
Point of declaration for an <I>alias-declaration</I>
</H4><B>Section: </B>3.3.2&#160; [basic.scope.pdecl]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>2010-03-05<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

<P>The current wording of 3.3.2 [basic.scope.pdecl] does not specify
the point of declaration for an <I>alias-declaration</I> (although it
does do so in paragraph 3 for a template alias: &#8220;The point of
declaration of a template alias immediately follows the identifier
for the alias being declared&#8221;).  One might assume that an
<I>alias-declaration</I> would be the same, but it's not clear that
that is the right resolution (for either declaration, but especially
for the <I>alias-declaration</I>).</P>

<P>An <I>alias-declaration</I> is intended to be essentially a
different syntactic form of a <TT>typedef</TT> declaration
(7.1.3 [dcl.typedef] paragraph 2).  Placing the point of
declaration at the trailing semicolon instead of following the name
of the alias would allow more compatibility with the capabilities of
<TT>typedef</TT>s, for instance:</P>

<PRE>
    struct S { };
    namespace N {
        using S = S;
    }
</PRE>



<P><B>Notes from the November, 2010 meeting:</B></P>

<P>The CWG agreed that the point of declaration for both template
and non-template cases should be at the semicolon.</P>

<P><B>Proposed resolution (January, 2011):</B></P>

<P>Change 3.3.2 [basic.scope.pdecl] paragraph 3 as follows:</P>

<BLOCKQUOTE>

...The point of declaration of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a template</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an</SPAN>
alias <SPAN style="font-weight:bold;background-color:#A0FFA0">or alias template</SPAN> immediately follows <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the
identifier for the alias being declared</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">the <I>type-id</I>
to which the alias refers</SPAN>.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1210"></A><H4>1210.
  
Injection of <I>elaborated-type-specifier</I> in enumeration scope
</H4><B>Section: </B>3.3.2&#160; [basic.scope.pdecl]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Johannes Schaub
 &#160;&#160;&#160;

 <B>Date: </B>2010-10-13<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>According to 3.3.2 [basic.scope.pdecl] paragraph 6,</P>

<BLOCKQUOTE>

<P>for an elaborated-type-specifier of the form</P>

<UL><I>class-key identifier</I></UL>

<P>if the <I>elaborated-type-specifier</I> is used in the
<I>decl-specifier-seq</I> or <I>parameter-declaration-clause</I> of a
function defined in namespace scope, the <I>identifier</I> is declared
as a <I>class-name</I> in the namespace that contains the declaration;
otherwise, except as a friend declaration, the <I>identifier</I> is
declared in the smallest non-class, non-function-prototype scope that
contains the declaration.</P>

</BLOCKQUOTE>

<P>This should have been, but was not, updated when enumeration
scope (3.3.8 [basic.scope.enum]) was added:</P>

<PRE>
    enum class E {
        e = sizeof((struct S*)0)
    };
</PRE>

<P>Presumably the name <TT>S</TT> belongs to the same scope as
<TT>E</TT>, not the enumeration scope of <TT>E</TT>.</P>

<BR><BR><HR><A NAME="997"></A><H4>997.
  
Argument-dependent lookup and dependent function template parameter types
</H4><B>Section: </B>3.4.2&#160; [basic.lookup.argdep]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>James Widman
 &#160;&#160;&#160;

 <B>Date: </B>6 November, 2009<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>3.4.2 [basic.lookup.argdep] paragraph 2 excludes dependent parameter
types and return types from consideration in determining the associated
classes and namespaces of a function template.  Presumably this means
that an example like</P>

<PRE>
    namespace N {
      template&lt;class T&gt; struct A { };
      void f(void (*)());
    }

    template &lt;class T&gt;
    void g(T, N::A&lt;T&gt;);

    void g();

    int main() {
      f(g);
    }
</PRE>

<P>is ill-formed because the second parameter of the function template
<TT>g</TT> does not add namespace <TT>N</TT> to the list of associated
namespaces.  This was probably unintentional.</P>

<P>See also <A HREF="
     cwg_defects.html#1015">issue 1015</A>.</P>

<P><B>Notes from the November, 2010 meeting:</B></P>

<P>The CWG agreed that the rules should be changed to make this
example well-formed.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change 3.4.2 [basic.lookup.argdep] paragraph 2 as follows:</P>

<BLOCKQUOTE>

...In addition, if the argument is the name or address of a set of
overloaded functions and/or function templates, its associated classes
and namespaces are the union of those associated with each of the
members of the set, i.e., the classes and namespaces associated with
its <SPAN style="text-decoration:line-through;background-color:#FFA0A0">(non-dependent)</SPAN> parameter types and return type.
<SPAN style="font-weight:bold;background-color:#A0FFA0">Additionally, if the aforementioned set of overloaded functions
is named with a <I>template-id</I>, its associated classes
and namespaces are those of its type
<I>template-argument</I>s and its template
<I>template-argument</I>s.</SPAN>

</BLOCKQUOTE>

<P>This resolution also resolves <A HREF="
     cwg_defects.html#1015">issue 1015</A>.</P>

<P><I>[Drafting note: It's not clear that we need the inserted text
above, because for the example in <A HREF="
     cwg_defects.html#1015">issue 1015</A>, the type <TT>N::S</TT> is already represented in the
type of the function address, so there is no need to pull it from
template arguments. For cases where template parameters are not
represented in the function type, it's not clear that we want ADL to
reach further.]</I></P>

<BR><BR><HR><A NAME="1015"></A><H4>1015.
  
Template arguments and argument-dependent lookup
</H4><B>Section: </B>3.4.2&#160; [basic.lookup.argdep]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2009-12-24<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>Currently, according to 3.4.2 [basic.lookup.argdep] paragraph 2,
explicit template arguments in a function argument do not contribute
to the associated namespaces in a function call, although they plausibly
should in an example like the following:</P>

<PRE>
    namespace N {
        struct S { };
        void f(void (*)(S));
    };

    template&lt;typename T&gt; void g(T);

    void h() {
        f(g&lt;N::S&gt;);    //<SPAN style="font-family:Times;font-style:italic"> Should find </SPAN>N::f
    }
</PRE>

<P>See also <A HREF="
     cwg_defects.html#997">issue 997</A>.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#997">issue 997</A>.</P>

<BR><BR><HR><A NAME="1111"></A><H4>1111.
  
Remove dual-scope lookup of member template names
</H4><B>Section: </B>3.4.5&#160; [basic.lookup.classref]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US23">N3092 comment
  US&#160;23<BR></A>

<P>According to 3.4.5 [basic.lookup.classref] paragraph 1,</P>

<BLOCKQUOTE>

<P>In a class member access expression (5.2.5 [expr.ref]), if the <TT>.</TT> or <TT>-&gt;</TT> token is
immediately followed by an identifier followed by a
<TT>&lt;</TT>, the identifier must be looked up to determine
whether the <TT>&lt;</TT> is the beginning of a template
argument list (14.2 [temp.names]) or a less-than
operator.  The identifier is first looked up in the class of
the object expression.  If the identifier is not found, it
is then looked up in the context of the entire
<I>postfix-expression</I> and shall name a class template.
If the lookup in the class of the object expression finds a
template, the name is also looked up in the context of the
entire <I>postfix-expression</I> and</P>

<UL><LI><P>if the name is not found, the name found in the
class of the object expression is used, otherwise</P></LI>

<LI><P>if the name is found in the context of the entire
<I>postfix-expression</I> and does not name a class
template, the name found in the class of the object
expression is used, otherwise</P></LI>

<LI><P>if the name found is a class template, it shall refer to
the same entity as the one found in the class of the object
expression, otherwise the program is ill-formed.</P></LI></UL>

</BLOCKQUOTE>

<P>This makes the following ill-formed:</P>

<PRE>
    #include &lt;set&gt;
    using std::set;
    struct X {
      template &lt;typename T&gt; void set(const T&amp; value);
    };
    void foo() {
      X x;
      x.set&lt;double&gt;(3.2);
    }
</PRE>

<P>That's confusing and unnecessary.  The compiler has already done
the lookup in <TT>X</TT>'s scope, and the obviously-correct
resolution is that one, not the identifier from the
<I>postfix-expression</I>'s scope.  <A HREF="
     cwg_defects.html#305">Issue 305</A>
fixed a similar issue for destructor names but missed member functions.</P>

<P><U>Suggested resolution</U>: Delete the end of paragraph 1, starting
with &#8220;If the lookup in the class...&#8221; and including all
three bullets.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<OL><LI><P>Change 3.4.3.1 [class.qual] paragraph 1 bullet 2 as
follows:</P></LI>

<UL><LI><P>a <I>conversion-type-id</I> of a<SPAN style="text-decoration:line-through;background-color:#FFA0A0">n</SPAN>
<I>conversion-function-id</I> is looked up <SPAN style="text-decoration:line-through;background-color:#FFA0A0">both in the scope of
the class and in the context in which the entire
<I>postfix-expression</I> occurs and shall refer to the same type in
both contexts</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">in the same manner as a
<I>conversion-type-id</I> in a class member access (see 3.4.5 [basic.lookup.classref])</SPAN>;</P></LI></UL>

<LI><P>Change 3.4.5 [basic.lookup.classref] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<P>In a class member access expression (5.2.5 [expr.ref]),
if the <TT>.</TT> or <TT>-&gt;</TT> token is immediately followed by
an <I>identifier</I> followed by a <TT>&lt;</TT>, the identifier must
be looked up to determine whether the <TT>&lt;</TT> is the beginning
of a template argument list (14.2 [temp.names]) or a less-than
operator.  The identifier is first looked up in the class of the
object expression.  If the identifier is not found, it is then looked
up in the context of the entire <I>postfix-expression</I> and shall
name a class template.  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">If the lookup in the class of the object
expression finds a template, the name is also looked up in the context
of the entire <I>postfix-expression</I> and</SPAN></P>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">if the name is not found, the name found in the class
of the object expression is used, otherwise</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">if the name is found in the context of the entire
<I>postfix-expression</I> and does not name a class template, the name
found in the class of the object expression is used,
otherwise</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">if the name found is a class template, it shall refer to
the same entity as the one found in the class of the object
expression, otherwise the program is ill-formed.</SPAN></P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 3.4.5 [basic.lookup.classref] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

<P>If the <I>id-expression</I> in a class member access is a
<I>qualified-id</I> of the form</P>

<PRE>
    class-name-or-namespace-name::...
</PRE>

<P>the <I>class-name-or-namespace-name</I> following the <TT>.</TT> or
<TT>-&gt;</TT> operator is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">looked up both in the context of the entire
<I>postfix-expression</I> and in the scope of the class of the object
expression. If the name is found only in the scope of the class of the
object expression, the name shall refer to a <I>class-name</I>.  If
the name is found only in the context of the entire
<I>postfix-expression</I>, the name shall refer to a <I>class-name</I>
or <I>namespace-name</I>.  If the name is found in both contexts, the
<I>class-name-or-namespace-name</I> shall refer to the same
entity.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">first looked up in the class of the object
expression and the name, if found, is used. Otherwise it is looked up
in the context of the entire <I>postfix-expression</I>. [<I>Note:</I>
See 3.4.3 [basic.lookup.qual], which describes the lookup of a name
before <TT>::</TT>, which will only find a type or namespace
name. &#8212;<I>end note</I>]</SPAN></P>

</BLOCKQUOTE>

<LI><P>Change 3.4.5 [basic.lookup.classref] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

<P>If the <I>id-expression</I> is a <I>conversion-function-id</I>, its
<I>conversion-type-id</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">shall denote the same type in both the
context in which the entire <I>postfix-expression</I> occurs and in
the context of the class of the object expression (or the class
pointed to by the pointer expression).</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">is first looked up in
the class of the object expression and the name, if found and denotes
a type, is used. Otherwise it is looked up in the context of the
entire <I>postfix-expression</I> and the name shall denote a type.
[<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  struct A { };
  namespace N {
    struct A {
      void g() { }
      template &lt;class T&gt; operator T();
    };
  }

  int main() {
    N::A a;
    a.operator A();    //<SPAN style="font-family:Times;font-style:italic"> calls </SPAN>N::A::operator N::A
  }</SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1220"></A><H4>1220.
  
Looking up <I>conversion-type-id</I>s
</H4><B>Section: </B>3.4.5&#160; [basic.lookup.classref]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>2010-11-13<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>The resolution of <A HREF="
     cwg_defects.html#1111">issue 1111</A> changes
3.4.5 [basic.lookup.classref] paragraph 7 to read,</P>

<BLOCKQUOTE>

[A] <I>conversion-type-id</I> is first looked up in the class of
the object expression and the name, if found and denotes a type,
is used.  Otherwise it is looked up in the context of the entire
<I>postfix-expression</I> and the name shall denote a type.

</BLOCKQUOTE>

<P>The result of this specification is that a non-type member
declaration in the class scope of the object expression will not
be found (although it will hide a base class type member of the
same name), but a non-type declaration in the context of the
expression will be found (and make the program ill-formed).</P>

<P>This is inconsistent with the way other lookups are handled
when they occur in a context that requires a type.  For example,
the lookup for a <I>nested-name-specifier</I> &#8220;considers
only namespaces, types, and templates whose specializations are
types&#8221; (3.4.3 [basic.lookup.qual] paragraph 1); the lookup
for a name appearing in an <I>elaborated-type-specifier</I> is
done &#8220;ignoring any non-type names that have been declared&#8221;
(3.4.4 [basic.lookup.elab] paragraph 2); and in the lookup for a name
in a <I>base-type-specifier</I>, &#8220;non-type names are
ignored&#8221; (10 [class.derived] paragraph 2). The lookup
for a <I>conversion-type-id</I> should be similar, and the wording
in 3.4.5 [basic.lookup.classref] paragraph 7 adjusted accordingly.</P>

<BR><BR><HR><A NAME="373"></A><H4>373.
  
Lookup on namespace qualified name in using-directive
</H4><B>Section: </B>3.4.6&#160; [basic.lookup.udir]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Clark Nelson
 &#160;&#160;&#160;

 <B>Date: </B>15 August 2002<BR>


<P>[Voted into WP at August, 2010 meeting.]</P>

<P>Is this case valid?  G++ compiles it.</P>
<PRE>
namespace X {
  namespace Y {
    struct X {
      void f()
      {
        using namespace X::Y;
        namespace Z = X::Y;
      }
    };
  }
}
</PRE>
<P>The relevant citation from the standard is
3.4.6 [basic.lookup.udir]: "When looking up a
namespace-name in a using-directive or namespace-alias-definition, only
namespace names are considered." This statement could reasonably be
interpreted to apply only to the last element of a qualified name, and
that's the way EDG and Microsoft seem to interpret it.</P>

<P>However, since a class can't contain a namespace, it seems to me that this
interpretation is, shall we say, sub optimal. If the X qualifiers in the
above example are interpreted as referring to the struct X, an error of some
sort is inevitable, since there can be no namespace for the qualified name
to refer to. G++ apparently interprets 3.4.6 [basic.lookup.udir]
as applying to
nested-name-specifiers in those contexts as well, which makes a valid
interpretation of the test possible.</P>

<P>I'm thinking it might be worth
tweaking the words in 3.4.6 [basic.lookup.udir]
to basically mandate the more useful
interpretation. Of course a person could argue that the difference would
matter only to a perverse program. On the other hand, namespaces were
invented specifically to enable the building of programs that would
otherwise be considered perverse. Where name clashes are concerned, one
man's perverse is another man's real world.</P>

<P><B>Proposed Resolution (November, 2006):</B></P>

<P>Change 3.4.6 [basic.lookup.udir] paragraph 1 as follows:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">When looking up a <I>namespace-name</I> in a <I>using-directive</I> or
<I>namespace-alias-definition</I>,</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">In a <I>using-directive</I>
or <I>namespace-alias-definition</I>, during the lookup for a
<I>namespace-name</I> or for a name in a <I>nested-name-specifier</I>,</SPAN>
only namespace names are considered.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1112"></A><H4>1112.
  
<TT>constexpr</TT> variables should have internal linkage like <TT>const</TT>
</H4><B>Section: </B>3.5&#160; [basic.link]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US24">N3092 comment
  US&#160;24<BR></A>

<P>One of the critieria for giving a name internal linkage is &#8220;a
variable that is explicitly declared <TT>const</TT> and neither
explicitly declared <TT>extern</TT> nor previously declared to have
external linkage.&#8221; This should presumably apply to
variables declared <TT>constexpr</TT> as well.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change 3.5 [basic.link] paragraph 3 bullet 2 as follows:</P>

<UL><LI><P>a variable that is explicitly declared <TT>const</TT>
<SPAN style="font-weight:bold;background-color:#A0FFA0">or <TT>constexpr</TT></SPAN> and neither explicitly declared
<TT>extern</TT> nor previously declared to have external linkage;
or</P></LI></UL>

<BR><BR><HR><A NAME="1113"></A><H4>1113.
  
Linkage of namespace member of unnamed namespace
</H4><B>Section: </B>3.5&#160; [basic.link]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>DE
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#DE4">N3092 comment
  DE&#160;4<BR></A>

<P>It is odd that, in the following example, <TT>N</TT> has no
linkage but <TT>g</TT> has external linkage:</P>

<PRE>
    namespace {
      namespace N // has no linkage
      {
        void g(); // has external linkage
      }
    }
</PRE>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change 3.5 [basic.link] paragraph 4 as follows:</P>

<BLOCKQUOTE>

<SPAN style="font-weight:bold;background-color:#A0FFA0">An unnamed namespace or a namespace declared directly
or indirectly within an unnamed namespace has internal
linkage. All other namespaces have external linkage.</SPAN> A
name having namespace scope <SPAN style="font-weight:bold;background-color:#A0FFA0">that has not been given
internal linkage above</SPAN> has <SPAN style="text-decoration:line-through;background-color:#FFA0A0">external linkage</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">the same linkage as the enclosing namespace</SPAN> if it
is the name of

<UL><LI><P>a variable<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, unless it has internal
linkage</SPAN>; or</P></LI>

<LI><P>a function<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, unless it has internal
linkage</SPAN>; or</P></LI>

<LI><P>a named class (Clause 9 [class]), or an
unnamed class defined in a typedef declaration in which the
class has the typedef name for linkage purposes
(7.1.3 [dcl.typedef]); or</P></LI>

<LI><P>a named enumeration (7.2 [dcl.enum]), or an
unnamed enumeration defined in a typedef declaration in
which the enumeration has the typedef name for linkage
purposes (7.1.3 [dcl.typedef]); or</P></LI>

<LI><P>an enumerator belonging to an enumeration with
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">external</SPAN> linkage; or</P></LI>

<LI><P>a template<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, unless it is a function template
that has internal linkage (Clause 14 [temp]);
or</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">.</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">a namespace (7.3 [basic.namespace]), unless it is
declared within an unnamed namespace.</SPAN></P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1187"></A><H4>1187.
  
Problems in initialization example
</H4><B>Section: </B>3.6.2&#160; [basic.start.init]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-31<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>



<P>The note in 3.6.2 [basic.start.init] paragraph 3 contains the
following example:</P>

<PRE>
  inline double fd() { return 1.0; }
  extern double d1;
  double d2 = d1;     //<SPAN style="font-family:Times;font-style:italic"> unspecified:</SPAN>
                      //<SPAN style="font-family:Times;font-style:italic"> may be statically initialized to </SPAN>0.0<SPAN style="font-family:Times;font-style:italic"> or</SPAN>
                      //<SPAN style="font-family:Times;font-style:italic"> dynamically initialized to </SPAN>1.0
  double d1 = fd();   //<SPAN style="font-family:Times;font-style:italic"> may be initialized statically to </SPAN>1.0
</PRE>

<P>The comment for <TT>d2</TT> overlooks the third possibility: if
both <TT>d1</TT> and <TT>d2</TT> are dynamically initialized, <TT>d2</TT>
will be initialized to <TT>0</TT>.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change the comments in the example in 3.6.2 [basic.start.init]
paragraph 3 as follows:</P>

<PRE>
  inline double fd() { return 1.0; }
  extern double d1;
  double d2 = d1;     //<SPAN style="font-family:Times;font-style:italic"> unspecified:</SPAN>
                      //<SPAN style="font-family:Times;font-style:italic"> may be statically initialized to </SPAN>0.0<SPAN style="font-family:Times;font-style:italic"> or</SPAN>
                      //<SPAN style="font-family:Times;font-style:italic"> dynamically initialized <SPAN style="text-decoration:line-through;background-color:#FFA0A0">to </SPAN></SPAN><SPAN style="text-decoration:line-through;background-color:#FFA0A0">1.0</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><SPAN style="font-family:Times;font-style:italic">to </SPAN>0.0<SPAN style="font-family:Times;font-style:italic"> if </SPAN>d1<SPAN style="font-family:Times;font-style:italic"> is dynamically initialized, or </SPAN>1.0<SPAN style="font-family:Times;font-style:italic"> otherwise</SPAN></SPAN>
  double d1 = fd();   //<SPAN style="font-family:Times;font-style:italic"> may be initialized statically <SPAN style="font-weight:bold;background-color:#A0FFA0">or dynamically</SPAN> to </SPAN>1.0
</PRE>

<P>(The note should also be in running text following the bulleted list
instead of appearing as a bulleted item, as well.)</P>

<BR><BR><HR><A NAME="1190"></A><H4>1190.
  
Operations on non-safely-derived pointers
</H4><B>Section: </B>3.7.4.3&#160; [basic.stc.dynamic.safety]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Hans Boehm
 &#160;&#160;&#160;

 <B>Date: </B>2010-09-01<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>3.7.4.3 [basic.stc.dynamic.safety] paragraph 4 only prohibits the
dereferencing and deallocation of non-safely-derived pointers. This is
insufficient.  Explicit deallocation of storage is described as
rendering invalid all pointers to that storage, with the result that
<I>all</I> operations on such a pointer value causes undefined
behavior (3.7.4.2 [basic.stc.dynamic.deallocation] paragraph 4).  The same should
be true if the storage pointed to by a non-safely-derived pointer is
garbage collected.  In particular, the promise of objects having
distinct addresses (1.8 [intro.object] paragraph 6) should not
apply if one of those objects is designated by a non-safely-derived
pointer.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change 3.7.4.3 [basic.stc.dynamic.safety] paragraph 4 as follows:</P>

<BLOCKQUOTE>

...Alternatively, an implementation may have <I>strict pointer
safety</I>, in which case, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">if</SPAN> a pointer value that is not a
safely-derived pointer value is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">dereferenced or deallocated,
and</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an invalid pointer value, unless</SPAN> the referenced
complete object is of dynamic storage duration and has <SPAN style="text-decoration:line-through;background-color:#FFA0A0">not</SPAN>
previously been declared reachable (20.9.2 [util.smartptr])<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, the behavior is undefined</SPAN>. [<I>Note:</I>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">this</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">The effect of using an invalid pointer value
(including passing it to a deallocation function) is undefined, see
3.7.4.2 [basic.stc.dynamic.deallocation]. This</SPAN> is true even if the
unsafely-derived pointer value might compare equal to some
safely-derived pointer value. &#8212;<I>end note</I>] It is
implementation defined...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1114"></A><H4>1114.
  
Incorrect use of placement <TT>new</TT> in example
</H4><B>Section: </B>3.8&#160; [basic.life]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>GB
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#GB18">N3092 comment
  GB&#160;18<BR></A>

<P>The example in 3.8 [basic.life] paragraph 9 reads,</P>

<PRE>
    struct B {
      B();
      ~B();
    };

    const B b;

    void h() {
      b.~B();
      new (&amp;b) const B;  //<SPAN style="font-family:Times;font-style:italic"> undefined behavior</SPAN>
    }
</PRE>

<P>Assuming that the placement <TT>new</TT> is intended to use
the operator defined in the Standard library, the <I>new-expression</I>
is ill-formed, because there is no implicit conversion from
&#8220;pointer to const <TT>B</TT>&#8221; to <TT>void*</TT>.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change the example in 3.8 [basic.life] paragraph 9 as
follows:</P>

<PRE>
    ...
    new (<SPAN style="font-weight:bold;background-color:#A0FFA0">const_cast&lt;B *&gt;(</SPAN>&amp;b<SPAN style="font-weight:bold;background-color:#A0FFA0">)</SPAN>) const B;  //<SPAN style="font-family:Times;font-style:italic"> undefined behavior</SPAN>
    ...
</PRE>

<BR><BR><HR><A NAME="619"></A><H4>619.
  
Completeness of array types
</H4><B>Section: </B>3.9&#160; [basic.types]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Clamage
 &#160;&#160;&#160;

 <B>Date: </B>16 February 2007<BR>


<P>[Voted into WP at August, 21010 meeting.]</P>



<P>Is the following example well-formed?</P>

<PRE>
    struct S {
        static char a[5];
    };
    char S::a[];    // Unspecified bound in definition
</PRE>

<P>3.5 [basic.link] paragraph 10 certainly makes allowance
for declarations to differ in the presence or absence of a major array
bound.  However, 3.1 [basic.def] paragraph 5 says that</P>

<BLOCKQUOTE>

A program is ill-formed if the definition of any object gives the
object an incomplete type (3.9 [basic.types]).

</BLOCKQUOTE>

<P>3.9 [basic.types] paragraph 7 says,</P>

<BLOCKQUOTE>

The declared type of an array object might be an array of unknown size
and therefore be incomplete at one point in a translation unit and
complete later on; the array types at those two points (&#8220;array
of unknown bound of <TT>T</TT>&#8221; and &#8220;array of
N <TT>T</TT>&#8221;) are different types.

</BLOCKQUOTE>

<P>This wording appears to make no allowance for the C concept of
&#8220;composite type;&#8221; instead, each declaration is said
to have its own type.  By this interpretation, the example is
ill-formed, because the type declared by the definition of
<TT>S::a</TT> is incomplete.</P>

<P>If the example is intended to be well-formed, the Standard
needs explicit wording stating that an omitted array bound in a
declaration is implicitly taken from that of a visible
declaration of that object, if any.</P>

<P><B>Notes from the April, 2007 meeting:</B></P>

<P>The CWG agreed that this usage should be permitted.</P>

<P><B>Proposed resolution (June, 2008):</B></P>

<OL><LI><P>Change 8.3.4 [dcl.array] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">If</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Except as noted below, if</SPAN> the constant expression
is omitted, the type of the identifier of <TT>D</TT> is
&#8220;<I>derived-declarator-type-list</I> array of unknown bound of
<TT>T</TT>,&#8221; an incomplete object type...

</BLOCKQUOTE>

<LI><P>Change 8.3.4 [dcl.array] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

When several &#8220;array of&#8221; specifications are adjacent, a
multidimensional array is created; <SPAN style="font-weight:bold;background-color:#A0FFA0">only the first of</SPAN> the
constant expressions that specify the bounds of the arrays <SPAN style="text-decoration:line-through;background-color:#FFA0A0">can</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">may</SPAN> be omitted <SPAN style="text-decoration:line-through;background-color:#FFA0A0">only for the first member of the
sequence. [<I>Note:</I> this elision is useful for function parameters
of array types, and when the array is external and the definition,
which allocates storage, is given elsewhere. &#8212;<I>end
note</I>]</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">In addition to declarations in which an incomplete
object type is allowed, an array bound may be omitted in the
declaration of a function parameter (8.3.5 [dcl.fct]).</SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The first <I>constant-expression</I> can</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">An array bound
may</SPAN> also be omitted when the declarator is followed by an
<I>initializer</I> (8.5 [dcl.init]). In this case the bound
is calculated from the number of initial elements (say, <TT>N</TT>)
supplied (8.5.1 [dcl.init.aggr]), and the type of the identifier
of <TT>D</TT> is &#8220;array of <TT>N</TT> <TT>T</TT>.&#8221;
<SPAN style="font-weight:bold;background-color:#A0FFA0">Furthermore, if there is a visible declaration of the name declared
by the <I>declarator-id</I> (if any) in which the bound was specified,
an omitted array bound is taken to be the same as in that earlier
declaration.</SPAN>

</BLOCKQUOTE>

</OL>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>The proposed resolution does not capture the result favored
by the CWG: array bound information should be accumulated across
declarations within the same scope, but a block extern declaration
in a nested scope should not inherit array bound information from
the outer declaration.  (This is consistent with the treatment of
default arguments in function declarations.)  For example:</P>

<PRE>
    int a[5];
    void f() {
        extern int a[];
        sizeof(a);
    }
</PRE>

<P>Although there was some confusion about the C99 wording dealing
with this case, it is probably well-formed in C99.  However, it
should be ill-formed in C++, because we want to avoid the
concept of &#8220;compatible types&#8221; as it exists in C.</P>

<P><B>Proposed resolution (March, 2010):</B></P>

<OL><LI><P>Change 8.3.4 [dcl.array] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">If</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Except as noted below, if</SPAN> the constant expression
is omitted, the type of the identifier of <TT>D</TT> is
&#8220;<I>derived-declarator-type-list</I> array of unknown bound of
<TT>T</TT>,&#8221; an incomplete object type...

</BLOCKQUOTE>

<LI><P>Change 8.3.4 [dcl.array] paragraphs 3-4 as follows:</P></LI>

<BLOCKQUOTE>

<P>When several &#8220;array of&#8221; specifications are
adjacent, a multidimensional array is created; <SPAN style="font-weight:bold;background-color:#A0FFA0">only the
first of</SPAN> the constant expressions that specify the bounds
of the arrays <SPAN style="text-decoration:line-through;background-color:#FFA0A0">can</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">may</SPAN> be omitted <SPAN style="text-decoration:line-through;background-color:#FFA0A0">only
for the first member of the sequence. [<I>Note:</I> this elision
is useful for function parameters of array types, and when the
array is external and the definition, which allocates storage, is
given elsewhere. &#8212;<I>end note</I>]</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">In addition
to declarations in which an incomplete object type is allowed, an
array bound may be omitted in some cases in the declaration of a
function parameter (8.3.5 [dcl.fct]).</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The
first <I>constant-expression</I> can</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">An array bound
may</SPAN> also be omitted when the declarator is followed by an
<I>initializer</I> (8.5 [dcl.init]). In this case the
bound is calculated from the number of initial elements (say,
<TT>N</TT>) supplied (8.5.1 [dcl.init.aggr]), and the type
of the identifier of <TT>D</TT> is &#8220;array of <TT>N</TT>
<TT>T</TT>.&#8221; <SPAN style="font-weight:bold;background-color:#A0FFA0">Furthermore, if there is a preceding
declaration of the entity in the same scope in which the bound
was specified, an omitted array bound is taken to be the same as
in that earlier declaration, and similarly for the definition of a
static data member of a class.</SPAN></P>

<P>[<I>Example:...</I></P>

<P>...can reasonably appear in an expression.  <SPAN style="font-weight:bold;background-color:#A0FFA0">Finally,</SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  extern int x[10];
  struct S {
    static int y[10];
  };

  int x[];                //<SPAN style="font-family:Times;font-style:italic">OK: bound is 10</SPAN>
  int S::y[];             //<SPAN style="font-family:Times;font-style:italic">OK: bound is 10</SPAN>

  void f() {
    extern int x[];
    int i = sizeof(x);    //<SPAN style="font-family:Times;font-style:italic">error: incomplete object type</SPAN>
  }</SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="981"></A><H4>981.
  
Constexpr constructor templates and literal types
</H4><B>Section: </B>3.9&#160; [basic.types]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Gabriel Dos Reis
 &#160;&#160;&#160;

 <B>Date: </B>16 October, 2009<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>



<P>3.9 [basic.types] paragraph 10 requires that a class have at
least one constexpr constructor other than the copy constructor in
order to be considered a literal type.  However, a constexpr
constructor template might be instantiated in such a way that the
<TT>constexpr</TT> specifier is ignored (7.1.5 [dcl.constexpr]
paragraph 5).  It is therefore not known whether a class with a
constexpr constructor template is a literal type or not until the
constructor template is specialized, which could mean that an example
like</P>

<PRE>
    struct IntValue {
      template&lt;typename T&gt;
        constexpr IntValue(T t) : val(t) { }

      constexpr intmax_t get_value() { return val; }
     
     private:
       intmax_t val;
    };
</PRE>

<P>is ill-formed, because it is an error to declare a member function
(like <TT>get_value()</TT>) of a non-literal class to be constexpr
(7.1.5 [dcl.constexpr] paragraph 6).</P>

<P>3.9 [basic.types] paragraph 10 should be revised so that
either a constexpr constructor or constexpr constructor template
allows a class to be a literal type.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change 3.9 [basic.types] paragraph 10 as follows:</P>

<BLOCKQUOTE>

<P>A type is a <I>literal type</I> if it is:</P>

<UL><LI><P>a scalar type; or</P></LI>

<LI><P>a class type (Clause 9 [class]) <SPAN style="text-decoration:line-through;background-color:#FFA0A0">with</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">that</SPAN></P></LI>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">a trivial copy constructor,</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">no non-trivial move constructor,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">has</SPAN> a trivial destructor,</P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">a trivial default constructor or</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">is an aggregate
type (8.5.1 [dcl.init.aggr]) or has</SPAN> at least one constexpr
constructor <SPAN style="text-decoration:line-through;background-color:#FFA0A0">other than the</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">or constructor template that
is not a</SPAN> copy or move constructor, and</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">has</SPAN> all non-static data members and base classes of
literal types; or</P></LI>

</UL>

<LI><P>an array of literal type.</P></LI>

</UL>

</BLOCKQUOTE>

<P>This resolution also resolves issues <A HREF="
     cwg_defects.html#1071">1071</A>
and <A HREF="
     cwg_defects.html#1198">1198</A>.</P>

<BR><BR><HR><A NAME="1071"></A><H4>1071.
  
Literal class types and trivial default constructors
</H4><B>Section: </B>3.9&#160; [basic.types]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2010-06-02<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>



<P>According to 3.9 [basic.types] paragraph 10, one of the
requirements for a literal class type is</P>

<UL><LI><P>a trivial default constructor or at least one constexpr
constructor other than the copy or move constructor</P></LI></UL>

<P>This rule has unfortunate consequences.  For example, in</P>

<PRE>
    struct A { int x; };
    struct B: A { int y; };
</PRE>

<P><TT>B</TT> is a literal type, even though it is impossible to
initialize a constant of that type.  Conversely, in</P>

<PRE>
    struct C {
        int a, b;
        constexpr C(int x, int y): a(x), b(y) { }
    };
    struct D {
        int x;
        C c;
    };
</PRE>

<P><TT>D</TT> is not a literal type, even though it could be
initialized as an aggregate.</P>

<P>It would be an improvement to replace the requirement for a
trivial default constructor with a requirement that the class be
an aggregate.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#981">issue 981</A>.</P>

<BR><BR><HR><A NAME="1181"></A><H4>1181.
  
What is a &#8220;built-in type?&#8221;
</H4><B>Section: </B>3.9&#160; [basic.types]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Barry Hedquist
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-26<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

<P>The current draft uses the term &#8220;built-in type&#8221; several
times, but it is not defined anywhere. The Index appears to make it
synonymous with &#8220;fundamental type,&#8221; but the implication of
4 [conv] paragraph 1 is that compound types like pointers
should also be considered as &#8220;built-in.&#8221;</P>

<P><B>Proposed resolution (January, 2011):</B></P>

<OL><LI><P>Change 1.8 [intro.object] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

[<I>Note:</I> C++ provides a variety of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">built-in</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">fundamental</SPAN> types and several ways of composing new types
from existing types (3.9 [basic.types]). &#8212;<I>end
note</I>]

</BLOCKQUOTE>

<LI><P>Change 2.5 [lex.pptoken] as follows:</P></LI>

<BLOCKQUOTE>

[<I>Example:</I> The program fragment <TT>x+++++y</TT> is parsed as
<TT>x ++ ++ + y</TT>, which, if <TT>x</TT> and <TT>y</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">are of
built-in</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">have integral</SPAN> types, violates a constraint
on increment operators, even though the parse <TT>x ++ + ++ y</TT>
might yield a correct expression.  &#8212;<I>end example</I>]

</BLOCKQUOTE>

<LI><P>Change 18.3.2.4 [numeric.limits.members] paragraph 58 as follows:</P></LI>

<BLOCKQUOTE>

True if the set of values representable by the type is
finite.<SUP>220</SUP> [<I>Note:</I> All <SPAN style="text-decoration:line-through;background-color:#FFA0A0">built-in</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">fundamental</SPAN> types <SPAN style="font-weight:bold;background-color:#A0FFA0">(3.9.1 [basic.fundamental])</SPAN>
are bounded.  This member would be false for arbitrary precision
types. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Change 24.2.1 [iterator.requirements.general] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...All input iterators <TT>i</TT> support the expression <TT>*i</TT>,
resulting in a value of some <SPAN style="text-decoration:line-through;background-color:#FFA0A0">class, enumeration, or
built-in</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">object</SPAN> type <TT>T</TT>, called the <I>value
type</I> of the iterator...

</BLOCKQUOTE>

<LI><P>Change 24.2.3 [input.iterators] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

A class or a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">built-in</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">pointer</SPAN> type <TT>X</TT>
satisfies the requirements of an input iterator for the value type
<TT>T</TT> if <TT>X</TT> satisfies the <TT>Iterator</TT> (24.2.2 [iterator.iterators]) and <TT>EqualityComparable</TT> (Table 33)
requirements and the expressions in Table 107 are valid and have the
indicated semantics.

</BLOCKQUOTE>

<LI><P>Change 24.2.4 [output.iterators] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

A class or a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">built-in</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">pointer</SPAN> type <TT>X</TT>
satisfies the requirements of an output iterator <SPAN style="text-decoration:line-through;background-color:#FFA0A0">if
<TT>X</TT></SPAN> if <TT>X</TT> satisfies the <TT>Iterator</TT>
requirements (24.2.2 [iterator.iterators]) and the expressions in
Table 108 are valid and have the indicated semantics.

</BLOCKQUOTE>

<LI><P>Change 24.2.5 [forward.iterators] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

A class or a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">built-in</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">pointer</SPAN> type <TT>X</TT>
satisfies the requirements of a forward iterator if...

</BLOCKQUOTE>

<LI><P>Change 24.2.6 [bidirectional.iterators] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

A class or a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">built-in</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">pointer</SPAN> type <TT>X</TT>
satisfies the requirements of a bidirectional iterator if, in addition
to satisfying the requirements for forward iterators, the following
expressions are valid as shown in Table 110.

</BLOCKQUOTE>

<LI><P>Change 24.2.7 [random.access.iterators] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

A class or a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">built-in</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">pointer</SPAN> type <TT>X</TT>
satisfies the requirements of a random access iterator if, in addition
to satisfying the requirements for bidirectional iterators, the
following expressions are valid as shown in Table 111.

</BLOCKQUOTE>

<LI><P>Change C.1.2 [diff.basic] section 3.1 as follows:</P></LI>

<BLOCKQUOTE>

<B>Rationale</B>: This avoids having different initialization rules
for <SPAN style="text-decoration:line-through;background-color:#FFA0A0">built-in</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">fundamental</SPAN> types and user-defined
types.

</BLOCKQUOTE>

<LI><P>Change C.1.8 [diff.class] section 9.1 as follows:</P></LI>

<BLOCKQUOTE>

...This new name space definition provides important notational
conveniences to C++ programmers and helps making the use of the
user-defined types as similar as possible to the use of
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">built-in</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">fundamental</SPAN> types...

</BLOCKQUOTE>

<LI><P>Delete the index entry, &#8220;built-in type; see fundamental
type</P>.&#8221;</LI>

</OL>

<P>(Note: This resolution assumes that the resolution for
<A HREF="
     cwg_defects.html#572">issue 572</A> has been applied, removing
&#8220;built-in type&#8221; from 4 [conv] paragraph 1.)</P>

<BR><BR><HR><A NAME="1198"></A><H4>1198.
  
Literal types and copy constructors
</H4><B>Section: </B>3.9&#160; [basic.types]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-09-16<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>



<P>According to 3.9 [basic.types] paragraph 10, a literal
class type has</P>

<UL><LI><P>a trivial copy constructor,</P></LI>

<LI><P>no non-trivial move constructor,</P></LI>

<LI><P>...</P></LI>

</UL>

<P>Is this intended to mean that</P>

<PRE>
    struct A {
       A(const A&amp;) = default;
       A(A&amp;);
    };
</PRE>

<P>is a literal class because it does have a trivial copy constructor
even though it also has a non-trivial one?  That seems inconsistent
with the prohibition of non-trivial move constructors.</P>

<P>My preference would be to resolve this inconsistency by dropping
the restriction on non-trivial move constructors.  It seems to me that
having a trivial copy or move constructor is sufficient, we don't need
to prohibit additional non-trivial ones.  Actually, it's not clear to
me that we need the first condition either; a literal type could be
used for singleton variables even if it can't be copied.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#981">issue 981</A>.</P>

<BR><BR><HR><A NAME="1219"></A><H4>1219.
  
Non-static data member initializers in constant expressions
</H4><B>Section: </B>3.9&#160; [basic.types]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jens Maurer
 &#160;&#160;&#160;

 <B>Date: </B>2010-11-13<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>The current treatment of constexpr constructors and constant expressions
does not deal with the initializers for non-static data members, which
should also be required to be constant expressions.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<OL><LI><P>Change 3.6.2 [basic.start.init] paragraph 2 as follows:</P></LI>

<UL><LI><P>if an object with static or thread storage duration is
initialized by a constructor call, if the constructor is a
<TT>constexpr</TT> constructor, if all constructor arguments are
constant expressions (including conversions), and if, after function
invocation substitution (7.1.5 [dcl.constexpr]), every constructor call
and full-expression in the <I>mem-initializer</I>s <SPAN style="font-weight:bold;background-color:#A0FFA0">and in the
<I>brace-or-equal-initializer</I>s for non-static data members</SPAN>
is a constant expression </P></LI></UL>

<LI><P>Change 3.9 [basic.types] paragraph 10 as follows (wording
assumes the proposed resolution of <A HREF="
     cwg_defects.html#981">issue 981</A>)</P></LI>

<BLOCKQUOTE>

<P>A type is a <I>literal type</I> if it is:</P>

<UL><LI><P>a scalar type; or</P></LI>

<LI><P>a class type (clause 9 [class]) that
<SPAN style="font-weight:bold;background-color:#A0FFA0">has all of the following properties:</SPAN></P></LI>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">it</SPAN> has a trivial destructor,</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">every constructor call and full-expression in the
<I>brace-or-equal-initializer</I>s for non-static data members (if
any) is a constant expression (5.19 [expr.const]),</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">it</SPAN> is an aggregate type (8.5.1 [dcl.init.aggr]) or
has at least one <TT>constexpr</TT> constructor or constructor
template that is not a copy or move constructor, and</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">it</SPAN> has all non-static data members and base
classes of literal types; or</P></LI>

</UL>

<LI><P>an array of literal type.</P></LI>

</UL>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1055"></A><H4>1055.
  
Permissible uses of <TT>void</TT>
</H4><B>Section: </B>3.9.1&#160; [basic.fundamental]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Nikolay Ivchenkov
 &#160;&#160;&#160;

 <B>Date: </B>2010-03-17<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>According to 3.9.1 [basic.fundamental] paragraph 9,</P>

<BLOCKQUOTE>

Any expression can be explicitly converted to type <I>cv</I>
<TT>void</TT> (5.4 [expr.cast]).  An expression of type
<TT>void</TT> shall be used only as an expression statement
(6.2 [stmt.expr]), as an operand of a comma expression
(5.18 [expr.comma]), as a second or third operand of
<TT>?:</TT> (5.16 [expr.cond]), as the operand of
<TT>typeid</TT>, or as the expression in a return statement
(6.6.3 [stmt.return]) for a function with the return type
<TT>void</TT>.

</BLOCKQUOTE>

<P>First, this is self-contradictory: if &#8220;any expression&#8221;
can be converted to <TT>void</TT>, why is such a conversion not listed
among the acceptable uses of an expression of type <TT>void</TT>?</P>

<P>Second, presumably an expression of type <TT>void</TT> can be used
as an operand of <TT>decltype</TT>, but this use is not listed.</P>

<P>Finally, there are several places in the Standard that speak of
expressions having a cv-qualified <TT>void</TT> type
(5.16 [expr.cond] paragraph 2, 6.6.3 [stmt.return]
paragraph 3).  However, an expression of type <TT>void</TT> is a
non-class prvalue, and there are no cv-qualified non-class prvalues
(3.10 [basic.lval] paragraph 4).</P>

<P><B>Proposed resolution (February, 2011):</B></P>

<OL><LI><P>Change 3.9.1 [basic.fundamental] paragraph 9 as follows:</P></LI>

<BLOCKQUOTE>

...Any expression can be explicitly converted to type <I>cv</I>
<TT>void</TT> (5.4 [expr.cast]). An expression of type
<TT>void</TT> shall be used only as an expression statement
(6.2 [stmt.expr]), as an operand of a comma expression
(5.18 [expr.comma]), as a second or third operand of
<TT>?:</TT> (5.16 [expr.cond]), as the operand of
<TT>typeid</TT> <SPAN style="font-weight:bold;background-color:#A0FFA0">or <TT>decltype</TT></SPAN>, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN> as the
expression in a return statement (6.6.3 [stmt.return]) for a
function with the return type <TT>void</TT><SPAN style="font-weight:bold;background-color:#A0FFA0">, or as the operand
of an explicit conversion to type <I>cv</I> <TT>void</TT></SPAN>.

</BLOCKQUOTE>

<LI><P>Change 5.16 [expr.cond] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

If either the second or the third operand has type <SPAN style="text-decoration:line-through;background-color:#FFA0A0">(possibly
cv-qualified)</SPAN> <TT>void</TT>, then...

</BLOCKQUOTE>

<LI><P>Change 6.6.3 [stmt.return] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

A return statement with an expression of type
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">&#8220;<I>cv</I></SPAN> <TT>void</TT><SPAN style="text-decoration:line-through;background-color:#FFA0A0">&#8221;</SPAN> can be
used only in functions with a return type of <I>cv</I> <TT>void</TT>;
the expression is evaluated just before the function returns to its
caller.

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="964"></A><H4>964.
  
Incorrect description of when the lvalue-to-rvalue conversion applies
</H4><B>Section: </B>3.10&#160; [basic.lval]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Doug Gregor
 &#160;&#160;&#160;

 <B>Date: </B>14 September, 2009<BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>



<P>3.10 [basic.lval] paragraph 7 says,</P>

<BLOCKQUOTE>

Whenever an lvalue appears in a context where an rvalue is expected,
the lvalue is converted to an rvalue

</BLOCKQUOTE>

<P>That is not correct in the context of an attempt to bind an
rvalue reference to an lvalue (8.5.3 [dcl.init.ref]).</P>

<P><B>Proposed resolution (October, 2009):</B></P>

<P>Change 3.10 [basic.lval] paragraph 7 as follows:</P>

<BLOCKQUOTE>

Whenever an lvalue appears in a context where an rvalue is expected
<SPAN style="font-weight:bold;background-color:#A0FFA0">and an lvalue is not explicitly prohibited (as, for example, in
8.5.3 [dcl.init.ref])</SPAN>, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the lvalue</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">it</SPAN>
is converted to an rvalue; see 4.1 [conv.lval], 4.2 [conv.array], and 4.3 [conv.func].

</BLOCKQUOTE>

<P><B>Notes from the March, 2010 meeting:</B></P>

<P>This resolution needs to be reconsidered in light of the new
expression taxonomy.</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<P>Change 3.10 [basic.lval] paragraph 2 as follows:</P>

<BLOCKQUOTE>

Whenever a glvalue appears in a context where a prvalue is expected,
the glvalue is converted to a prvalue; see 4.1 [conv.lval],
4.2 [conv.array], and 4.3 [conv.func].
<SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> An attempt to bind an rvalue reference to an lvalue
is not such a context; see 8.5.3 [dcl.init.ref]. &#8212;<I>end
note</I>]</SPAN>

</BLOCKQUOTE>


<BR><BR><HR><A NAME="1090"></A><H4>1090.
  
Alignment of subobjects
</H4><B>Section: </B>3.11&#160; [basic.align]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>2010-06-23<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>The current wording of the Standard does not recognize the fact
that the alignment of a complete object of a given type may be
different from its alignment as a subobject.  This arises in
particular with virtual base classes.  For example,</P>

<PRE>
    struct B { long double d; };
    struct D: virtual B { char c; };
</PRE>

<P>When <TT>D</TT> is a complete object, it will have a subobject of
type <TT>B</TT>, which must be aligned appropriately for a <TT>long
double</TT>.  On the other hand, if <TT>D</TT> appears as a subobject
of another object, the <TT>B</TT> subobject might be part of a
different subobject, reducing the alignment requirement on the
<TT>D</TT> subobject.</P>

<P>The Standard should make clear that it is the complete-object
alignment that is being described, in parallel with the distinction
between the size of a complete object and a subobject of the same
type.</P>

<BR><BR><HR><A NAME="1115"></A><H4>1115.
  
C-compatible alignment specification
</H4><B>Section: </B>3.11&#160; [basic.align]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting in document N3190.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US25">N3092 comment
  US&#160;25<BR></A>
<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#GB31">N3092 comment
  GB&#160;31<BR></A>

<P>The C and C++ approaches to alignment are incompatible.  See
document PL22.16 10-0083 = WG21 N3093 for details.</P>

<P><B>Notes from the August, 2010 meeting:</B></P>

<P>CWG agreed that the alignment specifier should be a keyword
instead of an attributes.</P>

<BR><BR><HR><A NAME="1180"></A><H4>1180.
  
Over-aligned class types
</H4><B>Section: </B>3.11&#160; [basic.align]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Clark Nelson
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-25<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>Now that alignment can be applied directly to class types, the
current wording of the note at the end of 3.11 [basic.align]
paragraph 3 is no longer correct:</P>

<BLOCKQUOTE>

[<I>Note:</I> every over-aligned type is or contains a class type with
a non-static data member to which an extended alignment has been
applied. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<P><U>Proposed resolution (November, 2010):</U></P>

<P>Change 3.11 [basic.align] paragraph 3 as follows:</P>

<BLOCKQUOTE>

[<I>Note:</I> every over-aligned type is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or contains</SPAN> a
class type <SPAN style="text-decoration:line-through;background-color:#FFA0A0">with a non-static data member to which an
extended alignment has been applied</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">to which extended
alignment applies (possibly through a non-static data
member)</SPAN>. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<BR><BR><HR><A NAME="572"></A><H4>572.
  
Standard conversions for non-built-in types
</H4><B>Section: </B>4&#160; [conv]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jens Maurer
 &#160;&#160;&#160;

 <B>Date: </B>6 April 2006<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

<P>4 [conv] paragraph 1 says,</P>

<BLOCKQUOTE>

Standard conversions are implicit conversions defined for built-in types.

</BLOCKQUOTE>

<P>However, enumeration types (which take part in the integral
promotions) and class types (which take part in the lvalue-to-rvalue
conversion) are not &#8220;built-in&#8221; types, so the definition of
&#8220;standard conversions&#8221; is wrong.</P>

<P><B>Proposed resolution (October, 2006):</B></P>

<P>Change 4 [conv] paragraph 1 as follows:</P>

<BLOCKQUOTE>

Standard conversions are implicit conversions <SPAN style="text-decoration:line-through;background-color:#FFA0A0">defined for built-in types</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">with built-in meaning</SPAN>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1117"></A><H4>1117.
  
Incorrect note about xvalue member access expressions
</H4><B>Section: </B>5&#160; [expr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>JP
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#JP1">N3092 comment
  JP&#160;1<BR></A>

<P>One of the bullets in the note in 5 [expr] paragraph
6 says that an expression is an xvalue if it is:</P>

<UL><LI><P>a class member access expression designating a
non-static data member in which the object expression is an
xvalue</P></LI></UL>

<P>This is incorrect if the type of the non-static data member
is a reference type (cf 5.2.5 [expr.ref] paragraph 4.)</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<P>Change 5 [expr] paragraph 6 bullet 3 as follows:</P>

<UL><LI><P>a class member access expression designating a non-static
data member <SPAN style="font-weight:bold;background-color:#A0FFA0">of non-reference type</SPAN> in which the object
expression is an xvalue, or</P></LI></UL>

<BR><BR><HR><A NAME="945"></A><H4>945.
  
Use of <TT>this</TT> in a late-specified return type
</H4><B>Section: </B>5.1.1&#160; [expr.prim.general]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>18 July, 2009<BR>


<P>(Moved from <A HREF="
     cwg_defects.html#760">issue 760</A>.)</P>

<P>Although it was considered and rejected as part of
<A HREF="
     cwg_closed.html#643">issue 643</A>, more recent developments
may argue in favor of allowing the use of <TT>this</TT> in a
late-specified return type.  In particular, declaring the return
type for a forwarding function in a derived class template that invokes
a member function of a dependent base class is difficult without
this facility.  For example:</P>

<PRE>
    template &lt;typename T&gt; struct derived: base&lt;T&gt; {
      auto invoke() -&gt; decltype(this-&gt;base_func()) {
        return this-&gt;base_func();
      }
    };
</PRE>

<P>(See also <A HREF="
     cwg_defects.html#1207">issue 1207</A> for another
potential motivation for a change to this rule.)</P>

<P><B>Additional note (October, 2010):</B></P>



<P>The question should also be considered for parameter types; for
example,</P>

<PRE>
class comparable {
public:
   bool is_equal(decltype(*this) other) { // should be X&amp;
       return /*...*/;
   }
};
</PRE>

<P><B>Proposed resolution (March, 2011):</B></P>

<P>This issue is resolved by the resolution of issues
<A HREF="
     cwg_defects.html#1017">1017</A> and <A HREF="
     cwg_defects.html#1207">1207</A>
in document N3282.</P>

<BR><BR><HR><A NAME="1034"></A><H4>1034.
  
Attributes for <TT>return</TT> statements in lambdas
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>2010-02-18<BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<P>5.1.2 [expr.prim.lambda] paragraph 4 bullet 1 says,</P>

<BLOCKQUOTE>

<P>if the <I>compound-statement</I> if [sic] of the form</P>

<UL><TT>{ return</TT> <I>attribute-specifier<SUB>opt</SUB> expression</I> <TT>; }</TT></UL>

<P>the type of the returned expression...</P>

</BLOCKQUOTE>

<P>The problem (besides the typo &#8220;if&#8221;) is that the
<I>attribute-specifier</I> for a <TT>return</TT> statement precedes,
rather than following, the keyword (6 [stmt.stmt] paragraph
1).</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<P>Change 5.1.2 [expr.prim.lambda] paragraph 4 bullet 1 as follows:</P>

<UL><LI><P>if the <I>compound-statement</I> is of the form</P>

<UL><TT>{ <SPAN style="text-decoration:line-through;background-color:#FFA0A0">return</SPAN></TT> <I>attribute-specifier<SUB>opt</SUB> </I><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>return</TT></SPAN><I> expression </I><TT>; }</TT></UL>

<P>the type of the returned expression after lvalue-to-rvalue
conversion (4.1 [conv.lval]), array-to-pointer conversion
(4.2 [conv.array]), and function-to-pointer conversion
(4.3 [conv.func]);</P>

</LI></UL>

<BR><BR><HR><A NAME="1062"></A><H4>1062.
  
Syntax of <I>attribute-specifier</I>s in lambdas
</H4><B>Section: </B>5.1.2&#160; [expr.prim.lambda]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Peter Sommerlad
 &#160;&#160;&#160;

 <B>Date: </B>2010-03-23<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#CH4">N3092 comment
  CH&#160;4<BR></A>



<P>The adoption of paper N3067 at the March, 2010 meeting moved the
position of the optional <I>attribute-specifier</I> in a function
declarator from immediately following the
<I>parameter-declaration-clause</I> to after the
<I>exception-specification</I>.  However, the grammar in
5.1.2 [expr.prim.lambda] paragraph 1 and the verbal description
in paragraph 5 still have the <I>attribute-specifier</I> in a
<I>lambda-declarator</I> at its old position.  These should be
updated to reflect the new function declarator syntax.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<OL><LI><P>Change the grammar in 5.1.2 [expr.prim.lambda] paragraph 1
as follows:</P></LI>

<UL><I>lambda-declarator:</I><BR>
<UL><TT>(</TT> <I>parameter-declaration-clause</I> <TT>)</TT> <I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">attribute-specifier<SUB>opt</SUB></SPAN></I> <TT>mutable</TT><I><SUB>opt</SUB></I><BR>
<UL><I>exception-specification<SUB>opt</SUB> <SPAN style="font-weight:bold;background-color:#A0FFA0">attribute-specifier<SUB>opt</SUB></SPAN> trailing-return-type<SUB>opt</SUB></I></UL></UL>
</UL>

<LI><P>Change 5.1.2 [expr.prim.lambda] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Any <I>attribute-specifier</I>s appearing immediately after the
<I>lambda-expression</I>'s
<I>parameter-declaration-clause</I> appertain</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">An
<I>attribute-specifier</I> in a <I>lambda-declarator</I>
appertains</SPAN> to the type of the corresponding function
call operator...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="798"></A><H4>798.
  
Overloaded subscript operator described in clause 5
</H4><B>Section: </B>5.2.1&#160; [expr.sub]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>UK
 &#160;&#160;&#160;

 <B>Date: </B>3 March, 2009<BR><BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3086.html#UK53">N2800 comment
  UK&#160;53<BR></A>

<P>5.2.1 [expr.sub] paragraph 2 deals with one particular
aspect of the overloaded <TT>operator[]</TT>, which seems out of place.
Either 5.2.1 [expr.sub] should be augmented to discuss
the overloaded <TT>operator[]</TT> in general or the information in
paragraph 2 should be moved into 13.5.5 [over.sub].</P>

<BR><BR><HR><A NAME="1083"></A><H4>1083.
  
Passing an object to ellipsis with non-trivial move constructor
</H4><B>Section: </B>5.2.2&#160; [expr.call]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-06-22<BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>



<P>5.2.2 [expr.call] paragraph 7 should mention a non-trivial
move constructor as well, for consistency with &#8220;trivially
copyable.&#8221;</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<P>Change 5.2.2 [expr.call] paragraph 7 as follows:</P>

<BLOCKQUOTE>

...Passing a potentially-evaluated argument of class type (Clause
9 [class]) <SPAN style="text-decoration:line-through;background-color:#FFA0A0">with</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">having</SPAN> a
non-trivial copy constructor<SPAN style="font-weight:bold;background-color:#A0FFA0">, a non-trivial move
constructor,</SPAN> or a non-trivial destructor<SPAN style="font-weight:bold;background-color:#A0FFA0">,</SPAN> with no
corresponding parameter is conditionally-supported<SPAN style="text-decoration:line-through;background-color:#FFA0A0">,</SPAN> with
implementation-defined semantics. If the argument...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1119"></A><H4>1119.
  
Missing case in description of member access ambiguity
</H4><B>Section: </B>5.2.5&#160; [expr.ref]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US32">N3092 comment
  US&#160;32<BR></A>

<P>According to 5.2.5 [expr.ref] paragraph 5,</P>

<BLOCKQUOTE>

If <TT>E2</TT> is a non-static data member or a non-static
member function, the program is ill-formed if the class of
which <TT>E2</TT> is directly a member is an ambiguous base
(10.2 [class.member.lookup]) of the naming class
(11.2 [class.access.base]) of <TT>E2</TT>.

</BLOCKQUOTE>

<P>This does not cover the following case:</P>

<PRE>
    struct A { int i; };
    struct B: A { };
    struct C: A, B { };
    void f(C* p) {
      p-&gt;A::i; // Should be ambiguous
    }
</PRE>

<P><B>Notes (August, 2010):</B></P>

<P>The example in the FCD National Body comment is incorrect: it is
missing the <TT>A::</TT> in the next-to-last line.</P>

<P>The ambiguity actually is covered in the Standard but in an
unexpected location: 11.2 [class.access.base] paragraph 6:</P>

<BLOCKQUOTE>

If a class member access operator, including an implicit
&#8220;<TT>this-&gt;</TT>,&#8221; is used to access a
non-static data member or non-static member function, the
reference is ill-formed if the left operand (considered as a
pointer in the &#8220;<TT>.</TT>&#8221; operator case)
cannot be implicitly converted to a pointer to the naming
class of the right operand.

</BLOCKQUOTE>

<P>An explanatory note, including a cross-reference to
11.2 [class.access.base], should be added to
5.2.5 [expr.ref] paragraph 6.</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<P>Change 5.2.5 [expr.ref] paragraph 5 as follows:</P>

<BLOCKQUOTE>

If <TT>E2</TT> is a non-static data member or a non-static member
function, the program is ill-formed if the class of which <TT>E2</TT>
is directly a member is an ambiguous base (10.2 [class.member.lookup])
of the naming class (11.2 [class.access.base]) of
<TT>E2</TT>. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> The program is also ill-formed if the
naming class is an ambiguous base of the class type of the object
expression; see 11.2 [class.access.base]. &#8212;<I>end
note</I>]</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1011"></A><H4>1011.
  
Standard conversions that cannot be inverted
</H4><B>Section: </B>5.2.9&#160; [expr.static.cast]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>2009-12-03<BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<P>According to 5.2.9 [expr.static.cast] paragraph 7, <TT>static_cast</TT>
can be used to perform the inverse of any standard conversion sequence
except the lvalue-to-rvalue, array-to-pointer, function-to-pointer, and
boolean conversions.  The null pointer and null pointer-to-member
conversions should also be listed &#8212; it should not be permitted to
cast a pointer or pointer-to-member to either integral type or
<TT>std::nullptr_t</TT>.</P>

<P><B>Proposed resolution (October, 2010):</B></P>

<OL><LI><P>Change 4.10 [conv.ptr] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...A null pointer constant can be converted to a pointer type; the
result is the <I>null pointer value</I> of that type and is
distinguishable from every other value of pointer to object or pointer
to function type. <SPAN style="font-weight:bold;background-color:#A0FFA0">Such a conversion is called a <I>null pointer
conversion</I>.</SPAN> Two null pointer values...

</BLOCKQUOTE>

<LI><P>Change 4.11 [conv.mem] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

A null pointer constant (4.10 [conv.ptr]) can be converted
to a pointer to member type; the result is the <I>null member pointer
value</I> of that type and is distinguishable from any pointer to
member not created from a null pointer constant. <SPAN style="font-weight:bold;background-color:#A0FFA0">Such a
conversion is called a <I>null member pointer conversion.</I></SPAN>
Two null member pointer values...

</BLOCKQUOTE>

<LI><P>Change 5.2.9 [expr.static.cast] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

The inverse of any standard conversion sequence (Clause 4 [conv])<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, other than the</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">not containing an</SPAN>
lvalue-to-rvalue (4.1 [conv.lval]), array-to-pointer
(4.2 [conv.array]), function-to-pointer (4.3 [conv.func]), <SPAN style="text-decoration:line-through;background-color:#FFA0A0">and</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">null pointer (4.10 [conv.ptr]), null member pointer (4.11 [conv.mem]),
or</SPAN> boolean (4.12 [conv.bool]) conversion<SPAN style="text-decoration:line-through;background-color:#FFA0A0">s</SPAN>,
can be performed explicitly using <TT>static_cast</TT>. A program is
ill-formed...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1094"></A><H4>1094.
  
Converting floating-point values to scoped enumeration types
</H4><B>Section: </B>5.2.9&#160; [expr.static.cast]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2010-07-17<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>



<P>According to 7.2 [dcl.enum] paragraph 10,</P>

<BLOCKQUOTE>

An expression of arithmetic or enumeration type can be
converted to an enumeration type explicitly.

</BLOCKQUOTE>

<P>However, 5.2.9 [expr.static.cast] paragraph 10 says only,</P>

<BLOCKQUOTE>

A value of integral or enumeration type can be explicitly
converted to an enumeration type.

</BLOCKQUOTE>

<P>This omits floating-point values.  Presumably unscoped
enumeration types are covered by paragraph 7,</P>

<BLOCKQUOTE>

The inverse of any standard conversion sequence (Clause
4 [conv]), other than the lvalue-to-rvalue
(4.1 [conv.lval]), array-to- pointer (4.2 [conv.array]), function-to-pointer (4.3 [conv.func]), and boolean (4.12 [conv.bool])
conversions, can be performed explicitly using
<TT>static_cast</TT>.

</BLOCKQUOTE>

<P>because 4.9 [conv.fpint] paragraph 2 allows an
unscoped enumeration value to be implicitly converted to a
floating point type.  (Although that also covers the integral
types, so it's not clear why they would be mentioned
specifically in 5.2.9 [expr.static.cast] paragraph 10.)
However, this should presumably say &#8220;arithmetic&#8221;
instead of &#8220;integral&#8221; to match the statement in
7.2 [dcl.enum] paragraph 10.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<OL><LI><P>Change 5.2.9 [expr.static.cast] paragraph 10 as follows:</P></LI>

<BLOCKQUOTE>

A value of integral or enumeration type can be explicitly converted to
an enumeration type.  The value is unchanged if the original value is
within the range of the enumeration values (7.2 [dcl.enum]). Otherwise, the resulting <SPAN style="text-decoration:line-through;background-color:#FFA0A0">enumeration</SPAN> value is
unspecified <SPAN style="font-weight:bold;background-color:#A0FFA0">(and might not be in that range). A value of
floating-point type can also be converted to an enumeration type. The
resulting value is the same as converting the original value to the
underlying type of the enumeration (4.9 [conv.fpint]), and
subsequently to the enumeration type</SPAN>.

</BLOCKQUOTE>

<LI><P>Add the following footnote to the end of 7.2 [dcl.enum]
paragraph 7:</P></LI>

<BLOCKQUOTE>

...If the <I>enumerator-list</I> is empty, the values of the
enumeration are as if the enumeration had a single enumerator with
value 0. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Footnote:</I> This set of values is used to define
promotion and conversion semantics for the enumeration type; it does
not exclude an expression of enumeration type from having a value that
falls outside this range. &#8212;<I>end footnote</I>]</SPAN>

</BLOCKQUOTE>

<LI><P>Delete 7.2 [dcl.enum] paragraph 10:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">An expression of arithmetic or enumeration type can be converted
to an enumeration type explicitly.  The value is unchanged if it is in
the range of enumeration values of the enumeration type; otherwise the
resulting enumeration value is unspecified.</SPAN>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="573"></A><H4>573.
  
Conversions between function pointers and <TT>void*</TT>
</H4><B>Section: </B>5.2.10&#160; [expr.reinterpret.cast]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>13 April 2006<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

<P>The resolution to <A HREF="
     cwg_defects.html#195">issue 195</A> makes
&#8220;converting a pointer to a function into a pointer to an object
type or vice versa&#8221; conditionally-supported behavior.  In doing
so, however, it overlooked the fact that <TT>void</TT> is not an
&#8220;object type&#8221; (3.9 [basic.types] paragraph 9).
The wording should be amended to allow conversion to and
from <TT>void*</TT> types.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<OL><LI><P>Change 3.7.4.3 [basic.stc.dynamic.safety] paragraphs 1-2 as
follows:</P></LI>

<BLOCKQUOTE>

<P>A <I>traceable pointer object</I> is</P>

<UL><LI><P>an object of <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>pointer-to-object</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an
object pointer</SPAN> type <SPAN style="font-weight:bold;background-color:#A0FFA0">(3.9.2 [basic.compound])</SPAN>,
or</P></LI>

<LI><P>an object of an integral type that is at least as large as
<TT>std::intptr_t</TT>, or</P></LI>

<LI><P>a sequence of elements in an array of character type, where the
size and alignment of the sequence match <SPAN style="text-decoration:line-through;background-color:#FFA0A0">that</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">those</SPAN> of some <SPAN style="text-decoration:line-through;background-color:#FFA0A0">pointer-to-object</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">object
pointer</SPAN> type.</P></LI>

</UL>

<P>A pointer value is a <I>safely-derived pointer</I> to a dynamic
object only if it has <SPAN style="text-decoration:line-through;background-color:#FFA0A0">pointer-to-object</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an object
pointer</SPAN> type and it is...</P>

</BLOCKQUOTE>

<LI><P>Change 3.9.2 [basic.compound] paragraphs 3-4 as follows:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">The type of a pointer to <TT>void</TT> or a pointer to an
object type is called an <I>object pointer type</I>. [<I>Note:</I> A
pointer to <TT>void</TT> does not have a pointer-to-object type,
however, because <TT>void</TT> is not an object type. &#8212;<I>end
note</I>] The type of a pointer that can designate a function is
called a <I>function pointer type</I>.</SPAN> A pointer to objects of
type <TT>T</TT> is referred to as a &#8220;pointer to
<TT>T</TT>.&#8221; [<I>Example:</I>...</P>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">Objects of cv-qualified (3.9.3 [basic.type.qualifier]) or
cv-unqualified type <TT>void*</TT> (pointer to void),</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">A
pointer to cv-qualified (3.9.3 [basic.type.qualifier]) or cv-unqualified
<TT>void</TT></SPAN> can be used to point to objects of unknown
type. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">A <TT>void*</TT></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Such a pointer</SPAN> shall be
able to hold any object pointer. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">A cv-qualified or cv-unqualified
(3.9.3 [basic.type.qualifier])</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">An object of type
<I>cv</I></SPAN> <TT>void*</TT> shall have the same representation and
alignment requirements as <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a cv-qualified or cv-unqualified</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>cv</I></SPAN> <TT>char*</TT>.</P>

</BLOCKQUOTE>

<LI><P>Change 4.10 [conv.ptr] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...A null pointer constant can be converted to a pointer type; the
result is the <I>null pointer value</I> of that type and is
distinguishable from every other value of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">pointer to object or
pointer to function</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">object pointer or function
pointer</SPAN> type...

</BLOCKQUOTE>

<LI><P>Change 4.11 [conv.mem] paragraph 2 footnote 58 as
follows:</P></LI>

<BLOCKQUOTE>

...Note that a pointer to member is not <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a pointer to object or a
pointer to function</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an object pointer or a function
pointer</SPAN> and...

</BLOCKQUOTE>

<LI><P>Change 5.2.10 [expr.reinterpret.cast] paragraphs 6-8 as
follows:</P></LI>

<BLOCKQUOTE>

<P>A <SPAN style="text-decoration:line-through;background-color:#FFA0A0">pointer to a</SPAN> function <SPAN style="font-weight:bold;background-color:#A0FFA0">pointer</SPAN> can be
explicitly converted to a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">pointer to a</SPAN> function
<SPAN style="font-weight:bold;background-color:#A0FFA0">pointer</SPAN> of a different type...</P>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">A pointer to an</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">An</SPAN> object <SPAN style="font-weight:bold;background-color:#A0FFA0">pointer</SPAN>
can be explicitly converted to <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a pointer to a different object
type</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an object pointer of a different type</SPAN>...</P>

<P>Converting a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">pointer to a function into a pointer to an
object</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">function pointer to an object pointer</SPAN> type or
vice versa is conditionally-supported...</P>

</BLOCKQUOTE>

<LI><P>Change the note in 8.3.5 [dcl.fct] paragraph 6 as
follows:</P></LI>

<BLOCKQUOTE>

[<I>Note:</I> function types are checked during the assignments and
initializations of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">pointer-to-functions, reference-to-functions,
and pointer-to-member-functions</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">pointers to functions,
references to functions, and pointers to member
functions</SPAN>. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>In the &#8220;Index of Implementation-defined Behavior,&#8221;
change the following item as indicated:</P></LI>

<BLOCKQUOTE>

converting <SPAN style="text-decoration:line-through;background-color:#FFA0A0">pointer to function into pointer to object</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">function pointer to object pointer</SPAN> and vice versa

</BLOCKQUOTE>

</OL>

<P><I>[Drafting note: 5.3.5 [expr.delete] paragraph 1 was not
changed, so the operand of <TT>delete</TT> still cannot be a
<TT>void*</TT>.  13.6 [over.built] paragraph 14 was not
changed, so <TT>void*</TT> pointers still do not get overloads for
<TT>operator-</TT>.  14.1 [temp.param] paragraph 4 was not
changed and thus continues to allow only pointers to objects, not
object pointers, as non-type template parameters.]</I></P>

<P>(See also <A HREF="
     cwg_defects.html#1120">issue 1120</A>.)</P>

<BR><BR><HR><A NAME="1120"></A><H4>1120.
  
<TT>reinterpret_cast</TT> and <TT>void*</TT>
</H4><B>Section: </B>5.2.10&#160; [expr.reinterpret.cast]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>GB
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#GB22">N3092 comment
  GB&#160;22<BR></A>

<P>It is not permitted to use <TT>reinterpret_cast</TT> to convert
between pointers to object type and pointers to <TT>void</TT>.</P>

<P>See also <A HREF="
     cwg_defects.html#573">issue 573</A>.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change 5.2.10 [expr.reinterpret.cast] paragraph 7 as follows:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A pointer to an object</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">An object
pointer</SPAN> can be explicitly converted to <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a pointer
to a different object type</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an object pointer of a
different type</SPAN>.<SUP>70</SUP> When a prvalue <TT>v</TT>
of type &#8220;pointer to <TT>T1</TT>&#8221; is converted to
the type &#8220;pointer to
<I>cv</I> <TT>T2</TT>&#8221;, the result is
<TT>static_cast&lt;</TT><I>cv</I>
<TT>T2*&gt;(static_cast&lt;</TT><I>cv</I>
<TT>void*&gt;(v))</TT> if both <TT>T1</TT> and <TT>T2</TT>
are standard-layout types (3.9 [basic.types]) and the
alignment requirements of <TT>T2</TT> are no stricter than
those of <TT>T1</TT><SPAN style="font-weight:bold;background-color:#A0FFA0">, or if either type is
<TT>void</TT></SPAN>.  Converting a prvalue of type
&#8220;pointer to <TT>T1</TT>&#8221; to the type
&#8220;pointer to <TT>T2</TT>&#8221; (where <TT>T1</TT> and
<TT>T2</TT> are object types and where the alignment
requirements of <TT>T2</TT> are no stricter than those of
<TT>T1</TT>) and back to its original type yields the
original pointer value.  The result of any other such
pointer conversion is unspecified.

</BLOCKQUOTE>

<P>(Note: this resolution depends on that of <A HREF="
     cwg_defects.html#573">issue 573</A>.)</P>

<BR><BR><HR><A NAME="1086"></A><H4>1086.
  
<TT>const_cast</TT> to rvalue reference to function type
</H4><B>Section: </B>5.2.11&#160; [expr.const.cast]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>2010-06-25<BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<P>5.2.11 [expr.const.cast] paragraph 1 refers to casting to an rvalue
reference to function type.  This was an accidental edit in the application
of the value categories and should be removed.</P>

<P><B>Proposed resolution (October, 2010):</B></P>

<P>Change 5.2.11 [expr.const.cast] paragraph 1 as follows:</P>

<BLOCKQUOTE>

If <TT>T</TT> is an lvalue reference <SPAN style="font-weight:bold;background-color:#A0FFA0">to object</SPAN> type <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or
an rvalue reference to function type</SPAN>, the result is an lvalue;
if <TT>T</TT> is an rvalue reference to object type, the result is an
xvalue; otherwise, the result is a prvalue and the lvalue-to-rvalue
(4.1 [conv.lval]), array-to-pointer (4.2 [conv.array]), and function-to-pointer (4.3 [conv.func])
standard conversions are performed on the expression <TT>v</TT>...

</BLOCKQUOTE>

<I>[Drafting note: with this change to the wording, an attempt to cast
a function lvalue to either an lvalue or rvalue reference will be
ill-formed because the function-to-pointer conversion will be applied
to the operand and the resulting operand base type will be
incompatible with the target base type.]</I>

<BR><BR><HR><A NAME="1121"></A><H4>1121.
  
Unnecessary ambiguity error in formation of pointer to member
</H4><B>Section: </B>5.3.1&#160; [expr.unary.op]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US33">N3092 comment
  US&#160;33<BR></A>

<P>The resolution of <A HREF="
     cwg_defects.html#983">issue 983</A> restored
an error, inadvertently removed by the resolution of
<A HREF="
     cwg_defects.html#39">issue 39</A>, for the formation of a member
of an ambiguous base class.  For example:</P>

<PRE>
    struct B { int i; };
    struct I1: B { };
    struct I2: B { };
    struct D: I1, I2 { };
    int B::* pm = &amp;D::i;    // Originally and again ambiguous
</PRE>

<P>This error is not necessary, because the result of taking the
address of a member of an ambiguous base class is a pointer to
a member of that class; an actual ambiguity would occur only if
that pointer to a base class member is converted to a pointer to
a member of the derived class.  (See <A HREF="
     cwg_closed.html#203">issue 203</A>,
which suggests changing the result of taking the address of a
member to reflect the naming class of the member instead of the
class of which it is directly a member; if that change were made,
the ambiguity error would be needed.)</P>

<P>The resolution of <A HREF="
     cwg_defects.html#983">issue 983</A> should
be reverted.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<OL><LI><P>Change 5.3.1 [expr.unary.op] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

...If the operand is a <I>qualified-id</I> naming a non-static member
<TT>m</TT> of some class <TT>C</TT> with type <TT>T</TT>, the result
has type &#8220;pointer to member of class <TT>C</TT> of type
<TT>T</TT> and is a prvalue designating <TT>C::m</TT><SPAN style="text-decoration:line-through;background-color:#FFA0A0">; the
program is ill formed if C is an ambiguous base (10.2) of the class
designated by the nested-name-specifier of the
qualified-id</SPAN>. Otherwise...

</BLOCKQUOTE>

<LI><P>Change 10.2 [class.member.lookup] paragraph 13 as follows:</P></LI>

<BLOCKQUOTE>

[<I>Note:</I> Even if the result of name lookup is unambiguous, use of
a name found in multiple subobjects might still be ambiguous
(4.11 [conv.mem], 5.2.5 [expr.ref],
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">5.3.1 [expr.unary.op],</SPAN> 11.2 [class.access.base]). &#8212;<I>end note</I>]...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1122"></A><H4>1122.
  
Circular definition of <TT>std::size_t</TT>
</H4><B>Section: </B>5.3.3&#160; [expr.sizeof]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>GB
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#GB24">N3092 comment
  GB&#160;24<BR></A>

<P>The return type of the <TT>sizeof</TT> operator is
defined as being of type <TT>std::size_t</TT>, defined in
library clause 18.2 [support.types]. This, in turn,
says that <TT>size_t</TT> is defined in the C standard,
which in turn says that <TT>size_t</TT> is defined as the
type of the result of the <TT>sizeof</TT> operator!</P>

<P>The C definition of <TT>sizeof</TT> returns an
implementation-defined unsigned integer type, recommended
not to have &#8220;an integer conversion rank greater than
<TT>signed long int</TT>, unless the implementation supports
objects large enough to make this necessary.&#8221;</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<P>Add the following three paragraphs after 18.2 [support.types]
paragraph 4:</P>

<BLOCKQUOTE>

<P>The type <TT>ptrdiff_t</TT> is an implementation-defined signed
integer type that can hold the difference of two subscripts in an
array object, as described in 5.7 [expr.add].</P>

<P>The type <TT>size_t</TT> is an implementation-defined unsigned
integer type that is large enough to contain the size in bytes of any
object.</P>

<P>[<I>Note:</I> It is recommended that implementations choose types
for <TT>ptrdiff_t</TT> and <TT>size_t</TT> whose integer conversion
ranks (4.13 [conv.rank]) are no greater than that of <TT>signed
long int</TT> unless a larger size is necessary to contain all the possible
values. &#8212;<I>end note</I>] </P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1061"></A><H4>1061.
  
Negative array bounds in a <I>new-expression</I>
</H4><B>Section: </B>5.3.4&#160; [expr.new]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Sean Hunt
 &#160;&#160;&#160;

 <B>Date: </B>2010-03-23<BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<P>Recent changes have added the requirement (5.3.4 [expr.new]
paragraph 7),</P>

<BLOCKQUOTE>

If the value of that <I>expression</I> is such that the size of
the allocated object would exceed the implementation-defined
limit, no storage is obtained and the <I>new-expression</I>
terminates by throwing an exception of a type that would match a
handler (15.3 [except.handle]) of type
<TT>std::bad_array_new_length</TT> (18.6.2.3 [new.badlength]).

</BLOCKQUOTE>

<P>Given this checking, is there any current reason for the statement
in the preceding paragraph,</P>

<BLOCKQUOTE>

If the value of the expression is negative, the behavior is undefined.

</BLOCKQUOTE>

<P>Presumably for most negative expressions on most platforms, a
negative value would result in a too-large request anyway, and
even if not the check could easily be expanded to look explicitly
for a negative value in addition to a too-large request.</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<OL><LI><P>Change 5.3.4 [expr.new] paragraphs 6 and 7 as
follows:</P></LI>

<BLOCKQUOTE>

<P>...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">If the value of the expression is negative, the behavior is
undefined.</SPAN>  [<I>Example:</I> given the definition <TT>int n = 42</TT>,
<TT>new float[n][5]</TT> is well-formed (because <TT>n</TT> is the
<I>expression</I> of a <I>noptr-new-declarator</I>), but <TT>new
float[5][n]</TT> is ill-formed (because <TT>n</TT> is not a constant
expression).  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">If <TT>n</TT> is negative, the effect of <TT>new
float[n][5]</TT> is undefined.</SPAN> &#8212;<I>end example</I>]</P>

<P>When the value of the <I>expression</I> in a
<I>noptr-new-declarator</I> is zero, the allocation function is called
to allocate an array with no elements. If the value of that
<I>expression</I> is <SPAN style="font-weight:bold;background-color:#A0FFA0">less than zero or</SPAN> such that the size
of the allocated object would exceed the implementation-defined limit,
no storage is obtained and the <I>new-expression</I> terminates by
throwing an exception of a type that would match a handler
(15.3 [except.handle]) of type <TT>std::bad_array_new_length</TT>
(18.6.2.3 [new.badlength]).</P>

</BLOCKQUOTE>

<LI><P>Change 18.6.2.3 [new.badlength] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

The class <TT>bad_array_new_length</TT> defines the type of objects
thrown as exceptions by the implementation to report an attempt to
allocate an array of size <SPAN style="font-weight:bold;background-color:#A0FFA0">less than zero or</SPAN> greater than an
implementation-defined limit (5.3.4 [expr.new]).

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1037"></A><H4>1037.
  
Requirements for operands of <I>delete-expression</I>s and deallocation functions
</H4><B>Section: </B>5.3.5&#160; [expr.delete]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2010-03-01<BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<P>According to 5.3.5 [expr.delete] paragraph 2,</P>

<BLOCKQUOTE>

...in the first alternative (<I>delete object</I>), the value of
the operand of <TT>delete</TT> shall be a pointer to a non-array
object or a pointer to a subobject (1.8 [intro.object])
representing a base class of such an object (Clause 10 [class.derived]).  If not, the behavior is undefined.  In the second
alternative (<I>delete array</I>), the value of the operand of
<TT>delete</TT> shall be the pointer value which resulted from a
previous array <I>new-expression</I>.<SUP>79</SUP> If not, the
behavior is undefined.

</BLOCKQUOTE>

<P>The second part of this specification makes it clear that an array
object being deleted must have been allocated via <TT>new</TT>.
However, the first part, for the non-array object, completely omits
this vital requirement, requiring only that it not be an array.</P>

<P>The corresponding requirement for an argument to a deallocation
function is found in 3.7.4.2 [basic.stc.dynamic.deallocation] paragraph 3:</P>

<BLOCKQUOTE>

...the value supplied to <TT>operator delete(void*)</TT> in the
standard library shall be one of the values returned by a
previous invocation of either <TT>operator new(std::size_t)</TT>
or <TT>operator new(std::size_t, const std::nothrow_t&amp;)</TT>
in the standard library, and the value supplied to <TT>operator
delete[](void*)</TT> in the standard library shall be one of the
values returned by a previous invocation of either <TT>operator
new[](std::size_t)</TT> or <TT>operator new[](std::size_t, const
std::nothrow_t&amp;)</TT> in the standard library.

</BLOCKQUOTE>

<P>This correctly states the required provenance of the pointer,
but it does so using &#8220;shall,&#8221; which is inappropriate
for a runtime requirement.  This wording should be recast in terms
of undefined behavior if the requirement is not met.</P>

<P><B>Proposed resolution (October, 2010):</B></P>

<OL><LI><P>Change 5.3.5 [expr.delete] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

If the operand has a class type, the operand is converted to a
pointer type by calling the above-mentioned conversion function,
and the converted operand is used in place of the original
operand for the remainder of this section.  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">In either
alternative, the value of the operand of <TT>delete</TT> may be a
null pointer value.  If it is not a null pointer value, in</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">In</SPAN> the first alternative (<I>delete object</I>), the
value of the operand of <TT>delete</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">shall</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">may</SPAN> be <SPAN style="font-weight:bold;background-color:#A0FFA0">a null pointer value,</SPAN> a pointer to
a non-array object <SPAN style="font-weight:bold;background-color:#A0FFA0">created by a previous
<I>new-expression,</I></SPAN> or a pointer to a subobject (1.8 [intro.object]) representing a base class of such an object (Clause
10 [class.derived]).  If not, the behavior is undefined.  In the
second alternative (<I>delete array</I>), the value of the operand of
<TT>delete</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">shall</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">may</SPAN> be <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">a null pointer value or a</SPAN> pointer value <SPAN style="text-decoration:line-through;background-color:#FFA0A0">which</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">that</SPAN> resulted from a previous array
<I>new-expression</I>.<SUP>79</SUP> If not, the behavior is
undefined. [<I>Note:</I> this means that the syntax of the
<I>delete-expression</I> must match the type of the object
allocated by <SPAN style="text-decoration:line-through;background-color:#FFA0A0">new</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>new</TT></SPAN>, not the
syntax of the <I>new-expression</I>. &#8212;<I>end note</I>]...

</BLOCKQUOTE>

<LI><P>Change 3.7.4.2 [basic.stc.dynamic.deallocation] paragraph 3 as
follows:</P></LI>

<BLOCKQUOTE>

...Otherwise, <SPAN style="font-weight:bold;background-color:#A0FFA0">the behavior is undefined if</SPAN> the value
supplied to <TT>operator delete(void*)</TT> in the standard
library <SPAN style="text-decoration:line-through;background-color:#FFA0A0">shall be</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">is not</SPAN> one of the values
returned by a previous invocation of either <TT>operator
new(std::size_t)</TT> or <TT>operator new(std::size_t, const
std::nothrow_t&amp;)</TT> in the standard library, and <SPAN style="font-weight:bold;background-color:#A0FFA0">the
behavior is undefined if</SPAN> the value supplied to <TT>operator
delete[](void*)</TT> in the standard library <SPAN style="text-decoration:line-through;background-color:#FFA0A0">shall be</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">is not</SPAN> one of the values returned by a previous
invocation of either <TT>operator new[](std::size_t)</TT> or
<TT>operator new[](std::size_t, const std::nothrow_t&amp;)</TT>
in the standard library.

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1123"></A><H4>1123.
  
Destructors should be <TT>noexcept</TT> by default
</H4><B>Section: </B>5.3.7&#160; [expr.unary.noexcept]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>FI
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting as paper N3204.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#FI17">N3092 comment
  FI&#160;17<BR></A>

<P>Destructors should by default be noexcept. Such a rule
should be obeyed even for cases where a destructor is
defaulted. Then a throwing destructor would need to be
declared <TT>noexcept(false)</TT>, and the resulting code
breakage is acceptable.</P>

<P><B>Notes from the August, 2010 meeting:</B></P>

<P>CWG agreed with the suggested direction.</P>

<P>(Duplicate of <A HREF="
     cwg_defects.html#1147">issue 1147</A>.)</P>

<BR><BR><HR><A NAME="1091"></A><H4>1091.
  
Inconsistent use of the term &#8220;object expression&#8221;
</H4><B>Section: </B>5.5&#160; [expr.mptr.oper]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Tom Plum
 &#160;&#160;&#160;

 <B>Date: </B>2010-07-10<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

<P>The description of class member access expressions in
5.2.5 [expr.ref] paragraph 2 defines the terms
&#8220;object expression&#8221; and &#8220;pointer
expression:&#8221;</P>

<BLOCKQUOTE>

For the first option (dot) the type of the first expression
(the <I>object expression</I>) shall be &#8220;class object&#8221;
(of a complete type). For the second option (arrow) the type
of the first expression (the <I>pointer expression</I>) shall be
&#8220;pointer to class object&#8221; (of a complete type).

</BLOCKQUOTE>

<P>(Note in passing that the phrase &#8220;class
object&#8221; seems very odd when describing a type.)  The
rest of that section is based on the equivalence of the
expression <TT>E1-&gt;E2</TT> to <TT>(*(E1)).E2</TT> and
thus is phrased only in terms of &#8220;object
expression.&#8221; This terminology appears to have been
misapplied in other parts of the Standard, using the term
&#8220;object expression&#8221; to refer both to class types
and pointers to class types.  The most egregious of these is
5.5 [expr.mptr.oper] paragraph 4, describing the
operands of a pointer-to-member expression:</P>

<BLOCKQUOTE>

The first operand is called the <I>object expression</I>.
If the dynamic type of the object expression does not
contain the member to which the pointer refers, the behavior
is undefined.

</BLOCKQUOTE>

<P>The dynamic type of the first operand in the
<TT>-&gt;*</TT> case is a pointer type, not a class type, so
it cannot &#8220;contain the member to which the pointer
refers.&#8221;  Another example is 3.4.5 [basic.lookup.classref],
describing the lookup in a class member access expression.  The
first paragraph uses the term consistently with its use in
5.2.5 [expr.ref], but paragraph 2 reads:</P>

<BLOCKQUOTE>

If the <I>id-expression</I> in a class member access
(5.2.5 [expr.ref]) is an <I>unqualified-id</I>, and the
type of the object expression is of a class type <TT>C</TT>, the
<I>unqualified-id</I> is looked up in the scope of class
<TT>C</TT>. If the type of the object expression is of
pointer to scalar type, the <I>unqualified-id</I> is looked
up in the context of the complete <I>postfix-expression</I>.

</BLOCKQUOTE>

<P>Paragraph 7 gets it right:</P>

<BLOCKQUOTE>

...in the context of the class of the object expression
(or the class pointed to by the pointer expression).

</BLOCKQUOTE>

<P>Another misapplication of the term occurs in 5.2.2 [expr.call]
paragraph 1:</P>

<BLOCKQUOTE>

...the call is as a member of the object pointed to or
referred to by the object expression (5.2.5 [expr.ref], 5.5 [expr.mptr.oper])... its final
overrider (10.3 [class.virtual]) in the dynamic type of
the object expression is called.  [<I>Note:</I> the dynamic
type is the type of the object pointed or referred to by the
current value of the object expression...

</BLOCKQUOTE>

<P>Here again we have the idea that an object expression can
&#8220;point to&#8221; an object.</P>

<P>Another minor complication is that 5 [expr]
paragraph 7 has a separate definition for the (hyphenated) term
&#8220;object-expression:&#8221;</P>

<BLOCKQUOTE>

An expression designating an object is called an <I>object-expression</I>.

</BLOCKQUOTE>

<P>This term is used several times in the Standard,
apparently interchangeably with the non-hyphenated version
defined in 5.2.5 [expr.ref]; for example,
5.1.1 [expr.prim.general] paragraph 10 bullet 1
mentions</P>

<BLOCKQUOTE>

a class member access (5.2.5 [expr.ref]) in which
the object-expression refers to the member's class

</BLOCKQUOTE>

<P>using the term defined in 5 [expr] paragraph 7 but
linking it with 5.2.5 [expr.ref].</P>

<P>These uses of &#8220;object expression&#8221; and
&#8220;object-expression&#8221; need to be made consistent,
especially the reference in 5.5 [expr.mptr.oper] that
implies that the dynamic type of a pointer is that of the
complete object to which it points.</P>

<P><B>Proposed resolution (February, 2011):</B></P>

<OL><LI><P>Change 3.4.5 [basic.lookup.classref] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">If the type of the object expression is of pointer to scalar
type</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">For a pseudo-destructor call (5.2.4 [expr.pseudo])</SPAN>, the <I>unqualified-id</I> is looked up in the
context of the complete <I>postfix-expression</I>.

</BLOCKQUOTE>

<LI><P>Delete 5 [expr] paragraph 7</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">An expression designating an object is called an
object-expression.</SPAN>

</BLOCKQUOTE>

<LI><P>Change 5.1.1 [expr.prim.general] paragraph 10 as follows:</P></LI>

<BLOCKQUOTE>

<P>An <I>id-expression</I> that denotes a non-static data member or
non-static member function of a class can only be used:</P>

<UL><LI><P>as part of a class member access (5.2.5 [expr.ref]) in which the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">object-expression</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">object
expression</SPAN> refers to the member's class or a class derived from
that class, or</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 5.2.2 [expr.call] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...For a member function call, the postfix expression shall be an
implicit (9.3.1 [class.mfct.non-static], 9.4 [class.static]) or
explicit class member access (5.2.5 [expr.ref]) whose
<I>id-expression</I> is a function member name, or a pointer-to-member
expression (5.5 [expr.mptr.oper]) selecting a function member; the
call is as a member of the <SPAN style="font-weight:bold;background-color:#A0FFA0">class</SPAN> object <SPAN style="text-decoration:line-through;background-color:#FFA0A0">pointed to
or</SPAN> referred to by the object expression <SPAN style="text-decoration:line-through;background-color:#FFA0A0">(5.2.5 [expr.ref], 5.5 [expr.mptr.oper])</SPAN>... [<I>Note:</I> the
dynamic type is the type of the object <SPAN style="text-decoration:line-through;background-color:#FFA0A0">pointed or</SPAN> referred
to by the current value of the object expression. 12.7 [class.cdtor] describes the behavior of virtual function calls when the
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">object-expression</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">object expression</SPAN> refers to an
object under construction or destruction. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Change 5.2.5 [expr.ref] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

For the first option (dot) <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the type of</SPAN> the first expression <SPAN style="text-decoration:line-through;background-color:#FFA0A0">(the
<I>object expression</I>)</SPAN> shall <SPAN style="text-decoration:line-through;background-color:#FFA0A0">be &#8220;class
object&#8221; (of a complete type)</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">have complete class
type</SPAN>. For the second option (arrow) <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the type of</SPAN> the
first expression <SPAN style="text-decoration:line-through;background-color:#FFA0A0">(the <I>pointer expression</I>)</SPAN> shall
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">be &#8220;pointer to class object&#8221; (of a complete
type)</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">have pointer to complete class type. The expression
<TT>E1-&gt;E2</TT> is converted to the equivalent form
<TT>(*(E1)).E2</TT>; the remainder of 5.2.5 [expr.ref] will
address only the first option (dot) [<I>Footnote:</I> Note that
<TT>(*(E1))</TT> is an lvalue. &#8212;<I>end footnote</I>]</SPAN>.  In
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">these cases</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">either case</SPAN>, the
<I>id-expression</I> shall name a member of the class or of one of its
base classes...

</BLOCKQUOTE>

<LI><P>Change 5.2.5 [expr.ref] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">If <TT>E1</TT> has the type &#8220;pointer to class <TT>X</TT>,&#8221;
then the expression <TT>E1-&gt;E2</TT> is converted to the equivalent
form <TT>(*(E1)).E2</TT>; the remainder of 5.2.5 [expr.ref]
will address only the first option (dot)<SUP>66</SUP>.</SPAN> Abbreviating
<I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">object-expression</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">postfix-expression</SPAN>.id-expression</I>
as <TT>E1.E2</TT>, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">then the</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>E1</TT> is called the
<I>object expression</I>.  The</SPAN> type and value category of
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">this expression</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>E1.E2</TT></SPAN> are determined as
follows...

</BLOCKQUOTE>

<LI><P>Change 5.5 [expr.mptr.oper] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The result is an object or a function of the
type specified by the second operand.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">The expression
<TT>E1-&gt;*E2</TT> is converted into the equivalent form
<TT>(*(E1)).*E2.</TT></SPAN>

</BLOCKQUOTE>

<LI><P>Change 5.5 [expr.mptr.oper] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The first operand</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Abbreviating
<I>pm-expression</I><TT>.*</TT><I>cast-expression</I> as
<TT>E1.*E2</TT>, <TT>E1</TT></SPAN> is called the <I>object
expression</I>.  If the dynamic type of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the object
expression</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>E1</TT></SPAN> does not contain the member to
which <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the pointer</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>E2</TT></SPAN> refers, the
behavior is undefined.

</BLOCKQUOTE>

<LI><P>Change 5.5 [expr.mptr.oper] paragraph 6 as follows:</P></LI>

<BLOCKQUOTE>

...In a <TT>.*</TT> expression whose object expression is an rvalue,
the program is ill-formed if the second operand is a pointer to member
function with <I>ref-qualifier</I> <TT>&amp;</TT>.  In a
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>-&gt;*</TT> expression or in a</SPAN> <TT>.*</TT> expression
whose object expression is an lvalue, the program is ill-formed if the
second operand is a pointer to member function with
<I>ref-qualifier</I> <TT>&amp;&amp;</TT>.  The result of a <TT>.*</TT>
expression whose second operand is a pointer to a data member is of
the same value category (3.10 [basic.lval]) as its first
operand. The result of a <TT>.*</TT> expression whose second operand
is a pointer to a member function is a prvalue.  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The result of an
<TT>-&gt;*</TT> expression is an lvalue if its second operand is a
pointer to data member and a prvalue otherwise.</SPAN> If the second
operand is the null pointer to member value (4.11 [conv.mem]), the behavior is undefined.

</BLOCKQUOTE>

<LI><P>Change 9.4 [class.static] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

...A <TT>static</TT> member may be referred to using the class member
access syntax, in which case the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">object-expression</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">object expression</SPAN> is evaluated...

</BLOCKQUOTE>

<LI><P>Change 12.7 [class.cdtor] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

...If the virtual function call uses an explicit class member access
(5.2.5) and the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">object-expression</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">object
expression</SPAN> refers to the object under construction...

</BLOCKQUOTE>

<LI><P>Change 14.2 [temp.names] paragraph 4 as
follows:</P></LI>

<BLOCKQUOTE>

When the name of a member template specialization appears after
<TT>.</TT> or <TT>-&gt;</TT> in a <I>postfix-expression</I> or after a
<I>nested-name-specifier</I> in a <I>qualified-id</I>, and the object
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">or pointer</SPAN> expression of the <I>postfix-expression</I> or...

</BLOCKQUOTE>

</OL>

<P><I>[Note: although the current text of 3.4.5 [basic.lookup.classref]
paragraph 7 mentions the phrase &#8220;pointer expression,&#8221;
that wording will be replaced by <A HREF="
     cwg_defects.html#1111">issue 1111</A>
or <A HREF="
     cwg_defects.html#1220">issue 1220</A> and is thus not addressed
here.]</I></P>

<BR><BR><HR><A NAME="1060"></A><H4>1060.
  
Scoped enumerators in integral constant expressions
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jonathan Caves
 &#160;&#160;&#160;

 <B>Date: </B>2010-03-21<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3260.]</P>



<P>According to 5.19 [expr.const] paragraph 3,</P>

<BLOCKQUOTE>

A constant expression is an <I>integral constant expression</I>
if it is of integral or enumeration type. [<I>Note:</I> such
expressions may be used as array bounds (8.3.4 [dcl.array], 5.3.4 [expr.new]), as case expressions
(6.4.2 [stmt.switch]), as bit-field lengths (9.6 [class.bit]), as enumerator initializers (7.2 [dcl.enum]), and as integral or enumeration non-type template
arguments (14.3 [temp.arg]). &#8212;<I>end note</I>]

</BLOCKQUOTE>

<P>Although there is conceptually a conversion from enumeration
type to integral type involved in using an enumerator as an array
bound or bit-field length, the normative wording for those uses
does not explicitly mention it and simply requires an integral
constant expression.  Consequently, the current wording permits
uses like the following:</P>

<PRE>
    enum class E { e = 10; };
    struct S {
        int arr[E::e];
        int i: E::e;
    };
</PRE>

<P>This seems surprising.</P>

<P><B>Proposed resolution (February, 2011):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#1197">issue 1197</A>.</P>

<BR><BR><HR><A NAME="1098"></A><H4>1098.
  
Pointer conversions in constant expressions
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-01<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>One of the bullets in 5.19 [expr.const] paragraph 2 says,</P>

<UL><LI><P>a type conversion from a pointer or
pointer-to-member type to a literal type</P></LI></UL>

<P>This appears to prohibit conversion from one pointer type to
another; for example,</P>

<PRE>
    int x;
    constexpr void* p = &amp;x;   //<SPAN style="font-family:Times;font-style:italic"> ill-formed</SPAN>
</PRE>

<P>This seems excessive and probably unintentional.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change 5.19 [expr.const] paragraph 2 as follows:</P>

<UL><LI><P>a type conversion from a pointer <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or
pointer-to-member</SPAN> type to <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a literal</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an
integral</SPAN> type <SPAN style="text-decoration:line-through;background-color:#FFA0A0">[<I>Note:</I> a user-defined conversion
invokes a function &#8212;<I>end note</I>]</SPAN>;</P></LI></UL>

<P><I>[Note: the proposed resolution of <A HREF="
     cwg_defects.html#1188">issue 1188</A> edits this bullet in an incompatible fashion.]</I></P>

<BR><BR><HR><A NAME="1099"></A><H4>1099.
  
Infinite recursion in <TT>constexpr</TT> functions
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-01<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>



<P>It is not clear what happens when a program violates the limits on
constexpr function recursion in a context that does not require a
constant expression.  For example,</P>

<PRE>
  constexpr int f(int i) { return f(i); }
  const int i = f(1);   //<SPAN style="font-family:Times;font-style:italic"> error, undefined behavior, or dynamic initialization?</SPAN>
</PRE>

<P>(Presumably the &#8220;within its resource limits&#8221; caveat of
1.4 [intro.compliance] paragraph 2 would effectively result in
undefined behavior in a context that required a constant expression.)</P>

<P><B>Notes from the November, 2010 meeting:</B></P>

<P>The CWG was of mixed opinion as to whether an infinite recursion
in a constexpr function should be ill-formed or simply render an
expression non-constant.</P>

<P><B>Proposed resolution (January, 2011):</B></P>

<P>Add the following bullet in 5.19 [expr.const] paragraph 2:</P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">an invocation of a <TT>constexpr</TT> function or a
<TT>constexpr</TT> constructor that would exceed the
implementation-defined recursion limit (see annex B [implimits]);</SPAN></P></LI></UL>

<BR><BR><HR><A NAME="1100"></A><H4>1100.
  
<TT>constexpr</TT> conversion functions and non-type template arguments
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-01<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3260.]</P>



<P>According to 14.3.2 [temp.arg.nontype] paragraph 1, one of the
possibilities for a <I>template-argument</I> for a non-type,
non-template <I>template-parameter</I> is</P>

<UL><LI><P>an integral constant expression (including a
constant expression of literal class type that can be used
as an integral constant expression as described in
5.19 [expr.const])</P></LI></UL>

<P>However, the requirement for such a literal class type is
(5.19 [expr.const] paragraph 5):</P>

<BLOCKQUOTE>

...that class type shall have a single non-explicit conversion
function to an integral or enumeration type and that
conversion function shall be constexpr.

</BLOCKQUOTE>

<P>Note that this normative requirement for a single
conversion function is contradicted by the example in that
paragraph, which reads in significant part,</P>

<PRE>
    struct A {
      constexpr A(int i) : val(i) { }
      constexpr operator int() { return val; }
      constexpr operator long() { return 43; }
    private:
      int val;
    };
    template&lt;int&gt; struct X { };
    constexpr A a = 42;
    X&lt;a&gt; x; //<SPAN style="font-family:Times;font-style:italic"> OK: unique conversion to </SPAN>int
</PRE>

<P><B>Proposed resolution (February, 2011):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#1197">issue 1197</A>.</P>

<BR><BR><HR><A NAME="1125"></A><H4>1125.
  
Unclear definition of &#8220;potential constant expression&#8221;
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>DE
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting as paper N3218.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#DE8">N3092 comment
  DE&#160;8<BR></A>

<P>In the definition of &#8220;potential constant
expression&#8221; in 5.19 [expr.const] paragraph 6,
it is unclear how &#8220;arbitrary&#8221; the substitution of the
function parameters is. Does it mean &#8220;there exists a value
for which the result is a constant expression&#8221; or does it
mean &#8220;for all possible values, the result needs to be a
constant expression?&#8221; Example:</P>

<PRE>
    constexpr int f(int x){ return x + 1; }
</PRE>

<P>is a constant expression under the first interpretation,
but not under the second (because overflow occurs for <TT>x
== INT_MAX</TT>, cf 5.19 [expr.const] paragraph 2
bullet 5). The answer also affects expressions such as:</P>

<PRE>
    constexpr int f2(bool v) { return v ? throw 0 : 0; }
    constexpr int f3(bool v) { return v &amp;&amp; (throw 0, 0); }
</PRE>

<P>See also <A HREF="
     cwg_defects.html#1129">issue 1129</A>.</P>

<BR><BR><HR><A NAME="1126"></A><H4>1126.
  
<TT>constexpr</TT> functions in <TT>const</TT> initializers
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>GB
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#GB25">N3092 comment
  GB&#160;25<BR></A>

<P>It does not appear to be clearly enough stated that the example</P>

<PRE>
    constexpr int f() { return 42 + 84; }
    const int sz = f();
    int a[sz];
</PRE>

<P>is equivalent to</P>

<PRE>
    const int sz = 42 + 84;
    int a[sz];
</PRE>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change 5.19 [expr.const] paragraph 1 as follows:</P>

<BLOCKQUOTE>

Certain contexts require expressions that satisfy additional
requirements as detailed in this sub-clause<SPAN style="font-weight:bold;background-color:#A0FFA0">; other
contexts have different semantics depending on whether or
not an expression satisfies these
requirements</SPAN>. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">Such expressions</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">Expressions that satisfy these requirements</SPAN> are
called <I>constant expressions</I>. [<I>Note:</I>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Those</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Constant</SPAN> expressions can be
evaluated during translation. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1127"></A><H4>1127.
  
Overload resolution in <TT>constexpr</TT> functions
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>GB
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting as paper N3218.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#GB26">N3092 comment
  GB&#160;26<BR></A>

<P>It is not clear how overload resolution is performed inside the
body of a <TT>constexpr</TT> function.  In particular, if the
function is invoked with parameters such that an expression
evaluates to an integral 0, does that make the expression eligible
for the null pointer conversion and thus potentially select a
different overloaded function than in invocations in which the
expression has a non-zero value?  (Suggested answer: no.)</P>

<BR><BR><HR><A NAME="1188"></A><H4>1188.
  
Type punning in constant expressions
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-31<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>The status of the following example is not clear:</P>

<PRE>
    union U { float f; unsigned long u; };

    constexpr U u1 = { 1.0 };
    constexpr unsigned long u2 = u1.u;
</PRE>

<P>This might be ill-formed because the aliasing causes undefined
behavior, which should make the expression not a constant expression.
However, a similar example using a permitted aliasing would
presumably be acceptable:</P>

<PRE>
    union U {
        unsigned char c[sizeof(double)];
        double d;
    };
    constexpr U c1u = { 0x12, 0x34 /* etc. */ };
    constexpr double c1 = c1u.d;
</PRE>

<P>One suggestion was that unions should not be considered literal
types, but some in the ensuing discussion deemed that excessive.  That
also would not address similar examples using
<TT>reinterpret_cast</TT>, which is currently also permitted in
constant expressions.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change 5.19 [expr.const] paragraph 2 as follows:</P>

<UL><LI><P>an lvalue-to-rvalue conversion...</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">an lvalue-to-rvalue conversion (4.1 [conv.lval])
that is applied to a glvalue that refers to a non-active member of a
union or a subobject thereof;</SPAN></P></LI>

<LI><P>...</P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">a type conversion from a pointer or pointer-to-member type to a
literal type [<I>Note:</I> a user-defined conversion invokes a function
&#8212;<I>end note</I>]</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">a <TT>reinterpret_cast</TT>
(5.2.10 [expr.reinterpret.cast])</SPAN>;</P></LI>

</UL>

<P><I>[Note: the proposed resolution of <A HREF="
     cwg_defects.html#1098">issue 1098</A>
edits this bullet in an incompatible fashion.]</I></P>

<BR><BR><HR><A NAME="1193"></A><H4>1193.
  
Use of address-constant pointers in constant expressions
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2010-09-02<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>



<P>It's not clear whether the current rules for constant expressions
allow indirect calls of constexpr functions and constexpr member
functions; for example,</P>

<PRE>
    constexpr bool is_negative(int x) { return x &lt; 0; }
    constexpr bool check(int x, bool (*p)(int)) { return p(x); }
    static_assert(check(-2, is_negative), "Error");
</PRE>

<P>If this is to be permitted, there does not seem to be a reason to
prohibit equality comparison of pointers to functions or pointers to
objects of static storage duration -- these can be tracked as is
already done for non-type template parameters.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change 5.19 [expr.const] paragraph 2 bullet 19 as follows:</P>

<UL><LI><P>a relational (5.9 [expr.rel]) or equality
(5.10 [expr.eq]) operator where <SPAN style="text-decoration:line-through;background-color:#FFA0A0">at least one of the
operands is a pointer</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">the result is
unspecified</SPAN>;</P></LI></UL>

<BR><BR><HR><A NAME="1197"></A><H4>1197.
  
Constexpr arrays
</H4><B>Section: </B>5.19&#160; [expr.const]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-09-08<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3260.]</P>



<P>The requirement in 5.19 [expr.const] that a constant
expression cannot contain</P>

<UL><LI><P>an array-to-pointer conversion (4.2 [conv.array])
that is applied to a glvalue that does not designate an object with
static storage duration</P></LI></UL>

<P>effectively eliminates the use of automatic constexpr arrays such
as</P>

<PRE>
    void f() {
       constexpr int ar[] = { 1, 2 };
       constexpr int i = ar[1];
    }
</PRE>

<P>There does not seem to be a problem with this kind of usage.</P>

<P><B>Proposed resolution (February, 2011):</B></P>

<P>The proposed resolution will be submitted as a separate document.</P>

<BR><BR><HR><A NAME="1054"></A><H4>1054.
  
Lvalue-to-rvalue conversions in expression statements
</H4><B>Section: </B>6.2&#160; [stmt.expr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Hans Boehm
 &#160;&#160;&#160;

 <B>Date: </B>2010-03-16<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

<P>C and C++ differ in the treatment of an expression statement, in
particular with regard to whether a volatile lvalue is fetched.  For
example,</P>

<PRE>
    volatile int x;
    void f() {
        x;    // Fetches x in C, not in C++
    }
</PRE>

<P>The reason C++ is different in this regard is principally due to
the fact that an assignment expression is an lvalue in C++ but not
in C.  If the lvalue-to-rvalue conversion were applied to expression
statements, a statement like</P>

<PRE>
    x = 5;
</PRE>

<P>would write to x and then immediately read it.</P>

<P>It is not clear that the current approach to dealing with the
difference in assignment expressions is the only or best approach;
it might be possible to avoid the unwanted fetch on the result of
an assignment statement without giving up the fetch for a variable
appearing by itself in an expression statement.</P>

<P><B>Proposed resolution (January, 2011):</B></P>

<OL><LI><P>Add a new paragraph after 5 [expr] paragraph
10:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">In some contexts, an expression only appears for its
side-effects. Such an expression is called a <I>discarded-value
expression</I>. The expression is evaluated and its value is
discarded. The array-to-pointer (4.2 [conv.array]) and
function-to-pointer (4.3 [conv.func]) standard conversions
are not applied. The lvalue-to-rvalue conversion (4.1 [conv.lval]) is applied only if the expression is an lvalue of
volatile-qualified type and it has one of the following
forms:</SPAN></P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0"><I>id-expression</I> (5.1.1 [expr.prim.general]),</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">subscripting (5.2.1 [expr.sub]),</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">class member access (5.2.5 [expr.ref]),</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">indirection (5.3.1 [expr.unary.op]),</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">pointer-to-member operation (5.5 [expr.mptr.oper]),</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">conditional expression (5.16 [expr.cond]) where both
the second and the third operand are one of the above, or</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">comma expression (5.18 [expr.comma]) where the right
operand is one of the above.</SPAN></P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 5.2.9 [expr.static.cast] paragraph 6 as follows:</P></LI>

<BLOCKQUOTE>

Any expression can be explicitly converted to type <I>cv</I>
<TT>void</TT><SPAN style="font-weight:bold;background-color:#A0FFA0">, in which case it becomes a discarded-value
expression (Clause 5 [expr])</SPAN>.  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The expression
value is discarded.</SPAN> [<I>Note:</I> however, if the value is in a
temporary object (12.2 [class.temporary]), the destructor for that
object is not executed until the usual time, and the value of the
object is preserved for the purpose of executing the destructor.
&#8212;<I>end note</I>] <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The lvalue-to-rvalue (4.1 [conv.lval]), array-to-pointer (4.2 [conv.array]), and
function-to-pointer (4.3 [conv.func]) standard conversions
are not applied to the expression.</SPAN>

</BLOCKQUOTE>

<LI><P>Change 5.18 [expr.comma] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...A pair of expressions separated by a comma is evaluated
left-to-right<SPAN style="font-weight:bold;background-color:#A0FFA0">;</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">and the value of</SPAN> the left
expression is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">discarded</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">a discarded-value expression
(Clause 5 [expr])</SPAN>.<SUP>83</SUP> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The
lvalue-to-rvalue (4.1 [conv.lval]), array-to-pointer
(4.2 [conv.array]), and function-to-pointer (4.3 [conv.func]) standard conversions are not applied to the left
expression.</SPAN> Every value computation...

</BLOCKQUOTE>

<LI><P>Change 6.2 [stmt.expr] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...The expression is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">evaluated and its value is discarded</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">a discarded-value expression (clause 5 [expr])</SPAN>. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The lvalue-to-rvalue (4.1 [conv.lval]),
array-to-pointer (4.2 [conv.array]), and function-to-pointer
(4.3 [conv.func]) standard conversions are not applied to the
expression.</SPAN>  All side effects...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="948"></A><H4>948.
  
<TT>constexpr</TT> in <I>condition</I>s
</H4><B>Section: </B>6.4&#160; [stmt.select]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Gabriel dos Reis
 &#160;&#160;&#160;

 <B>Date: </B>2 August, 2009<BR>


<P>[Voted into WP at August, 21010 meeting.]</P>



<P>The grammar for <I>condition</I> in 6.4 [stmt.select]
paragraph 1 does not allow for the <TT>constexpr</TT> specifier.
This was not intended by the original proposal.</P>

<P><B>Proposed resolution (March, 2010):</B></P>

<OL><LI><P>Change the definition of <I>condition</I> in
6.4 [stmt.select] paragraph 1 as follows:</P></LI>

<UL><I>condition:</I>
<UL><I>expression</I></UL>
<UL><I>attribute-specifier<SUB>opt</SUB> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">type</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">decl</SPAN>-specifier-seq declarator</I> <TT>=</TT> <I>initializer-clause</I></UL>
<UL><I>attribute-specifier<SUB>opt</SUB> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">type</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">decl</SPAN>-specifier-seq declarator braced-init-list</I></UL>
</UL>

<LI><P>Insert the following text as a new paragraph at the end of
6.4 [stmt.select]:</P></LI>

<BLOCKQUOTE>

<SPAN style="font-weight:bold;background-color:#A0FFA0">In the <I>decl-specifier-seq</I> of a <I>condition</I>, each
<I>decl-specifier</I> shall be either a <I>type-specifier</I> or
<TT>constexpr</TT>.</SPAN>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1204"></A><H4>1204.
  
Specifiers in a <I>for-range-declaration</I>
</H4><B>Section: </B>6.5&#160; [stmt.iter]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-10-01<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>It seems unfortunate that the beginning of a C-style <TT>for</TT>
loop can look like</P>

<UL><TT>for (</TT> <I>attribute-specifier<SUB>opt</SUB> decl-specifier-seq<SUB>opt</SUB> declarator</I></UL>

<P>whereas the beginning of a range-based <TT>for</TT> loop looks like</P>

<UL><TT>for (</TT> <I>attribute-specifier<SUB>opt</SUB> type-specifier-seq<SUB>opt</SUB> declarator</I></UL>

<P>So that we don't know what constraints we are trying to apply to
the specifiers until we see, or don't see, a <TT>:</TT>.  The
inconsistency between <I>decl-specifier-seq</I> and
<I>type-specifier-seq</I> seems gratuitous and inconvenient.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<OL><LI><P>Change the grammar 6.5 [stmt.iter] paragraph 1 as
follows:</P></LI>

<UL><I>for-range-declaration:</I>
<UL><I>attribute-specifier<SUB>opt</SUB> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">type-specifier-seq</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">decl-specifier-seq</SPAN> declarator</I></UL>

</UL>

<LI><P>Add the following as a new paragraph at the end of 6.5.4 [stmt.ranged]:</P></LI>

<BLOCKQUOTE>

<SPAN style="font-weight:bold;background-color:#A0FFA0">The the <I>decl-specifier-seq</I> of a <I>for-range-declaration</I>,
each <I>decl-specifier</I> shall be either a <I>type-specifier</I> or
<TT>constexpr</TT>.</SPAN>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="864"></A><H4>864.
  
<I>braced-init-list</I> in the range-based <TT>for</TT> statement
</H4><B>Section: </B>6.5.4&#160; [stmt.ranged]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>James Widman
 &#160;&#160;&#160;

 <B>Date: </B>7 April, 2009<BR>


<P>[Voted into WP at August, 21010 meeting.]</P>



<P>The intent is that the range-based <TT>for</TT> statement should
be able to be used with a <I>braced-init-list</I> as the range over
which to iterate.  However, this does not work grammatically: a
<I>braced-init-list</I> is not an <I>expression</I>, as required by
the syntax in 6.5.4 [stmt.ranged] paragraph 1:</P>

<UL><TT>for (</TT> <I>for-range-declaration</I><TT> : </TT> <I>expression</I><TT> ) </TT><I>statement</I></UL>

<P>Even if this were resolved, the &#8220;equivalent to&#8221; code
is not correct.  It contains the declaration,</P>

<UL><TT>auto &amp;&amp; __range = ( </TT><I>expression</I><TT> );</TT></UL>

<P>This has a similar problem, in that 7.1.6.4 [dcl.spec.auto]
paragraph 3 requires that the <I>initializer</I> have one of the forms</P>

<UL>
<TT>= </TT><I>assignment-expression</I><BR>
<TT>( </TT><I>assignment-expression</I><TT> )</TT>
</UL>

<P>which does not allow for a <I>braced-initializer-list</I>.  In
addition, although not allowed by the grammar, 7.1.6.4 [dcl.spec.auto]
paragraph 6 treats the <I>braced-init-list</I> specially, in order for
the type deduction to work correctly:</P>

<BLOCKQUOTE>

Obtain <TT>P</TT> from <TT>T</TT> by replacing the occurrences of
<TT>auto </TT>with either a new invented type template parameter
<TT>U</TT> or, if the initializer is a <I>braced-init-list</I>
(8.5.4 [dcl.init.list]), with
<TT>std::initializer_list&lt;U&gt;</TT>.

</BLOCKQUOTE>

<P>The problem here is that a parenthesized initializer, as in the
code expansion of the range-based <TT>for</TT> statement, is not
a <I>braced-init-list</I>.</P>

<P><B>Proposed resolution (June, 2010):</B></P>

<OL><LI><P>Change 6.5 [stmt.iter] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<P>Iteration statements specify looping.</P>

<UL><I>iteration-statement:</I>
<UL><TT>while (</TT> <I>condition</I> <TT>)</TT> <I>statement</I></UL>
<UL><TT>do</TT> <I>statement</I> <TT>while (</TT> <I>expression</I> <TT>) ;</TT></UL>
<UL><TT>for (</TT> <I>for-init-statement condition<SUB>opt</SUB></I> <TT>;</TT> <I>expression<SUB>opt</SUB></I> <TT>)</TT> <I>statement</I></UL>
<UL><TT>for (</TT> <I>for-range-declaration</I> <TT>:</TT> <I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">expression</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">for-range-initializer</SPAN></I> <TT>)</TT> <I>statement</I></UL>
</UL><BR>

<UL><I>for-init-statement:</I>
<UL><I>expression-statement</I></UL>
<UL><I>simple-declaration</I></UL>
</UL><BR>

<UL><I>for-range-declaration:</I>
<UL><I>type-specifier-seq attribute-specifier<SUB>opt</SUB> declarator</I></UL>
</UL><BR>

<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><I>for-range-initializer:</I></SPAN>
<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><I>expression</I></SPAN></UL>
<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><I>braced-init-list</I></SPAN></UL>
</UL>

<P>[<I>Note:</I> a <I>for-init-statement</I> ends with a semicolon.
&#8212;<I>end note</I>]</P>

</BLOCKQUOTE>

<LI><P>Change 6.5.4 [stmt.ranged] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">The</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">For a</SPAN> range-based <TT>for</TT> statement
<SPAN style="font-weight:bold;background-color:#A0FFA0">of the form</SPAN></P>

<UL><TT>for (</TT> <I>for-range-declaration</I> <TT>:</TT> <I>expression</I> <TT>)</TT> <I>statement</I></UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">let <I>range-init</I> be equivalent to the <I>expression</I>
surrounded by parentheses:</SPAN></P>

<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>(</TT> <I>expression</I> <TT>)</TT></SPAN></UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Footnote:</I> this ensures that a top-level comma
operator cannot be reinterpreted as a delimiter between
<I>init-declarator</I>s in the declaration of
<TT>__range</TT>. &#8212;<I>end footnote</I>] and for a
range-based <TT>for</TT> statement of the form</SPAN></P>

<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>for (</TT> <I>for-range-declaration</I> <TT>:</TT> <I>braced-init-list</I> <TT>)</TT> <I>statement</I></SPAN></UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">let <I>range-init</I> be equivalent to the
<I>braced-init-list</I>.  In each case, a range-based
<TT>for</TT> statement</SPAN> is equivalent to</P>

<PRE>
  {
    auto &amp;&amp; __range = <SPAN style="text-decoration:line-through;background-color:#FFA0A0">( <SPAN style="font-family:Times;font-style:italic">expression</SPAN> )</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><SPAN style="font-family:Times;font-style:italic">range-init</SPAN></SPAN>;
    for ( auto __begin = <SPAN style="font-family:Times;font-style:italic">begin-expr</SPAN>,
    ...
</PRE>

</BLOCKQUOTE>

<P><B>Note to editor:</B></P>

<P>The formatting in the preceding change for
<I>range-init</I> follows that of the existing text for
<I>begin-expr</I> and <I>end-expr</I>.  However, CWG is concerned
that this style makes all of these elements look too much like
grammar nonterminals and asks that the editor consider some other
formatting convention.</P>

</OL>

<BR><BR><HR><A NAME="1018"></A><H4>1018.
  
Ambiguity between <I>simple-declaration</I> and <I>attribute-declaration</I>
</H4><B>Section: </B>7&#160; [dcl.dcl]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>2010-01-04<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>The grammar for declarations includes the following two nonterminals:</P>

<UL><I>simple-declaration:</I>
<UL><I>attribute-specifier<SUB>opt</SUB> decl-specifier-seq<SUB>opt</SUB> init-declarator-list<SUB>opt</SUB></I> <TT>;</TT></UL>
</UL>

<UL><I>attribute-declaration:</I>
<UL><I>attribute-specifier</I> <TT>;</TT></UL>
</UL>

<P>An <I>attribute-specifier</I> followed by a semicolon could thus
be parsed as either an <I>attribute-declaration</I> or as a
<I>simple-declaration</I> that omits the optional
<I>decl-specifier-seq</I> and <I>init-declarator-list</I>, and the
current wording does not disambiguate the two.  (There doesn't seem
to be a compelling need for <I>attribute-declaration</I> as a
separate nonterminal, given that <I>simple-declaration</I> can
accommodate that form.)</P>

<P><B>Proposed resolution (February, 2011):</B></P>

<P>Change 7 [dcl.dcl] paragraph 1 as follows:</P>

<UL><I>simple-declaration:</I>
<UL><I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">attribute-specifier-seq<SUB>opt</SUB></SPAN> decl-specifier-seq<SUB>opt</SUB> init-declarator-list<SUB>opt</SUB></I> <TT>;</TT><BR>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>attribute-specifier-seq decl-specifier-seq init-declarator-list</I> <TT>;</TT></SPAN>
</UL>

</UL>

<BLOCKQUOTE>

...The <SPAN style="text-decoration:line-through;background-color:#FFA0A0">optional</SPAN> <I>attribute-specifier-seq</I> in a
<I>simple-declaration</I> appertains to each of the entities declared
by the <I>declarator</I>s<SPAN style="text-decoration:line-through;background-color:#FFA0A0">; it shall not appear if the optional</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">of the</SPAN> <I>init-declarator-list</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">is omitted</SPAN>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1042"></A><H4>1042.
  
Attributes in <I>alias-declaration</I>s
</H4><B>Section: </B>7&#160; [dcl.dcl]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>2010-03-04<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>The grammar for an <I>alias-declaration</I> does not have a
place for an <I>attribute-specifier</I>, although a
<TT>typedef</TT> declaration does.  Since an
<I>alias-declaration</I> is essentially a different syntactic
form of a <TT>typedef</TT> declaration (7.1.3 [dcl.typedef] paragraph 2), this could be surprising.</P>

<P><B>Proposed resolution (February, 2011):</B></P>

<OL><LI><P>Change the grammar in 7 [dcl.dcl] paragraph 1 as
follows:</P></LI>

<UL><I>alias-declaration:</I>
<UL><TT>using</TT> <I>identifier <SPAN style="font-weight:bold;background-color:#A0FFA0">attribute-specifier-seq<SUB>opt</SUB></SPAN></I> <TT>=</TT> <I>type-id</I> <TT>;</TT></UL>
</UL>

<LI><P>Change 7.1.3 [dcl.typedef] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

A <I>typedef-name</I> can also be introduced by an
<I>alias-declaration</I>. The <I>identifier</I> following the
<TT>using</TT> keyword becomes a <I>typedef-name</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">and the
optional <I>attribute-specifier-seq</I> following the <I>identifier</I>
appertains to that <I>typedef-name</I></SPAN>.  It has the same
semantics...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1128"></A><H4>1128.
  
<I>attribute-specifier</I>s in <I>decl-specifier-seq</I>s
</H4><B>Section: </B>7.1&#160; [dcl.spec]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US39">N3092 comment
  US&#160;39<BR></A>

<P>The current wording of 7.1 [dcl.spec] paragraph 1 says,</P>

<BLOCKQUOTE>

The optional <I>attribute-specifier</I> in a <I>decl-specifier-seq</I>
appertains to the type determined by the <I>decl-specifier-seq</I>
(8.3 [dcl.meaning]).

</BLOCKQUOTE>

<P>However, <I>decl-specifier-seq</I> is a recursive production.  The
intent is that the <I>attribute-specifier</I> appertains to the type
determined by the top-level <I>decl-specifier-seq</I>, but this makes
it sound as if it appertains to the one that directly contains the
<I>attribute-specifier</I>.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change 7.1 [dcl.spec] paragraph 1 as follows:</P>

<BLOCKQUOTE>

The optional <I>attribute-specifier</I> in a
<I>decl-specifier-seq</I> appertains to the type determined
by the <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>decl-specifier-seq</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">preceding
<I>decl-specifier</I>s</SPAN> (8.3 [dcl.meaning]).

</BLOCKQUOTE>

<BR><BR><HR><A NAME="407"></A><H4>407.
  
Named class with associated typedef: two names or one?
</H4><B>Section: </B>7.1.3&#160; [dcl.typedef]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Clark Nelson
 &#160;&#160;&#160;

 <B>Date: </B>31 March 2003<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

<P>Here's an example:</P>
<PRE>
  typedef struct S { ... } S;
  void fs(S *x) { ... }
</PRE>
<P>The big question is, to what declaration does the reference to identifier S
actually refer? Is it the S that's declared as a typedef name, or the S
that's declared as a class name (or in C terms, as a struct tag)? (In either
case, there's clearly only one type to which it could refer, since a typedef
declaration does not introduce a new type. But the debugger apparently cares
about more than just the identity of the type.)</P>

<P>Here's a classical, closely related example:</P>
<PRE>
  struct stat { ... };
  int stat();
  ... stat( ... ) ...
</PRE>
<P>Does the identifier stat refer to the class or the function? Obviously, in
C, you can't refer to the struct tag without using the struct keyword,
because it is in a different name space, so the reference must be to the
function. In C++, the reference is also to the function, but for a
completely different reason.</P>

<P>Now in C, typedef names and function names are in the same name space, so
the natural extrapolation would be that, in the first example, S refers to
the typedef declaration, as it would in C. But C++ is not C. For the
purposes of this discussion, there are two important differences between C
and C++</P>

<P>The first difference is that, in C++, typedef names and class names are not
in separate name spaces. On the other hand, according to section
3.3.10 [basic.scope.hiding] (Name hiding), paragraph 2:</P>
<BLOCKQUOTE>
A class name (9.1) or enumeration name (7.2) can be hidden by <SPAN style="font-weight:bold;background-color:#A0FFA0">the name of
an object, function, or enumerator</SPAN> declared in the same scope. If a class
or enumeration name and an object, function, or enumerator are declared in
the same scope (in any order) with the same name, the class or enumeration
name is hidden wherever the object, function, or enumerator name is
visible.
</BLOCKQUOTE>

<P>Please consider carefully the phrase I have highlighted, and the fact that a
typedef name is not the name of an object, function or enumerator. As a
result, this example:</P>
<PRE>
  struct stat { ... };
  typedef int stat;
</PRE>
<P>Which would be perfectly legal in C, is disallowed in C++, both implicitly
(see the above quote) and explicitly (see section
7.1.3 [dcl.typedef] (The typedef
specifier), paragraph 3):</P>
<BLOCKQUOTE>
In a given scope, a typedef specifier shall not be used to redefine the
name of any type declared in that scope to refer to a different type.
Similarly, in a given scope, a class or enumeration shall not be declared
with the same name as a typedef-name that is declared in that scope and
refers to a type other than the class or enumeration itself.
</BLOCKQUOTE>

<P>From which we can conclude that in C++ typedef names do not hide class names
declared in the same scope. If they did, the above example would be legal.</P>

<P>The second difference is that, in C++, a typedef name that refers to a class
is a class-name; see 7.1.3 [dcl.typedef] paragraph 4:</P>
<BLOCKQUOTE>
A typedef-name that names a class is a class-name(9.1). If a typedef-name
is used following the class-key in an elaborated-type-specifier (7.1.5.3) or
in the class-head of a class declaration (9), or is used as the identifier
in the declarator for a constructor or destructor declaration (12.1, 12.4),
the program is ill-formed.
</BLOCKQUOTE>

<P>This implies, for instance, that a typedef-name referring to a class can be
used in a nested-name-specifier (i.e. before :: in a qualified name) or
following ~ to refer to a destructor. Note that using a typedef-name as a
class-name in an elaborated-type-specifier is not allowed. For example:</P>
<PRE>
  struct X { };
  typedef struct X X2;
  X x; // legal
  X2 x2; // legal
  struct X sx; // legal
  struct X2 sx2; // illegal
</PRE>

<P>The final relevant piece of the standard is
7.1.3 [dcl.typedef] paragraph 2:</P>
<BLOCKQUOTE>
In a given scope, a typedef specifier can be used to redefine the name of
any type declared in that scope to refer to the type to which it already
refers.
</BLOCKQUOTE>

<P>This of course is what allows the original example, to which let us now
return:</P>
<PRE>
  typedef struct S { ... } S;
  void fs(S *x) { ... }
</PRE>
<P>The question, again is, to which declaration of S does the reference
actually refer? In C, it would clearly be to the second, since the first
would be accessible only by using the struct keyword. In C++, if typedef
names hid class names declared in the same scope, the answer would be the
same. But we've already seen that typedef names do not hide class names
declared in the same scope.</P>

<P>So to which declaration does the reference to S refer? The answer is that it
doesn't matter. The second declaration of S, which appears to be a
declaration of a typedef name, is actually a declaration of a class name
(7.1.3 [dcl.typedef] paragraph 4), and as such is simply a
redeclaration. Consider the following example:</P>
<PRE>
  typedef int I, I;
  extern int x, x;
  void f(), f();
</PRE>
<P>To which declaration would a reference to I, x or f refer? It doesn't
matter, because the second declaration of each is really just a
redeclaration of the thing declared in the first declaration. So to save
time, effort and complexity, the second declaration of each doesn't add any
entry to the compiler's symbol table.</P>

<P><B>Note (March, 2005):</B></P>



<P><U>Matt Austern</U>: Is this legal?</P>

<PRE>
    struct A { };
    typedef struct A A;
    struct A* p;
</PRE>

<P>Am I right in reading the standard [to say that this is
ill-formed]?  On the one hand it's a nice uniform rule.  On the other
hand, it seems likely to confuse users.  Most people are probably used
to thinking that 'typedef struct A A' is a null operation, and, if
this code really is illegal, it would seem to be a gratuitous C/C++
incompatibility.</P>

<P><U>Mike Miller</U>: I think you're right.  7.1.3 [dcl.typedef] paragraph 1:</P>

<BLOCKQUOTE>

A name declared with the <TT>typedef</TT> specifier becomes a
<I>typedef-name</I>.

</BLOCKQUOTE>

<P>7.1.3 [dcl.typedef] paragraph 2:</P>

<BLOCKQUOTE>

In a given non-class scope, a <TT>typedef</TT> specifier can be used
to redefine the name of any type declared in that scope
to refer to the type to which it already refers.

</BLOCKQUOTE>

<P>After the <TT>typedef</TT> declaration in the example, the name
<TT>X</TT> has been &#8220;redefined&#8221; &#8212; it is no longer
just a <I>class-name</I>, it has been &#8220;redefined&#8221; to be a
<I>typedef-name</I> (that, by virtue of the fact that it refers to a
class type, is also a <I>class-name</I>).</P>

<P><U>John Spicer</U>: In C, and originally in C++, an
<I>elaborated-type-specifier</I> did not consider typedef names, so
&#8220;<TT>struct X* x</TT>&#8221; would find the class and not the
typedef.</P>

<P>When C++ was changed to make typedefs visible to
<I>elaborated-type-specifier</I> lookups, I believe this issue was
overlooked and inadvertantly made ill-formed.
</P>

<P>I suspect we need add text saying that if a given scope contains
both a class/enum and a typedef, that an elaborated type specifier
lookup finds the class/enum.
</P>

<P><U>Mike Miller</U>: I'm a little uncomfortable with this approach.
The model we have for declaring a typedef in the same scope as a
class/enum is redefinition, not hiding (like the &#8220;<TT>struct
stat</TT>&#8221; hack).  This approach seems to assume that the
typedef hides the class/enum, which can then be found by an
<I>elaborated-type-specifier</I>, just as if it were hidden by a
variable, function, or enumerator.
</P>

<P>Also, this approach reduces but doesn't eliminate the
incompatibility with C.  For example:
</P>

<PRE>
    struct S { };
    {
        typedef struct S S;
        struct S* p;        // still ill-formed
    }
</PRE>

<P>My preference would be for something following the basic principle
that declaring a <I>typedef-name</I> <TT>T</TT> in a scope where
<TT>T</TT> already names the type designated by the typedef should
have no effect on whether an <I>elaborated-type-specifier</I> in that
or a nested scope is well-formed or not.  Another way of saying that
is that a <I>typedef-name</I> that designates a same-named class or
enumeration in the same or a containing scope is transparent with
respect to <I>elaborated-type-specifier</I>s.</P>

<P><U>John Spicer</U>: This strikes me as being a rather complicated
solution. When we made the change to make typedefs visible to
<I>elaborated-type-specifier</I>s we did so knowing it would make some
C cases ill-formed, so this does not bother me.  We've lived with the
C incompatibility for many years now, so I don't personally feel a
need to undo it.  I also don't like the fact that you have to
essentially do the old-style <I>elaborated-type-specifier</I> lookup
to check the result of the lookup that found the typedef.
</P>

<P>I continue to prefer the direction I described earlier where if a
given scope contains both a class/enum and a typedef, that an
<I>elaborated-type-specifier</I> lookup finds the class/enum.
</P>

<P><B>Notes from the April, 2005 meeting:</B></P>

<P>The CWG agreed with John Spicer's approach, i.e., permitting
a <I>typedef-name</I> to be used in an
<I>elaborated-type-specifier</I> only if it is declared in the same
scope as the class or enumeration it names.</P>

<P><B>Proposed resolution (January, 2011):</B></P>

<P>Add the following new paragraph after 7.1.3 [dcl.typedef]
paragraph 4:</P>

<BLOCKQUOTE>

<P>If a <TT>typedef</TT> specifier is used to redefine in a given
scope an entity that can be referenced using an
<I>elaborated-type-specifier</I>, the entity can continue to be
referenced by an <I>elaborated-type-specifier</I> or as an enumeration or
class name in an enumeration or class definition respectively.
[<I>Example:</I></P>

<PRE>
  struct S;
  typedef struct S S;
  int main() {
    struct S* p; //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
  }
  struct S {};   //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="700"></A><H4>700.
  
Constexpr member functions of class templates
</H4><B>Section: </B>7.1.5&#160; [dcl.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jens Maurer
 &#160;&#160;&#160;

 <B>Date: </B>27 June, 2008<BR>


<P>[Voted into WP at August, 21010 meeting.]</P>



<P>7.1.5 [dcl.constexpr] paragraph 5 applies only to &#8220;the
instantiated template specialization of a constexpr function
template;&#8221; it should presumably apply to non-template member
functions of a class template, as well.</P>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>This question is more involved than it might appear.  For example,
a constexpr member function is implicitly <TT>const</TT>; if the
<TT>constexpr</TT> specifier is ignored, does that make the member
function non-const?  Also, should this provision apply only to
dependent expressions in the function?  Should it be an error if no
constexpr function can be instantiated from the template, along the
lines of the permission given in 14.6 [temp.res] paragraph 8
for an implementation to diagnose a template definition from which no
valid specialization can be instantiated?</P>

<P><B>Notes from the July, 2009 meeting:</B></P>

<P>The consensus of the CWG was that an &#8220;ignored&#8221;
<TT>constexpr</TT> specifier in this case simply means that the
specialization is not constexpr, not that it is not const.  The
CWG also decided not to address the question of non-dependent
expressions that render a function template specialization
non-constexpr, leaving it to quality of implementation whether
a (warning) diagnostic is issued in such cases.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 7.1.5 [dcl.constexpr] paragraph 5 as follows:</P>

<BLOCKQUOTE>

If the instantiated template specialization of a constexpr
function template <SPAN style="font-weight:bold;background-color:#A0FFA0">or member function of a class
template</SPAN> would fail to satisfy the requirements for a
constexpr function or constexpr constructor, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the
<TT>constexpr</TT> specifier is ignored</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">that
specialization is not a constexpr function or constexpr
constructor</SPAN>. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> if the function is a
member function it will still be <TT>const</TT> as described
below. Implementations are encouraged to issue a warning if a
function was rendered not constexpr by a non-dependent
construct. &#8212;<I>end note</I>]</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="837"></A><H4>837.
  
Constexpr functions and <TT>return</TT> <I>braced-init-list</I>
</H4><B>Section: </B>7.1.5&#160; [dcl.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>11 March, 2009<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3268.]</P>

<P>The body of a constexpr function is required by
7.1.5 [dcl.constexpr] paragraph 3 to be of the form</P>

<UL><TT>{ return</TT> <I>expression</I><TT>; }</TT></UL>

<P>However, there does not seem to be any good reason for prohibiting
the alternate return syntax involving a <I>braced-init-list</I>.
The restriction should be removed.</P>

<P><B>Proposed resolution (March, 2010):</B></P>

<OL><LI><P>Change 6.6.3 [stmt.return] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

A return statement <SPAN style="text-decoration:line-through;background-color:#FFA0A0">without an expression</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">with neither an
<I>expression</I> nor a <I>braced-init-list</I></SPAN> can be used only
in functions that do not return a value...

</BLOCKQUOTE>

<LI><P>Change 7.1.5 [dcl.constexpr] paragraph 3 bullets 4
and 5 as follows:</P></LI>

<UL><LI><P>its <I>function-body</I> shall be a <I>compound-statement</I>
of the form</P>

<UL><TT>{ return </TT><I>expression</I><TT> ; }</TT></UL>

<P>where <I>expression</I> is a potential constant expression
(5.19)<SPAN style="font-weight:bold;background-color:#A0FFA0">, or</SPAN></P>

<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>{ return </TT><I>braced-init-list</I><TT> ; }</TT></SPAN></UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">where every <I>assignment-expression</I> that is an
<I>initializer-clause</I> appearing directly or indirectly within the
<I>braced-init-list</I> is a potential constant expression</SPAN></P>

</LI>

<LI><P>every <SPAN style="font-weight:bold;background-color:#A0FFA0">constructor call and</SPAN> implicit conversion
used in <SPAN style="text-decoration:line-through;background-color:#FFA0A0">converting <I>expression</I> to the function return
type</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">initializing the return value</SPAN>
(<SPAN style="font-weight:bold;background-color:#A0FFA0">6.6.3 [stmt.return],</SPAN> 8.5 [dcl.init])
shall be one of those allowed in a constant expression
(5.19 [expr.const]).</P></LI>

</UL>

</OL>

<P><B>Notes from the March, 2010 meeting:</B></P>

<P>The new wording added in 5.19 [expr.const] in support
of reference parameters for constexpr functions should also be
considered to see whether additional changes are needed.</P>

<BR><BR><HR><A NAME="860"></A><H4>860.
  
Explicit qualification of constexpr member functions
</H4><B>Section: </B>7.1.5&#160; [dcl.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>6 April, 2009<BR>


<P>[Voted into WP at August, 21010 meeting.]</P>



<P>7.1.5 [dcl.constexpr] paragraph 6 says,</P>

<BLOCKQUOTE>

A constexpr specifier for a non-static member function that is not a
constructor declares that member function to be const (9.3.1 [class.mfct.non-static]).

</BLOCKQUOTE>

<P>Is a <TT>const</TT> qualifier on such a member function redundant
or ill-formed?</P>

<P><B>Notes from the July, 2009 meeting:</B></P>

<P>The CWG agreed that a <TT>const</TT> qualifier on a constexpr
member function is simply redundant and not an error.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 7.1.5 [dcl.constexpr] paragraph 6 as follows:</P>

<BLOCKQUOTE>

A <TT>constexpr</TT> specifier for a non-static member function
that is not a constructor declares that member function to be
<TT>const</TT> (9.3.1 [class.mfct.non-static]). [<I>Note:</I> the
<TT>constexpr</TT> specifier has no other effect on the function
type. &#8212;<I>end note</I>] <SPAN style="font-weight:bold;background-color:#A0FFA0">The keyword <TT>const</TT> is
ignored if it appears in the <I>cv-qualifier-seq</I> of the
function declarator of the declaration of such a member
function.</SPAN> The class of which that function is a member
shall be a literal type (3.9 [basic.types]). [<I>Example:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="892"></A><H4>892.
  
Missing requirements for constexpr constructors
</H4><B>Section: </B>7.1.5&#160; [dcl.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>8 May, 2009<BR>


<P>[Voted into WP at August, 21010 meeting.]</P>

<P>The rules for constexpr constructors are missing some necessary
requirements.  In particular, there is no requirement that a
<I>brace-or-equal-initializer</I> for a non-static data member be
a constant expression, and the requirement for constexpr constructors
for initializing non-static data members applies only to members
named in a <I>mem-initializer</I>, allowing a non-constexpr default
constructor to be invoked.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 7.1.5 [dcl.constexpr] paragraph 4 as follows:</P>

<BLOCKQUOTE>

<P>The definition of a constexpr constructor shall satisfy the
following constraints:</P>

<UL><LI><P>each of its parameter types shall be a literal type or a
reference to a literal type</P></LI>

<LI><P>its <I>function-body</I> shall not be a
<I>function-try-block</I></P></LI>

<LI><P>the <I>compound-statement</I> of its <I>function-body</I> shall
be empty</P></LI>

<LI><P>every non-static data member and base class sub-object shall be
initialized (12.6.2 [class.base.init])</P></LI>

<LI><P>every constructor involved in initializing non-static data
members and base class sub-objects <SPAN style="text-decoration:line-through;background-color:#FFA0A0">invoked by a
<I>mem-initializer</I></SPAN> shall be a constexpr
constructor<SPAN style="text-decoration:line-through;background-color:#FFA0A0">.</SPAN></P></LI>

<LI><P>every constructor argument and full-expression in a
<I>mem-initializer</I> shall be a potential constant
expression</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">every <I>assignment-expression</I> that is an
<I>initializer-clause</I> appearing directly or indirectly within a
<I>brace-or-equal-initializer</I> for a non-static data member that is
not named by a <I>mem-initializer-id</I> shall be a constant
expression</SPAN></P></LI>

<LI><P>every implicit conversion used in converting a constructor
argument to the corresponding parameter type and converting a
full-expression to the corresponding member type shall be one of those
allowed in a constant expression.</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="898"></A><H4>898.
  
Declarations in constexpr functions
</H4><B>Section: </B>7.1.5&#160; [dcl.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>9 May, 2009<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3268.]</P>

<P>According to 7.1.5 [dcl.constexpr] paragraph 3, no declarations
are permitted in the body of a constexpr function.  This seems overly
restrictive.  At least three kinds of declarations would seem to be
helpful in writing such functions: <TT>static_assert</TT>,
<TT>typedef</TT> and alias declarations, and local automatic variables
initialized with constant expressions.  (Similar considerations apply
to lambdas in which the <I>lambda-return-type-clause</I> is omitted.)</P>

<P><B>Rationale (July, 2009):</B></P>

<P>This suggestion needs a proposal and analysis by EWG before it can
be considered by CWG.</P>

<BR><BR><HR><A NAME="1129"></A><H4>1129.
  
Default <TT>nothrow</TT> for <TT>constexpr</TT> functions
</H4><B>Section: </B>7.1.5&#160; [dcl.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>GB
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#GB29">N3092 comment
  GB&#160;29<BR></A>

<P>A <TT>constexpr</TT> function is not permitted to return via an
exception. This should be recognised, and a function
declared <TT>constexpr</TT> without an explicit exception
specification should be treated as if declared
<TT>noexcept(true)</TT> rather than the usual
<TT>noexcept(false)</TT>. For a function template declared
<TT>constexpr</TT> without an explicit exception specification, it
should be considered <TT>noexcept(true)</TT> if and only if the
<TT>constexpr</TT> keyword is respected on a given
instantiation. </P>

<P>See also <A HREF="
     cwg_defects.html#1125">issue 1125</A>.</P>

<P><B>Notes from the August, 2010 meeting:</B></P>

<P>The premise is not correct: an exception is forbidden only when a
<TT>constexpr</TT> function is invoked in a context that requires
a constant expression. Used as an ordinary function, it can throw.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change 5.3.7 [expr.unary.noexcept] paragraph 3 bullet 1 as follows:</P>

<UL><LI>a potentially evaluated call<SUP>80</SUP> to a
function, member function, function pointer, or member
function pointer that does not have a non-throwing
<I>exception-specification</I> (15.4 [except.spec]),
<SPAN style="font-weight:bold;background-color:#A0FFA0">unless the call is a constant expression (5.19 [expr.const]),</SPAN></LI></UL>

<BR><BR><HR><A NAME="1186"></A><H4>1186.
  
Non-dependent <TT>constexpr</TT> violations in function templates
</H4><B>Section: </B>7.1.5&#160; [dcl.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-30<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>7.1.5 [dcl.constexpr] paragraph 5 says,</P>

<BLOCKQUOTE>

If the instantiated template specialization of a constexpr function
template or member function of a class template would fail to satisfy
the requirements for a constexpr function or constexpr constructor,
that specialization is not a constexpr function or constexpr
constructor.  [<I>Note:</I> if the function is a member function it
will still be <TT>const</TT> as described below.  Implementations are
encouraged to issue a warning if a function is rendered not constexpr
by a non-dependent construct. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<P>A non-dependent error in a function template renders it ill-formed
with no diagnostic required (14.6 [temp.res] paragraph 8).
A similar approach is being taken in the proposed resolution of
<A HREF="
     cwg_defects.html#1125">issue 1125</A> with respect to constexpr
functions.  It would be more consistent to treat constexpr function
templates in the same way, along the lines of</P>

<BLOCKQUOTE>

If no specialization of the template would be <TT>constexpr</TT>,
the program is ill-formed, no diagnostic required.

</BLOCKQUOTE>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change 7.1.5 [dcl.constexpr] paragraph 6 as follows:</P>

<BLOCKQUOTE>

If the instantiated template specialization of a constexpr function
template or member function of a class template would fail to satisfy
the requirements for a <TT>constexpr</TT> function or
<TT>constexpr</TT> constructor, that specialization is not a
<TT>constexpr</TT> function or <TT>constexpr</TT> constructor.
[<I>Note:</I> if the function is a member function it will still be
<TT>const</TT> as described below.  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">Implementations are
encouraged to issue a warning if a function is rendered not
<TT>constexpr</TT> by a non-dependent construct.</SPAN> &#8212;<I>end
note</I>] <SPAN style="font-weight:bold;background-color:#A0FFA0">If no specialization of the template would yield a
<TT>constexpr</TT> function or <TT>constexpr</TT> constructor, the
program is ill-formed; no diagnostic required.</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1194"></A><H4>1194.
  
Constexpr references
</H4><B>Section: </B>7.1.5&#160; [dcl.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2010-09-04<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3277.]</P>



<P>7.1.5 [dcl.constexpr] restricts the <TT>constexpr</TT>
specifier to object and function declarations.  Especially given
the support for reference types in constexpr functions, and
considering that constexpr pointer declarations are permitted,
there does not seem to be a good reason for excluding constexpr
references.</P>

<P>(See also <A HREF="
     cwg_defects.html#1195">issue 1195</A>.)</P>

<P><B>Proposed resolution (November. 2010):</B></P>

<OL><LI><P>Change 7.1.5 [dcl.constexpr] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

The constexpr specifier shall be applied only to the definition of
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">an object</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">a variable</SPAN>, the declaration of a
function...

</BLOCKQUOTE>

<LI><P>Change 7.1.5 [dcl.constexpr] paragraph 8 as follows:</P></LI>

<BLOCKQUOTE>

A <TT>constexpr</TT> specifier used in an object declaration declares
the object as <TT>const</TT>.  Such an object shall be initialized. If
it is initialized by a constructor call, the constructor shall be a
constexpr constructor and every argument to the constructor shall be a
constant expression.  Otherwise, <SPAN style="font-weight:bold;background-color:#A0FFA0">or if a <TT>constexpr</TT>
specifier is used in a reference declaration,</SPAN> every
full-expression that appears in its initializer shall be a constant
expression...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1195"></A><H4>1195.
  
References to non-literal types in constexpr functions
</H4><B>Section: </B>7.1.5&#160; [dcl.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2010-09-05<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3277.]</P>



<P>7.1.5 [dcl.constexpr] paragraph 3 is overly restrictive
in requiring that reference parameter and return types of a constexpr
function or constructor must refer to a literal type.
5.19 [expr.const] paragraph 2 already prevents any
problematic uses of lvalues of non-literal types, and it permits
use of pointers to non-literal types as address constants.  The
same should be permitted via reference parameters and return types
of constexpr functions.</P>

<P>(See also <A HREF="
     cwg_defects.html#1194">issue 1194</A>.)</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<OL><LI><P>Change 3.9 [basic.types] paragraph 10 as follows:</P></LI>

<BLOCKQUOTE>

<P>A type is a <I>literal type</I> if it is:</P>

<UL><LI><P>a scalar type; or</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">a reference type; or</SPAN></P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 7.1.5 [dcl.constexpr] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

<P>The definition of a constexpr function shall satisfy the following
constraints:</P>

<UL><LI><P>it shall not be virtual (10.3 [class.virtual])</P></LI>

<LI><P>its return type shall be a literal type <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or a reference to
literal type</SPAN></P></LI>

<LI><P>each of its parameter types shall be a literal type <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or a
reference to literal type</SPAN></P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 7.1.5 [dcl.constexpr] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

<P>The definition of a constexpr constructor shall satisfy the
following constraints:</P>

<UL><LI><P>each of its parameter types shall be a literal type <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or a
reference to literal type</SPAN>;</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1199"></A><H4>1199.
  
Deleted constexpr functions
</H4><B>Section: </B>7.1.5&#160; [dcl.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2010-09-17<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3277.]</P>



<P>The current requirements for constexpr functions do not permit a
deleted constexpr function because the definition does not consist of
a <I>compound-statement</I> containing just a <TT>return</TT>
statement.  However, it could be useful to allow this form in a
case where a single piece of code is used in multiple configurations,
in some of which the function is constexpr and others deleted;
having to update all declarations of the function to remove the
<TT>constexpr</TT> specifier is unnecessarily onerous.</P>

<P><B>Proposed resolution (January, 2011):</B></P>

<OL><LI><P>Change 7.1.5 [dcl.constexpr] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

<UL><LI><P>...</P></LI>

<LI><P>its <I>function-body</I> shall be <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>= delete</TT>
or</SPAN> a <I>compound-statement</I> of the form</P>

<PRE>
  { return <I>expression</I> ; }
</PRE>

</LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 7.1.5 [dcl.constexpr] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">The definition of a <TT>constexpr</TT> constructor</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">In the definition of a <TT>constexpr</TT> constructor, each of
the parameter types shall be a literal type or a reference to a
literal type.  In addition, either its <I>function-body</I> shall be
<TT>= delete</TT> or it</SPAN> shall satisfy the following
constraints:</P>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">each of its parameter types shall be a literal type or
a reference to literal type;</SPAN></P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1225"></A><H4>1225.
  
<TT>constexpr</TT> constructors and virtual bases
</H4><B>Section: </B>7.1.5&#160; [dcl.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-10-26<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>A class with a virtual base should not be allowed to have a
<TT>constexpr</TT> constructor.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Add the following bullet to the list in 7.1.5 [dcl.constexpr]
paragraph 4:</P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">the class shall not have virtual base
classes;</SPAN></P></LI></UL>

<BR><BR><HR><A NAME="1075"></A><H4>1075.
  
Grammar does not allow template alias in <I>type-name</I>
</H4><B>Section: </B>7.1.6.2&#160; [dcl.type.simple]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-06-06<BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>



<P>According to 14.2 [temp.names] paragraph 7,</P>

<BLOCKQUOTE>

A <I>template-id</I> that names a template alias specialization is a
<I>type-name</I>.

</BLOCKQUOTE>

<P>However, the grammar for <I>type-name</I> in 7.1.6.2 [dcl.type.simple]
does not include a production for <I>simple-template-id</I>.</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<P>Change the definition of <I>type-name</I> in 7.1.6.2 [dcl.type.simple]
paragraph 1 as follows:</P>

<UL><I>type-name:</I>
<UL><I>class-name</I></UL>
<UL><I>enum-name</I></UL>
<UL><I>typedef-name</I></UL>
<UL><I><SPAN style="font-weight:bold;background-color:#A0FFA0">simple-template-id</SPAN></I></UL>

</UL>

<BR><BR><HR><A NAME="1130"></A><H4>1130.
  
Function parameter type adjustments and <TT>decltype</TT>
</H4><B>Section: </B>7.1.6.2&#160; [dcl.type.simple]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US40">N3092 comment
  US&#160;40<BR></A>

<P>The description of <TT>decltype</TT> does not specify whether the
type of a parameter is the declared type or the type as
adjusted in 8.3.5 [dcl.fct] paragraph 5:</P>

<PRE>
    auto f(int a[])-&gt;decltype(a);     // ill-formed or int*?
    auto g(const int i)-&gt;decltype(i); // int or const int?
</PRE>

<P><U>Suggested resolution</U>: Clarify the wording to
indicate that the type of a parameter is after the array-
and function-to-pointer decay but before the removal of
cv-qualification.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change 8.3.5 [dcl.fct] paragraph 5 as follows:</P>

<BLOCKQUOTE>

...After producing the list of parameter types, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">several
transformations take place upon these types to determine the
function type.  Any</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">any top-level</SPAN>
<I>cv-qualifier</I><SPAN style="font-weight:bold;background-color:#A0FFA0">s</SPAN> modifying a parameter type
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">is</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">are</SPAN> deleted <SPAN style="font-weight:bold;background-color:#A0FFA0">when forming the
function type</SPAN>. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">[<I>Example:</I> the type
<TT>void(*)(const int)</TT> becomes <TT>void(*)(int)</TT>
&#8212;<I>end example</I>] Such
<I>cv-qualifier</I>s affect only the definition of the
parameter within the body of the function; they do not
affect the function type. If a
<I>storage-class-specifier</I> modifies a parameter type,
the specifier is deleted. [<I>Example:</I> <TT>register
char*</TT> becomes <TT>char*</TT> &#8212;<I>end example</I>]
Such <I>storage-class-specifier</I>s affect only the definition of
the parameter within the body of the function; they do not
affect the function type.</SPAN> The resulting list of transformed
parameter types and the presence or absence of the ellipsis
or a function parameter pack is the function's
<I>parameter-type-list</I>. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> This
transformation does not affect the types of the parameters.
For example, <TT>int(*)(const int p, decltype(p)*)</TT> and
<TT>int(*)(int, const int*)</TT> are identical types.
&#8212;<I>end note</I>]</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1212"></A><H4>1212.
  
Non-function-call xvalues and <TT>decltype</TT>
</H4><B>Section: </B>7.1.6.2&#160; [dcl.type.simple]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2010-10-21<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>Given</P>

<PRE>
    int&amp;&amp; f();
    int i;
</PRE>

<P>it is surprising that <TT>decltype(f())</TT> and
<TT>decltype(static_cast&lt;int&amp;&amp;&gt;(i))</TT> are not the
same type.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change 7.1.6.2 [dcl.type.simple] paragraph 4 as follows:</P>

<BLOCKQUOTE>

<P>The type denoted by <TT>decltype(e)</TT> is defined as follows:</P>

<UL><LI><P>if <TT>e</TT> is an unparenthesized <I>id-expression</I> or
a class member access (5.2.5 [expr.ref]),
<TT>decltype(e)</TT> is the type of the entity named by <TT>e</TT>.
If there is no such entity, or if <TT>e</TT> names a set of overloaded
functions, the program is ill-formed;</P></LI>

<LI><P>otherwise, if <TT>e</TT> is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a function call (5.2.2 [expr.call]) or an invocation of an overloaded operator (parentheses
around <TT>e</TT> are ignored), <TT>decltype(e)</TT> is the return
type of the statically chosen function</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an xvalue,
<TT>decltype(e)</TT> is <TT>T&amp;&amp;</TT>, where <TT>T</TT> is the
type of <TT>e</TT></SPAN>;</P></LI>

<LI><P>otherwise, if <TT>e</TT> is an lvalue, <TT>decltype(e)</TT> is
<TT>T&amp;</TT>, where <TT>T</TT> is the type of <TT>e</TT>;</P></LI>

<LI><P>otherwise, <TT>decltype(e)</TT> is the type of
<TT>e</TT>.</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1131"></A><H4>1131.
  
Template aliases in <I>elaborated-type-specifier</I>s
</H4><B>Section: </B>7.1.6.3&#160; [dcl.type.elab]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US41">N3092 comment
  US&#160;41<BR></A>

<P>The current wording disallows use of <I>typedef-name</I>s in
<I>elaborated-type-specifier</I>s. This prohibition should also
apply to template aliases:</P>

<PRE>
    struct A { };
    template&lt;typename T&gt; using X = A;
    struct X&lt;int&gt;* p2; // ill-formed
</PRE>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change 7.1.6.3 [dcl.type.elab] paragraph 2 as follows:</P>

<BLOCKQUOTE>

...If the <I>identifier</I> resolves to a
<I>typedef-name</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">or the <I>simple-template-id</I>
resolves to an alias template specialization</SPAN>, the
<I>elaborated-type-specifier</I>  is ill-formed. [<I>Note:</I>...

</BLOCKQUOTE>

<P><I>[Note: this wording assumes the change from &#8220;template
alias&#8221; to &#8220;alias template&#8221; requested by comment
FI 11 on FCD N3092.]</I></P>

<BR><BR><HR><A NAME="1022"></A><H4>1022.
  
Can an enumeration variable have values outside the values of the enumeration?
</H4><B>Section: </B>7.2&#160; [dcl.enum]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-01-22<BR><BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US31">N3092 comment
  US&#160;31<BR></A>



<P>According to 7.2 [dcl.enum] paragraph 10,</P>

<BLOCKQUOTE>

An expression of arithmetic or enumeration type can be converted
to an enumeration type explicitly.  The value is unchanged if it
is in the range of enumeration values of the enumeration type;
otherwise the resulting enumeration value is unspecified.

</BLOCKQUOTE>

<P>(There is similar wording in 5.2.9 [expr.static.cast].)
Does the phrase &#8220;resulting enumeration value&#8221; mean
that the result, although unspecified, must lie within the range
of enumeration values of the enumeration type?  Existing practice
seems to allow out-of-range values to be preserved if the
underlying type is large enough to represent the value.  This
freedom is important both for efficiency (to avoid having to mask
values while storing and/or fetching) and to prevent optimizers
from removing code that tests for out-of-range values.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#1094">issue 1094</A>.</P>

<BR><BR><HR><A NAME="1012"></A><H4>1012.
  
Undeprecating <TT>static</TT>
</H4><B>Section: </B>7.3.1.1&#160; [namespace.unnamed]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Ville Voutilainen
 &#160;&#160;&#160;

 <B>Date: </B>2009-12-09<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#FI6">N3092 comment
  FI&#160;6<BR></A>



<P>Although 7.3.1.1 [namespace.unnamed] states that the use of the
<TT>static</TT> keyword for declaring variables in namespace scope is
deprecated because the unnamed namespace provides a superior
alternative, it is unlikely that the feature will be removed at any
point in the foreseeable future, especially in light of C compatibility
concerns.  The Committee should consider removing the deprecation.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<OL><LI><P>Delete 7.3.1.1 [namespace.unnamed] paragraph 2:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The use of the <TT>static</TT> keyword is deprecated when declaring
variables in a namespace scope (see annex D [depr]); the
<I>unnamed-namespace</I> provides a superior alternative.</SPAN>

</BLOCKQUOTE>

<LI><P>Delete _N3225_.D.2 [depr.static]:</P></LI>

<BLOCKQUOTE>

<P><TABLE width="100%"><TR><TD><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><B>D.2 <TT>static</TT> keyword</B></SPAN></TD><TD align="right"><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><B>[depr.static]</B></SPAN></TD></TR></TABLE></P>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">The use of the <TT>static</TT> keyword is deprecated when
declaring objects in namespace scope (see 3.3.6 [basic.scope.namespace]).</SPAN></P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="341"></A><H4>341.
  
<TT>extern "C"</TT> namespace member function versus global variable
</H4><B>Section: </B>7.5&#160; [dcl.link]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>1 Mar 2002<BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>



<P>Here's an interesting case:
<PRE>
  int f;
  namespace N {
    extern "C" void f () {}
  }
</PRE>
As far as I can tell, this is not precluded by the ODR section
(3.2 [basic.def.odr])
or the extern "C" section (7.5 [dcl.link]).
However, I believe many compilers
do not do name mangling on variables and (more-or-less by definition)
on extern "C" functions.  That means the variable and the function
in the above end up having the same name at link time.  EDG's front
end, g++, and the Sun compiler all get essentially the same error,
which is a compile-time assembler-level error because of the
duplicate symbols (in other words, they fail to check for this, and the
assembler complains).  MSVC++ 7 links the program without error,
though I'm not sure how it is interpreted.</P>

<P>Do we intend for this case to be valid?  If not, is it a compile time
error (required), or some sort of ODR violation (no diagnostic
required)?  If we do intend for it to be valid, are we forcing
many implementations to break binary compatibility by requiring
them to mangle variable names?</P>

<P>Personally, I favor a compile-time error, and an ODR prohibition on
such things in separate translation units.</P>

<P><B>Notes from the 4/02 meeting:</B></P>

<P>The working group agreed with the proposal.  We feel a diagnostic
should be required for declarations within one translation unit.
We also noted that if the variable in global scope in the above example
were declared static we would still expect an error.</P>

<P>Relevant sections in the
standard are 7.5 [dcl.link] paragraph 6 and
3.5 [basic.link] paragraph 9.  We feel that the definition
should be written such that the entities in conflict are not "the same
entity" but merely not allowed together.</P>

<P><B>Additional note (September, 2004)</B></P>

<P>This problem need not involve a conflict between a function
and a variable; it can also arise with two variable
declarations:</P>

<PRE>
    int x;
    namespace N {
        extern "C" int x;
    }
</PRE>

<P><B>Proposed resolution (March, 2008):</B></P>

<P>Change 7.5 [dcl.link] paragraph 6 as follows:</P>

<BLOCKQUOTE>

<P>At most one function with a particular name can have C
language linkage. Two declarations for a function with C language
linkage with the same function name (ignoring the namespace names
that qualify it) that appear in different namespace scopes refer
to the same function. Two declarations for an object with C
language linkage with the same name (ignoring the namespace names
that qualify it) that appear in different namespace scopes refer
to the same object. <SPAN style="font-weight:bold;background-color:#A0FFA0">A function or object with C linkage shall
not be declared with the same name (clause 3 [basic]) as an object or reference declared in global scope,
unless both declarations denote the same object; no diagnostic is
required if the declarations appear in different translation
units.</SPAN> [<I>Note:</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">because of the one definition rule
(3.2 [basic.def.odr]), only</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Only</SPAN> one definition
for a function or object with C linkage may appear in the program
<SPAN style="font-weight:bold;background-color:#A0FFA0">(see 3.2 [basic.def.odr])</SPAN>; that <SPAN style="text-decoration:line-through;background-color:#FFA0A0">is,</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">implies
that</SPAN> such a function or object must not be defined in more
than one namespace scope. For example,</P>

<PRE>
    <SPAN style="font-weight:bold;background-color:#A0FFA0">int x;</SPAN>
    namespace A {
      extern "C" int f();
      extern "C" int g() { return 1; }
      extern "C" int h();
      <SPAN style="font-weight:bold;background-color:#A0FFA0">extern "C" int x();               //<SPAN style="font-family:Times;font-style:italic"> ill-formed: same name as global-scope object </SPAN>x</SPAN>
    }

    namespace B {
      extern "C" int f();               //<SPAN style="font-family:Times;font-style:italic"> </SPAN>A::f<SPAN style="font-family:Times;font-style:italic"> and </SPAN>B::f<SPAN style="font-family:Times;font-style:italic"> refer</SPAN>
                                        //<SPAN style="font-family:Times;font-style:italic"> to the same function</SPAN>
      extern "C" int g() { return 1; }  //<SPAN style="font-family:Times;font-style:italic"> ill-formed, the function </SPAN>g
                                        //<SPAN style="font-family:Times;font-style:italic"> with C language linkage</SPAN>
                                        //<SPAN style="font-family:Times;font-style:italic"> has two definitions</SPAN>
    }

    int A::f() { return 98; }           //<SPAN style="font-family:Times;font-style:italic"> definition for the function </SPAN>f
                                        //<SPAN style="font-family:Times;font-style:italic"> with C language linkage</SPAN>
    extern "C" int h() { return 97; }
                                        //<SPAN style="font-family:Times;font-style:italic"> definition for the function </SPAN>h
                                        //<SPAN style="font-family:Times;font-style:italic"> with C language linkage</SPAN>
                                        //<SPAN style="font-family:Times;font-style:italic"> </SPAN>A::h<SPAN style="font-family:Times;font-style:italic"> and </SPAN>::h<SPAN style="font-family:Times;font-style:italic"> refer to the same function</SPAN>
</PRE>

<P>&#8212;<I>end note</I>]</P>

</BLOCKQUOTE>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>It should also be possible to declare references with C name
linkage (although the meaning the first sentence of 7.5 [dcl.link] paragraph 1 with respect to the meaning of such a
declaration is not clear), which would mean that the changed
wording should refer to declaring &#8220;the same entity&#8221;
instead of &#8220;the same object.&#8221; The formulation here
would probably benefit from the approach currently envisioned for
issues <A HREF="
     cwg_defects.html#570">570</A> and <A HREF="
     cwg_defects.html#633">633</A>, in which &#8220;variable&#8221; is defined as being
either an object or a reference.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 7.5 [dcl.link] paragraph 6 as follows:</P>

<BLOCKQUOTE>

<P>At most one function with a particular name can have C
language linkage. Two declarations for a function with C language
linkage with the same function name (ignoring the namespace names
that qualify it) that appear in different namespace scopes refer
to the same function.  Two declarations for an object <SPAN style="font-weight:bold;background-color:#A0FFA0">or
reference</SPAN> with C language linkage with the same name
(ignoring the namespace names that qualify it) that appear in
different namespace scopes refer to the same object <SPAN style="font-weight:bold;background-color:#A0FFA0">or
reference</SPAN>. <SPAN style="font-weight:bold;background-color:#A0FFA0">An entity with C language linkage shall not
be declared with the same name as an entity in global scope,
unless both declarations denote the same object or reference; no
diagnostic is required if the declarations appear in different
translation units.</SPAN> [<I>Note:</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">because of the one
definition rule (3.2 [basic.def.odr]), only</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">Only</SPAN> one definition for <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a function or
object</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an entity</SPAN> with C linkage may appear in
the program <SPAN style="font-weight:bold;background-color:#A0FFA0">(see 3.2 [basic.def.odr])</SPAN>; that
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">is,</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">implies that</SPAN> such <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a function or
object</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an entity</SPAN> must not be defined in more
than one namespace scope. <SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end note</I>]</SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">For example,</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  int x;</SPAN>
  namespace A {
    extern "C" int f();
    extern "C" int g() { return 1; }
    extern "C" int h();
<SPAN style="font-weight:bold;background-color:#A0FFA0">    extern "C" int x();               // <SPAN style="font-family:Times;font-style:italic">ill-formed: same name as global-scope object </SPAN>x</SPAN>
  }

  namespace B {
   extern "C" int f();                // A::f<SPAN style="font-family:Times;font-style:italic"> and </SPAN>B::f<SPAN style="font-family:Times;font-style:italic"> refer</SPAN>
                                      // <SPAN style="font-family:Times;font-style:italic">to the same function</SPAN>
   extern "C" int g() { return 1; }   // <SPAN style="font-family:Times;font-style:italic">ill-formed, the function </SPAN>g
                                      // <SPAN style="font-family:Times;font-style:italic">with C language linkage</SPAN>
                                      // <SPAN style="font-family:Times;font-style:italic">has two definitions</SPAN>
  }

  int A::f() { return 98; }           // <SPAN style="font-family:Times;font-style:italic">definition for the function </SPAN>f
                                      // <SPAN style="font-family:Times;font-style:italic">with C language linkage</SPAN>
  extern "C" int h() { return 97; }
                                      // <SPAN style="font-family:Times;font-style:italic">definition for the function </SPAN>h
                                      // <SPAN style="font-family:Times;font-style:italic">with C language linkage</SPAN>
                                      // A::h<SPAN style="font-family:Times;font-style:italic"> and </SPAN>::h<SPAN style="font-family:Times;font-style:italic"> refer to the same function</SPAN>
</PRE>

<P>&#8212;<I>end <SPAN style="text-decoration:line-through;background-color:#FFA0A0">note</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">example</SPAN></I>]</P>

</BLOCKQUOTE>

<P><B>Additional note (February, 2010):</B></P>

<P>The proposed wording above does not cover the case where two
different entities with C linkage are declared in different namespaces,
only the case where one of the entities is in global scope.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change 7.5 [dcl.link] paragraph 6 as follows:</P>

<BLOCKQUOTE>

<P>At most one function with a particular name can have C
language linkage. Two declarations for a function with C
language linkage with the same function name (ignoring the
namespace names that qualify it) that appear in different
namespace scopes refer to the same function.  Two
declarations for <SPAN style="text-decoration:line-through;background-color:#FFA0A0">an object</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">a variable</SPAN>
with C language linkage with the same name (ignoring the
namespace names that qualify it) that appear in different
namespace scopes refer to the same <SPAN style="text-decoration:line-through;background-color:#FFA0A0">object</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">variable</SPAN>. <SPAN style="font-weight:bold;background-color:#A0FFA0">An entity with C language linkage
shall not be declared with the same name as an entity in
global scope, unless both declarations denote the same
entity; no diagnostic is required if the declarations appear
in different translation units. A variable with C language
linkage shall not be declared with the same name as a
function with C language linkage (ignoring the namespace
names that qualify the respective names); no diagnostic is
required if the declarations appear in different translation
units.</SPAN> [<I>Note:</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">because of the one
definition rule (3.2 [basic.def.odr]), only</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">Only</SPAN> one definition for <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a function or
object</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an entity with a given name</SPAN> with C
<SPAN style="font-weight:bold;background-color:#A0FFA0">language</SPAN> linkage may appear in the program
<SPAN style="font-weight:bold;background-color:#A0FFA0">(see 3.2 [basic.def.odr])</SPAN>; that
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">is,</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">implies</SPAN> such <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a function or
object</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an entity</SPAN> must not be defined in
more than one namespace scope. <SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end
note</I>]</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">For example,</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  int x;</SPAN>
  namespace A {
    extern "C" int f();
    extern "C" int g() { return 1; }
    extern "C" int h();
<SPAN style="font-weight:bold;background-color:#A0FFA0">    extern "C" int x();               //<SPAN style="font-family:Times;font-style:italic"> ill-formed: same name as global-scope object </SPAN>x</SPAN>
  }

  namespace B {
    extern "C" int f();               //<SPAN style="font-family:Times;font-style:italic"> </SPAN>A::f<SPAN style="font-family:Times;font-style:italic"> and </SPAN>B::f<SPAN style="font-family:Times;font-style:italic"> refer</SPAN>
                                      //<SPAN style="font-family:Times;font-style:italic"> to the same function</SPAN>
    extern "C" int g() { return 1; }  //<SPAN style="font-family:Times;font-style:italic"> ill-formed, the function </SPAN>g
                                      //<SPAN style="font-family:Times;font-style:italic"> with C language linkage</SPAN>
                                      //<SPAN style="font-family:Times;font-style:italic"> has two definitions</SPAN>
  }

  int A::f() { return 98; }           //<SPAN style="font-family:Times;font-style:italic"><SPAN style="font-weight:bold;background-color:#A0FFA0"> </SPAN>definition for the function </SPAN>f
                                      //<SPAN style="font-family:Times;font-style:italic"> with C language linkage</SPAN>
  extern "C" int h() { return 97; }
                                      //<SPAN style="font-family:Times;font-style:italic"> definition for the function </SPAN>h
                                      //<SPAN style="font-family:Times;font-style:italic"> with C language linkage</SPAN>
                                      //<SPAN style="font-family:Times;font-style:italic"> </SPAN>A::h<SPAN style="font-family:Times;font-style:italic"> and </SPAN>::h<SPAN style="font-family:Times;font-style:italic"> refer to the same function</SPAN>
</PRE>

<P>&#8212;<I>end <SPAN style="text-decoration:line-through;background-color:#FFA0A0">note</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">example</SPAN></I>]</P>

</BLOCKQUOTE>

<P><I>[Note to editor: please consider reformatting the comments in the
example.]</I></P>

<BR><BR><HR><A NAME="1185"></A><H4>1185.
  
Misleading description of language linkage and member function types
</H4><B>Section: </B>7.5&#160; [dcl.link]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-29<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>The current wording of 7.5 [dcl.link] paragraph 4 is:</P>

<BLOCKQUOTE>

...A C language linkage is ignored for the names of class members and
the member function type of class member functions...

</BLOCKQUOTE>

<P>This has two problems.  First, it sounds as if a class member
function has a &#8220;member function type,&#8221; while in fact
the type of a class member function is an ordinary function type
(cf 9.2 [class.mem] paragraph 11).</P>

<P>Second, even if that problem is fixed, it is not accurate to
say that a C language linkage is &#8220;ignored&#8221; for the
type of a member function.  It does not affect the language
linkage of the type of the member function, but it does affect
the language linkage of any function declarators appearing in
the parameter and return types of the function and thus the
type of the function.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change 7.5 [dcl.link] paragraph 4 as follows:</P>

<BLOCKQUOTE>

...A C language linkage is ignored <SPAN style="text-decoration:line-through;background-color:#FFA0A0">for</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">in determining
the language linkage of</SPAN> the names of class members and the
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">member</SPAN> function type of class member functions...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="972"></A><H4>972.
  
Allowing multiple <I>attribute-specifier</I>s
</H4><B>Section: </B>7.6.1&#160; [dcl.attr.grammar]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>5 October, 2009<BR>


<P>[Voted into the WP at the November, 2010 meeting as part of paper
N3190.</P>

<P>The current syntax requires that multiple <I>attribute</I>s that
appertain to the same entity be grouped into a single
<I>attribute-specifier</I>.
The migration from existing vendor-specific attributes would be
easier if the syntax allowed multiple <I>attribute-specifier</I>s
at each location where an <I>attribute-specifier</I> currently
appears.</P>

<P><B>Proposed resolution (October, 2010):</B></P>

<OL><LI><P>Replace every occurrence of <I>attribute-specifier</I> with
<I>attribute-specifier-seq</I> except in 7.6.1 [dcl.attr.grammar]
paragraphs 1, 3, and 6 (but <I>including</I> paragraph 4).</P></LI>

<LI><P>Insert the following production at the beginning of the grammar
of 7.6.1 [dcl.attr.grammar] paragraph 1:</P></LI>

<UL><I>attribute-specifier-seq:</I>
<UL><I>attribute-specifier-seq<SUB>opt</SUB> attribute-specifier</I></UL>
</UL>

</OL>

<BR><BR><HR><A NAME="1031"></A><H4>1031.
  
Optional elements in attributes
</H4><B>Section: </B>7.6.1&#160; [dcl.attr.grammar]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>2010-02-10<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>An <I>attribute-argument-clause</I> should be allowed to consist
solely of <TT>()</TT>, i.e., with no <I>balanced-token-seq</I>.
Furthermore, the grammar for <I>balanced-token</I> should make
the <I>balanced-token-seq</I> optional.  Both of these goals could
be accomplished by making the <I>balanced-token</I> optional in the
first production of the rule for <I>balanced-token-seq</I>.</P>

<P><B>Proposed resolution (February, 2011):</B></P>

<P>Change the grammar of 7.6.1 [dcl.attr.grammar] paragraph 1 as
follows:</P>

<UL><I>balanced-token-seq:</I>
<UL><I>balanced-token<SPAN style="font-weight:bold;background-color:#A0FFA0"><SUB>opt</SUB></SPAN></I><BR>
<I>balanced-token-seq balanced-token</I>
</UL>
</UL>

<BR><BR><HR><A NAME="1033"></A><H4>1033.
  
Restrictions on alignment attributes
</H4><B>Section: </B>7.6.2&#160; [dcl.align]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>2010-02-17<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>According to 7.6.2 [dcl.align] paragraph 5,</P>

<BLOCKQUOTE>

The combined effect of all alignment attributes in a declaration
shall not specify an alignment that is less strict than the
alignment that would otherwise be required for the entity being
declared.

</BLOCKQUOTE>

<P>&#8220;...would otherwise be required&#8221; could be read as
referring to the alignment set by another declaration of the
entity.  However, it was intended to prevent specifying an
alignment smaller than the natural alignment the entity would
have in the absence of an <TT>align</TT> attribute.  The wording
should be changed to make that clearer.</P>

<P><B>Proposed resolution (February, 2011):</B></P>

<P>Change 7.6.2 [dcl.align] paragraph 5 as follows:</P>

<BLOCKQUOTE>

The combined effect of all <I>alignment-specifier</I>s in a
declaration shall not specify an alignment that is less strict than
the alignment that would <SPAN style="text-decoration:line-through;background-color:#FFA0A0">otherwise</SPAN> be required for the
entity being declared <SPAN style="font-weight:bold;background-color:#A0FFA0">if all <I>alignment-specifier</I>s were
ignored (including those in other declarations)</SPAN>.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1036"></A><H4>1036.
  
Alignment attribute in an <I>exception-declaration</I>
</H4><B>Section: </B>7.6.2&#160; [dcl.align]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>2010-02-26<BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<P>The Standard explicitly bans alignment attributes for function parameters
(7.6.2 [dcl.align] paragraph 1), but it is silent regarding
the &#8220;parameter&#8221; of an exception handler.  This should be
clarified one way or the other.</P>

<P><B>Proposed resolution (October, 2010):</B></P>

<P>Change 7.6.2 [dcl.align] paragraph 1 as follows:</P>

<BLOCKQUOTE>

...The <I>attribute</I> may be followed by an ellipsis.  The attribute
may be applied to a variable <SPAN style="text-decoration:line-through;background-color:#FFA0A0">that is neither a function parameter
nor declared with the register storage class specifier and to a class
data member that is not a bit-field</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">or to a class data
member, but it shall not be applied to a bit-field, a function
parameter, the formal parameter of a catch clause (15.3 [except.handle]), or a variable declared with the <TT>register</TT>
storage class specifier</SPAN>. The attribute may also be applied to
the declaration of a class or enumeration type.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1243"></A><H4>1243.
  
Misleading footnote regarding multiple-declarator declarations
</H4><B>Section: </B>8&#160; [dcl.decl]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Johannes Schaub
 &#160;&#160;&#160;

 <B>Date: </B>2011-02-08<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>The footnote for 8 [dcl.decl] paragraph 3 reads,</P>

<BLOCKQUOTE>

A declaration with several declarators is usually equivalent to the
corresponding sequence of declarations each with a single
declarator...  The exception occurs when a name introduced by one of
the <I>declarator</I>s hides a type name used by the
<I>decl-specifier</I>s, so that when the same decl-specifiers are used
in a subsequent declaration, they do not have the same meaning...

</BLOCKQUOTE>

<P>A more important exception to the rule has been added in C++0x,
specifically with the <TT>auto</TT> specifier when the deduced type is
not the same for all <I>declarator</I>s, which renders the declaration
ill-formed.  The footnote should be updated accordingly.</P>

<BR><BR><HR><A NAME="1234"></A><H4>1234.
  
<I>abstract-declarator</I> does not permit <TT>...</TT> after <I>ptr-operator</I>
</H4><B>Section: </B>8.1&#160; [dcl.name]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Johannes Schaub
 &#160;&#160;&#160;

 <B>Date: </B>2011-01-18<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>The ellipsis for a parameter pack enters the normal
<I>declarator</I> grammar as part of the <I>declarator-id</I>
nonterminal.  In contrast, however, the <I>abstract-declarator</I>
grammar has no counterpart to <I>declarator-id</I>; instead, the
ellipsis is one of the productions for the <I>abstract-declarator</I>
nonterminal itself.  It is thus impossible to declare a parameter
pack for a pointer or reference using an abstract declarator, e.g.,</P>

<PRE>
  template&lt;typename... T&gt; void f(T&amp; ...t);   //<SPAN style="font-family:Times;font-style:italic"> </SPAN>t<SPAN style="font-family:Times;font-style:italic"> is a parameter pack</SPAN>
  template&lt;typename... T&gt; void f(T&amp; ...);    //<SPAN style="font-family:Times;font-style:italic"> equivalent to </SPAN>void f(T&amp;, ...)
</PRE>

<BR><BR><HR><A NAME="1240"></A><H4>1240.
  
<TT>constexpr</TT> defaulted constructors
</H4><B>Section: </B>8.1&#160; [dcl.name]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jens Maurer
 &#160;&#160;&#160;

 <B>Date: </B>2011-02-02<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

<P><A HREF="
     cwg_defects.html#1199">Issue 1199</A> proposes to add the capability
of defining a <TT>constexpr</TT> special function as deleted.  It
would be similarly useful to be able to mark a defaulted constructor
as <TT>constexpr</TT>.  (It should be noted that the existing text of
12.1 [class.ctor] and the proposed resolution of
<A HREF="
     cwg_defects.html#1224">issue 1224</A> already allow for implicitly-defined
constructors to be implicitly <TT>constexpr</TT>; this issue simply
proposes allowing the explicit use of the <TT>constexpr</TT>
specifier.)</P>

<P><B>Proposed resolution (February, 2011):</B></P>

<OL><LI><P>Change 7.1.5 [dcl.constexpr] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

<UL><LI><P>...</P></LI>

<LI><P>its <I>function-body</I> shall be <TT>= delete</TT><SPAN style="font-weight:bold;background-color:#A0FFA0">, <TT>=
default</TT>,</SPAN> or a <I>compound-statement</I> of the form</P>

<PRE>
  { return <I>expression</I> ; }
</PRE>

</LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 7.1.5 [dcl.constexpr] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

<P>In the definition of a <TT>constexpr</TT> constructor, each of the
parameter types shall be a literal type or a reference to a literal
type.  In addition, either its <I>function-body</I> shall be <TT>=
delete</TT> <SPAN style="font-weight:bold;background-color:#A0FFA0">or <TT>= default</TT></SPAN> or it shall satisfy the
following constraints:</P>

<UL><LI><P>...</P></LI>

</UL>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">A trivial copy/move constructor is also a <TT>constexpr</TT>
constructor.</SPAN></P>

</BLOCKQUOTE>

</OL>

<I>[Note: this resolution assumes that the changes for
<A HREF="
     cwg_defects.html#1199">issue 1199</A> have been applied.]</I>

<BR><BR><HR><A NAME="547"></A><H4>547.
  
Partial specialization on member function types
</H4><B>Section: </B>8.3.5&#160; [dcl.fct]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Peter Dimov
 &#160;&#160;&#160;

 <B>Date: </B>04 November 2005<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>The following example appears to be well-formed, with the partial
specialization matching the type of <TT>Y::f()</TT>, even though it
is rejected by many compilers:</P>

<PRE>
    template&lt;class T&gt; struct X;

    template&lt;class R&gt; struct X&lt; R() &gt; {
    };

    template&lt;class F, class T&gt; void test(F T::* pmf) {
        X&lt;F&gt; x;
    }

    struct Y {
        void f() {
        }
    };

    int main() {
        test( &amp;Y::f );
    }
</PRE>

<P>However, 8.3.5 [dcl.fct] paragraph 4 says,</P>

<BLOCKQUOTE>

A <I>cv-qualifier-seq</I> shall only be part of the function type for
a non-static member function, the function type to which a pointer to
member refers, or the top-level function type of a function typedef
declaration. The effect of a <I>cv-qualifier-seq</I> in a function
declarator is not the same as adding cv-qualification on top of the
function type. In the latter case, the cv-qualifiers are ignored.

</BLOCKQUOTE>

<P>This specification makes it impossible to write a partial
specialization for a <TT>const</TT> member function:</P>

<PRE>
    template&lt;class R&gt; struct X&lt;R() const&gt; {
    };
</PRE>

<P>A template argument is not one of the permitted contexts for
cv-qualification of a function type.  This restriction should be
removed.</P>

<P><B>Notes from the April, 2006 meeting:</B></P>

<P>During the meeting the CWG was of the opinion that the
&#8220;<TT>R() const</TT>&#8221; specialization would not match
the const member function even if it were allowed and so classified
the issue as NAD.  Questions have been raised since the meeting,
however, suggesting that the template argument in the partial
specialization would, in fact, match the type of a const member
function (see, for example, the very similar usage via typedefs
in 9.3 [class.mfct] paragraph 9).  The issue is thus being
left open for renewed discussion at the next meeting.</P>

<P><B>Proposed resolution (June, 2008):</B></P>

<P>Change 8.3.5 [dcl.fct] paragraph 7 as follows:</P>

<BLOCKQUOTE>

A <I>cv-qualifier-seq</I> shall only be part of the function type for a
non-static member function, the function type to which a pointer to
member refers, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN> the top-level function type of a function typedef
declaration<SPAN style="font-weight:bold;background-color:#A0FFA0">, or the top-level function type of a <I>type-id</I> that is a
<I>template-argument</I> for a type <I>template-parameter</I></SPAN>. The
effect... A <I>ref-qualifier</I> shall only be part of the function type for
a non-static member function, the function type to which a pointer to
member refers, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN> the top-level function type of a function typedef
declaration<SPAN style="font-weight:bold;background-color:#A0FFA0">, or the top-level function type of a <I>type-id</I> that is a
<I>template-argument</I> for a type <I>template-parameter</I></SPAN>. The
return type...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="994"></A><H4>994.
  
<I>braced-init-list</I> as a default argument
</H4><B>Section: </B>8.3.5&#160; [dcl.fct]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>25 Oct, 2009<BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>



<P>It seems strange that it is possible to call a function with an
explict argument of <TT>{}</TT> but that it is not possible to specify
that same argument as a default in a function declaration.</P>

<P><B>Rationale (August, 2010):</B></P>

<P>This was previously considered and rejected by EWG.</P>

<P><B>Note (October, 2010):</B></P>

<P>Additional discussion has indicated a potential willingness to
revisit this question.  </P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>See paper N3217.</P>

<BR><BR><HR><A NAME="1069"></A><H4>1069.
  
Incorrect function type with <I>trailing-return-type</I>
</H4><B>Section: </B>8.3.5&#160; [dcl.fct]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>James Widman
 &#160;&#160;&#160;

 <B>Date: </B>2010-04-30<BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>



<P>In 8.3.5 [dcl.fct] paragraph 2, the type of a function
declarator with a <I>trailing-return-type</I> is said to be</P>

<BLOCKQUOTE>

&#8220;function of (<I>parameter-declaration-clause</I>)
<I>cv-qualifier-seq<SUB>opt</SUB> ref-qualifier<SUB>opt</SUB></I>
returning <I>type-id</I>&#8221;.

</BLOCKQUOTE>

<P>This formulation incorrectly omits the
<I>derived-declarator-type-list</I> modifier for the type, and it
should refer to &#8220;the <I>trailing-type-specifier-seq</I> of the
<I>trailing-return-type</I>&#8221; as the return type instead of
<I>type-id</I> (which is left over from before the introduction
of <I>trailing-return-type</I>).</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<P>Change 8.3.5 [dcl.fct] paragraph 2 as follows:</P>

<BLOCKQUOTE>

...<TT>T</TT> shall be the single <I>type-specifier</I> <TT>auto</TT>.
The type of the <I>declarator-id</I> in <TT>D</TT> is
&#8220;<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>derived-declarator-type-list</I></SPAN> function of
(<I>parameter-declaration-clause</I>)
<I>cv-qualifier-seq<SUB>opt</SUB> ref-qualifier<SUB>opt</SUB></I>
returning <I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">type-id</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">trailing-return-type</SPAN></I>&#8221;.  The optional...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1183"></A><H4>1183.
  
Expansion of parameter packs in declarators
</H4><B>Section: </B>8.3.5&#160; [dcl.fct]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-26<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3270.]</P>

<P>8.3.5 [dcl.fct] paragraph 13 says,</P>

<BLOCKQUOTE>

The type <TT>T</TT> of the <I>declarator-id</I> of the function
parameter pack shall contain a template parameter pack; each template
parameter pack in <TT>T</TT> is expanded by the function parameter
pack.

</BLOCKQUOTE>

<P>I think that's incorrect.  For example, I think</P>

<PRE>
    template&lt;class... P&gt; void f(int (* ...p)[sizeof...(P)]);
</PRE>

<P>should be an error, and that the function parameter pack <TT>p</TT>
does not expand the template parameter pack <TT>P</TT> in this case.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#778">issue 778</A>.</P>

<BR><BR><HR><A NAME="1134"></A><H4>1134.
  
When is an explicitly-defaulted function defined?
</H4><B>Section: </B>8.4.2&#160; [dcl.fct.def.default]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US47">N3092 comment
  US&#160;47<BR></A>

<P>8.4.2 [dcl.fct.def.default] paragraph 4 says,</P>

<BLOCKQUOTE>

A special member function is <I>user-provided</I> if it is
user-declared and not explicitly defaulted on its first
declaration. A user-provided explicitly-defaulted function
is defined at the point where it is explicitly defaulted...

</BLOCKQUOTE>

<P>The second sentence should say &#8220;user-declared&#8221;
instead of &#8220;user-provided.&#8221;</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<P>Change 8.4.2 [dcl.fct.def.default] paragraph 4 as follows:</P>

<BLOCKQUOTE>

...A special member function is <I>user-provided</I> if it is
user-declared and not explicitly defaulted on its first declaration. A
user-provided explicitly-defaulted function <SPAN style="font-weight:bold;background-color:#A0FFA0">(i.e., explicitly
defaulted after its first declaration)</SPAN> is defined at the point
where it is explicitly defaulted; if such a function is implicitly
defined as deleted, the program is ill-formed. [<I>Note:</I>...

</BLOCKQUOTE>

<I>[Drafting note: the suggestion in the NB comment is incorrect.
The proposed resolution clarifies the intent.]</I>

<BR><BR><HR><A NAME="1135"></A><H4>1135.
  
Explicitly-defaulted non-public special member functions
</H4><B>Section: </B>8.4.2&#160; [dcl.fct.def.default]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>FI
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#FI1">N3092 comment
  FI&#160;1<BR></A>

<P>It should be allowed to explicitly default a non-public
special member function on its first declaration. It is very
likely that users will want to default protected/private
constructors and copy constructors without having to write
such defaulting outside the class.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<OL><LI><P>Change 8.4.2 [dcl.fct.def.default] paragraphs 1-5 as
follows:</P></LI>

<BLOCKQUOTE>

<P>A function definition of the form:</P>

<UL><I>attribute-specifier<SUB>opt</SUB> decl-specifier-seq<SUB>opt</SUB> declarator </I> <TT>= default ;</TT></UL>

<P>is called an <I>explicitly-defaulted</I> definition. A function
that is explicitly defaulted shall</P>

<UL><LI><P>be a special member function,</P></LI>

<LI><P>have the same declared function type (except for possibly
differing <I>ref-qualifier</I>s and except that in the case of a copy
constructor or copy assignment operator, the parameter type may be
&#8220;reference to non-const <TT>T</TT>&#8221;, where <TT>T</TT> is
the name of the member function's class) as if it had been
implicitly declared, <SPAN style="font-weight:bold;background-color:#A0FFA0">and</SPAN></P></LI>

<LI><P>not have default arguments<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, and</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">.</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">not have an <I>exception-specification</I>.</SPAN></P></LI>

</UL>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">[<I>Note:</I> This implies that parameter types, return type, and
cv-qualifiers must match the hypothetical implicit declaration.
&#8212;<I>end note</I>]</SPAN></P>

<P>An explicitly-defaulted function may be declared <TT>constexpr</TT>
only if it would have been implicitly declared as
<TT>constexpr</TT><SPAN style="font-weight:bold;background-color:#A0FFA0">, and may have an explicit
<I>exception-specification</I> only if it is compatible (15.4 [except.spec]) with the <I>exception-specification</I> on the implicit
declaration</SPAN>. If <SPAN style="text-decoration:line-through;background-color:#FFA0A0">it</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">a function</SPAN> is
explicitly defaulted on its first declaration,</P>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">it shall be public,</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">it shall not be explicit,</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">it shall not be virtual,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">it is implicitly considered to be <TT>constexpr</TT>
if the implicit declaration would be,</SPAN></P></LI>

<LI><P>it is implicitly considered to have the same
<I>exception-specification</I> as if it had been implicitly declared
(15.4 [except.spec]), and</P></LI>

<LI><P>in the case of a copy constructor, move constructor, copy
assignment operator, or move assignment operator, it shall have the
same parameter type as if it had been implicitly declared.</P></LI>

</UL>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">[<I>Note:</I> Such a special member function may be trivial, and
thus its accessibility and explicitness should match the hypothetical
implicit definition; see below. &#8212;<I>end note</I>]</SPAN>
[<I>Example:</I></P>

<PRE>
  struct S {
<SPAN style="font-weight:bold;background-color:#A0FFA0">    constexpr S() = default;                 //<SPAN style="font-family:Times;font-style:italic">ill-formed: implicit </SPAN>S()<SPAN style="font-family:Times;font-style:italic"> is not </SPAN>constexpr</SPAN>
    S(int a = 0) = default;                  //<SPAN style="font-family:Times;font-style:italic"> ill-formed: default argument</SPAN>
    void operator=(const S&amp;) = default;      //<SPAN style="font-family:Times;font-style:italic"> ill-formed: non-matching return type</SPAN>
    ~S() throw(<SPAN style="font-weight:bold;background-color:#A0FFA0">int</SPAN>) = default;               //<SPAN style="font-family:Times;font-style:italic"> ill-formed: exception specification <SPAN style="font-weight:bold;background-color:#A0FFA0">doesn't match</SPAN></SPAN>
  private:
<SPAN style="font-weight:bold;background-color:#A0FFA0">    int i;</SPAN>
    S(S&amp;);                                   //<SPAN style="font-family:Times;font-style:italic"> OK: private copy constructor</SPAN>
  };
  S::S(S&amp;) = default;                        //<SPAN style="font-family:Times;font-style:italic"> OK: defines copy constructor</SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

<P>Explicitly-defaulted functions and implicitly-declared functions
are collectively called <I>defaulted</I> functions, and the implementation
shall provide implicit definitions for them (12.1 [class.ctor]
12.4 [class.dtor], 12.8 [class.copy]), which
might mean defining them as deleted. A special member function is
<I>user-provided</I> if it is user-declared and not explicitly
defaulted <SPAN style="font-weight:bold;background-color:#A0FFA0">or deleted</SPAN> on its first declaration. A
user-provided explicitly-defaulted function <SPAN style="font-weight:bold;background-color:#A0FFA0">(i.e., explicitly
defaulted after its first declaration)</SPAN> is defined at the point
where it is explicitly defaulted; if such a function is implicitly
defined as deleted, the program is ill-formed. [<I>Note:</I>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">while an implicitly-declared special member function is inline
(Clause 12 [special]), an explicitly-defaulted definition
may be non-inline.  Non-inline definitions are user-provided, and
hence non-trivial (12.1 [class.ctor], 12.4 [class.dtor], 12.8 [class.copy]).  This rule enables</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">Declaring a function as defaulted after its first declaration can
provide</SPAN> efficient execution and concise definition while
enabling a stable binary interface to an evolving code
base. &#8212;<I>end note</I>]</P>

<P>[<I>Example:</I></P>

<PRE>
  struct trivial {
    trivial() = default;
    trivial(const trivial&amp;) = default;
    trivial(trivial&amp;&amp;) = default;
    trivial&amp; operator=(const trivial&amp;) = default;
    trivial&amp; operator=(trivial&amp;&amp;) = default;
    ~trivial() = default;
  };

  struct nontrivial1 {
    nontrivial1();
  };

  nontrivial1::nontrivial1() = default;           //<SPAN style="font-family:Times;font-style:italic"> not <SPAN style="text-decoration:line-through;background-color:#FFA0A0">inline</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">first declaration</SPAN></SPAN>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">  struct nontrivial2 {
    nontrivial2();
  };
  inline nontrivial2::nontrivial2() = default;    //<SPAN style="font-family:Times;font-style:italic"> not first declaration</SPAN>

  struct nontrivial3 {
    virtual ~nontrivial3() = 0;                   //<SPAN style="font-family:Times;font-style:italic"> virtual</SPAN>
  };
  inline nontrivial3::~nontrivial3() = default;   //<SPAN style="font-family:Times;font-style:italic"> not first declaration</SPAN></SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<LI><P>Change 12.1 [class.ctor] paragraph 5 as follows:</P></LI>

<BLOCKUOTE>

...A default constructor is trivial if it is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">neither</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">not</SPAN> user-provided <SPAN style="text-decoration:line-through;background-color:#FFA0A0">nor deleted</SPAN> and...

</BLOCKUOTE>

<LI><P>Change 12.4 [class.dtor] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

...A destructor is trivial if it is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">neither</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">not</SPAN>
user-provided <SPAN style="text-decoration:line-through;background-color:#FFA0A0">nor deleted</SPAN> and...

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraph 13 as follows:</P></LI>

<BLOCKQUOTE>

A copy/move constructor for class X is trivial if it is
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">neither</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">not</SPAN> user-provided <SPAN style="text-decoration:line-through;background-color:#FFA0A0">nor deleted</SPAN>
and...

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraph 27 as follows:</P></LI>

<BLOCKQUOTE>

A copy/move assignment operator for class <TT>X</TT> is
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>trivial</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">trivial</SPAN> if it is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">neither</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">not</SPAN> user-provided <SPAN style="text-decoration:line-through;background-color:#FFA0A0">nor deleted</SPAN> and...

</BLOCKQUOTE>

</OL>

<P>This resolution also resolves issues <A HREF="
     cwg_defects.html#1136">1136</A>,
<A HREF="
     cwg_defects.html#1137">1137</A>, <A HREF="
     cwg_defects.html#1140">1140</A>,
<A HREF="
     cwg_defects.html#1145">1145</A>, <A HREF="
     cwg_defects.html#1149">1149</A>, and
<A HREF="
     cwg_defects.html#1208">1208</A>.</P>

<BR><BR><HR><A NAME="1136"></A><H4>1136.
  
Explicitly-defaulted explicit constructors
</H4><B>Section: </B>8.4.2&#160; [dcl.fct.def.default]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>FI
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#FI2">N3092 comment
  FI&#160;2<BR></A>

<P>It should be allowed to explicitly default an explicit
special member function on its first declaration. It is very
likely that users will want to default explicit copy
constructors without having to write such defaulting outside
of the class.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>This issue is resolved by the resolution of <A HREF="
     cwg_defects.html#1135">issue 1135</A>.</P>

<BR><BR><HR><A NAME="1137"></A><H4>1137.
  
Explicitly-defaulted virtual special member functions
</H4><B>Section: </B>8.4.2&#160; [dcl.fct.def.default]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>FI
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#FI3">N3092 comment
  FI&#160;3<BR></A>

<P>It should be allowed to explicitly default a virtual
special member function on its first declaration. It is very
likely that users will want to default virtual copy
assignment operators and destructors without having to write
such defaulting outside of the class.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>This issue is resolved by the resolution of <A HREF="
     cwg_defects.html#1135">issue 1135</A>.</P>

<BR><BR><HR><A NAME="508"></A><H4>508.
  
Non-constructed value-initialized objects
</H4><B>Section: </B>8.5&#160; [dcl.init]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>18 Mar 2005<BR>


<P>[Voted into WP at August, 2010 meeting.]</P>

<P>According to the definition of <I>value initialization</I>
(8.5 [dcl.init] paragraph 5), non-union class types without
user-declared constructors are value-initialized by value-initializing
each of their members rather than by executing the (generated)
default constructor.  However, a number of other items in the
Standard are described in relationship to the execution of the
constructor:</P>

<UL>

<LI><P>12.4 [class.dtor] paragraph 6: &#8220;Bases and
members are destroyed in the reverse order of the completion of their
constructor.&#8221;  If a given base or member is value-initialized without
running its constructor, is it destroyed?  (For that matter, paragraph
10 refers to &#8220;constructed&#8221; objects; is an object that is
value-initialized without invoking a constructor
&#8220;constructed?&#8221;)</P></LI>

<LI><P>15.2 [except.ctor] paragraph 2: &#8220;An object that is
partially constructed or partially destroyed will have destructors
executed for all of its fully constructed subobjects, that is, for
subobjects for which the constructor has completed
execution...&#8221;</P></LI>

<LI><P>3.8 [basic.life] paragraph 1: The lifetime of an
object begins when &#8220;the constructor call has completed.&#8221;
(In the TC1 wording&#160;&#8212; &#8220;if <TT>T</TT> is a class type
with a non-trivial constructor (12.1 [class.ctor]), the
constructor call has completed&#8221;&#160;&#8212; the lifetime of
some value-initialized objects never began; in the current wording
&#8212;&#160;&#8220;the constructor invoked to create the object is
non-trivial&#8221;&#160;&#8212; the lifetime begins before any of the
members are initialized.)</P></LI>

</UL>

<P><B>Proposed resolution (October, 2005):</B></P>

<P>Add the indicated words to 8.5 [dcl.init] paragraph 6:</P>

<BLOCKQUOTE>

A program that calls for default-initialization or
value-initialization of an entity of reference type is ill-formed. If
<TT>T</TT> is a cv-qualified type, the cv-unqualified version
of <TT>T</TT> is used for these definitions of zero-initialization,
default-initialization, and value-initialization. <SPAN style="font-weight:bold;background-color:#A0FFA0">Even when
value-initialization of an object does not call that object's
constructor, the object is deemed to have been fully constructed once
its initialization is complete and thus subject to provisions of this
International Standard applying to &#8220;constructed&#8221; objects,
objects &#8220;for which the constructor has completed
execution,&#8221; etc.</SPAN>

</BLOCKQUOTE>

<P><B>Notes from April, 2006 meeting:</B></P>

<P>There was some concern about whether this wording covered (or
needed to cover) cases where an object is &#8220;partially
constructed.&#8221;  Another approach might be simply to define
value initialization to be &#8220;construction.&#8221;  Returned to
&#8220;drafting&#8221; status for further investigation.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 8.5 [dcl.init] paragraph 7 as follows:</P>

<BLOCKQUOTE>

<P>To <I>value-initialize</I> an object of type <TT>T</TT> means:</P>

<UL><LI><P>...</P></LI>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">An object that is value-initialized is deemed to be constructed
and thus subject to provisions of this International Standard applying
to &#8220;constructed&#8221; objects, objects &#8220;for which the
constructor has completed,&#8221; etc., even if no constructor is invoked
for the object's initialization.</SPAN></P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="615"></A><H4>615.
  
Incorrect description of variables that can be initialized
</H4><B>Section: </B>8.5&#160; [dcl.init]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>comp.std.c++
 &#160;&#160;&#160;

 <B>Date: </B>30 January 2007<BR>


<P>[Voted into WP at August, 21010 meeting.]</P>

<P>8.5 [dcl.init] paragraph 2 reads,</P>

<BLOCKQUOTE>

Automatic, register, static, and external variables of namespace scope
can be initialized by arbitrary expressions involving literals and
previously declared variables and functions.

</BLOCKQUOTE>

<P>Both &#8220;automatic&#8221; and &#8220;static&#8221; are used to
describe <I>storage durations</I>, &#8220;register&#8221; is
a <I>storage class specifier</I> which indicates the object has
automatic storage duration, &#8220;external&#8221;
describes <I>linkage</I>, and &#8220;namespace scope&#8221; is a kind
of <I>scope</I>. Automatic, register, static and external, together
with namespace scope, are used to restrict the
&#8220;variables.&#8221;</P>

<P>Register objects are only a sub-set of automatic objects and thus
the word &#8220;register&#8221; is redundant and should be elided. If
register objects are to be emphasized, they should be mentioned like
&#8220;Automatic (including register)...&#8221;</P>

<P>Variables having namespace scope can never be automatic; they can
only be static, with either external or internal linkage. Therefore,
there are in fact no &#8220;automatic variables of namespace
scope,&#8221; and the &#8220;static&#8221; in &#8220;static variables
of namespace scope&#8221; is useless.</P>

<P>In fact, automatic and static variables already compose all
variables with either external linkage or not, and thus the
&#8220;external&#8221; becomes redundant, too, and the quoted sentence
seems to mean that all variables of namespace scope can be initialized
by arbitrary expressions. But this is not true because not all
internal variables of namespace scope can. Therefore, the restrictive
&#8220;external&#8221; is really necessary, not redundant.</P>

<P>As a result, the erroneous restrictive &#8220;automatic, register,
static&#8221; should be removed and the quoted sentence may be changed
to:</P>

<BLOCKQUOTE>

External variables of namespace scope can be initialized by arbitrary
expressions involving literals and previously declared variables and
functions.

</BLOCKQUOTE>

<P><B>Notes from the April, 2007 meeting:</B></P>

<P>This sentence is poorly worded, but the analysis given in
the issue description is incorrect.  The intent is simply that
the storage class of a variable places no restrictions on the
kind of expression that can be used to initialize it (in contrast
to C, where variables of static storage duration can only be
initialized by constant expressions).</P>

<P><B>Proposed resolution (June, 2008):</B></P>

<P>Change 8.5 [dcl.init] paragraph 2 as follows:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Automatic, register, static, and external variables of namespace scope</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">Variables of automatic, thread, and static storage duration</SPAN> can
be initialized by arbitrary expressions involving literals and
previously declared variables and functions...

</BLOCKQUOTE>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>The existing wording is intended to exclude block-scope
<TT>extern</TT> declarations but to allow initializers in all
other forms of variable declarations.  The best way to phrase
that is probably to say that all variable definitions (except for
function parameters, where the initializer syntax is used for
default arguments) can have arbitrary expressions as
initializers, regardless of storage duration.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 8.5 [dcl.init] paragraph 2 as follows:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Automatic, register, thread_local, static, and
namespace-scoped external variables can be initialized by</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">Except for objects declared with the <TT>constexpr</TT>
specifier, for which see 7.1.5 [dcl.constexpr], an
<I>initializer</I> in the definition of a variable can consist
of</SPAN> arbitrary expressions involving literals and previously
declared variables and functions<SPAN style="font-weight:bold;background-color:#A0FFA0">, regardless of the
variable's storage duration</SPAN>. [<I>Example:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="694"></A><H4>694.
  
Zero- and value-initialization of union objects
</H4><B>Section: </B>8.5&#160; [dcl.init]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Clark Nelson
 &#160;&#160;&#160;

 <B>Date: </B>14 May, 2008<BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<P>The C committee is considering changing the definition of
zero-initialization of unions to guarantee that the bytes of the
entire union are set to zero before assigning 0, converted to the
appropriate type, to the first member.  The argument (summarized
<A href="http://www.open-std.org/jtc1/sc22/wg14/11416">here</A>)
is for backward compatibility.  The C++ Committee may want to
consider the same change.</P>

<P><B>Proposed resolution (August, 2008):</B></P>

<P>Change bullet 3 of 8.5 [dcl.init] paragraph 5 (in the first
list, dealing with zero-initialization) as follows:</P>

<UL><LI>if <TT>T</TT> is a (possibly cv-qualified) union type,
<SPAN style="font-weight:bold;background-color:#A0FFA0">the object representation of <TT>T</TT> (3.9 [basic.types]) is zero-initialized, after which</SPAN> the object's first
non-static named data member is zero-initialized;</LI></UL>

<P><I>[Drafting notes: Ask a C liaison about the progress of WG14
paper N1311, which deals with this issue.  Since the adoption of
WG21 paper N2544, unions may have static data members, hence the
change to refer to the first non-static data member and the
deletion of the footnote.]</I></P>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>It was observed that padding bytes in structs are
zero-initialized in C, so if we are changing the treatment of
unions in this way we should consider adding the C behavior for
padding bytes at the same time.  In particular, using
<TT>memcmp</TT> to compare structs only works reliably if the
padding bytes are zero-initialized.</P>

<P><B>Additional notes (February, 2010):</B></P>

<P>The C Committee has changed its approach to this question and
is no longer using a two-phase process; in C, zero-initialization
is specific to program start-up and thus is not appropriate for
use with thread-local storage. See C paper
<A href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1387.htm">N1387</A>.</P>

<P><B>Proposed resolution (October, 2010):</B></P>

<P>Change 8.5 [dcl.init] paragraph 5 as follows:</P>

<BLOCKQUOTE>

<P>To <I>zero-initialize</I> an object or reference of type <TT>T</TT>
means:</P>

<UL><LI><P>if <TT>T</TT> is a scalar type (3.9 [basic.types]),
the object is set to the value <TT>0</TT> (zero), taken as an integral
constant expression, converted to <TT>T</TT>;<SUP>103</SUP></P></LI>

<LI><P>if T is a (possibly cv-qualified) non-union class type, each
non-static data member and each base-class subobject is
zero-initialized<SPAN style="font-weight:bold;background-color:#A0FFA0">, and padding is initialized to zero bits</SPAN>;</P></LI>

<LI><P>if T is a (possibly cv-qualified) union type, the object's
first non-static named data member is zero-initialized<SPAN style="font-weight:bold;background-color:#A0FFA0">, and padding
is initialized to zero bits</SPAN>;</P></LI>

<LI><P>if T is an array type, each element is zero-initialized;</P></LI>

<LI><P>if T is a reference type, no initialization is performed.</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1214"></A><H4>1214.
  
Kinds of initializers
</H4><B>Section: </B>8.5&#160; [dcl.init]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Johannes Schaub
 &#160;&#160;&#160;

 <B>Date: </B>2010-10-30<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>8.5 [dcl.init] paragraph 16 describes three kinds of
initializers: a single expression, a <I>braced-init-list</I>, and a
parenthesized list of expressions.  It is not clear which, if any,
of these categories is the appropriate description for an
initializer like</P>

<PRE>
    T t( { 1, 2 } )
</PRE>

<P>and thus not clear which of the bullets in the list applies.</P>

<BR><BR><HR><A NAME="938"></A><H4>938.
  
Initializer lists and array new
</H4><B>Section: </B>8.5.1&#160; [dcl.init.aggr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>12 July, 2009<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>



<P>8.5.1 [dcl.init.aggr] paragraph 4 says,</P>

<BLOCKQUOTE>

An <I>initializer-list</I> is ill-formed if the number of
<I>initializer-clause</I>s exceeds the number of members or elements
to initialize.

</BLOCKQUOTE>

<P>However, in a <I>new-expression</I>, the number of elements to be
initialized is potentially unknown at compile time. How should an
overly-long <I>initializer-list</I> in a <I>new-expression</I> be treated?</P>

<P><B>Notes from the August, 2010 meeting:</B></P>

<P>The consensus of the CWG was that this case should throw an exception
at runtime.</P>

<P><B>Proposed resolution (January, 2011):</B></P>

<P>Change 5.3.4 [expr.new] paragraph 7 as follows:</P>

<BLOCKQUOTE>

When the value of the <I>expression</I> in a
<I>noptr-new-declarator</I> is zero, the allocation function is called
to allocate an array with no elements.  If the value of that
<I>expression</I> is less than zero or such that the size of the
allocated object would exceed the implementation-defined limit,
<SPAN style="font-weight:bold;background-color:#A0FFA0">or if the <I>new-initializer</I> is a <I>braced-init-list</I> for
which the number of <I>initializer-clause</I>s exceeds the number of
elements to initialize,</SPAN> no storage is obtained and the
<I>new-expression</I> terminates by throwing an exception of a type
that would match a handler (15.3 [except.handle]) of type
<TT>std::bad_array_new_length</TT> (18.6.2.3 [new.badlength]).

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1030"></A><H4>1030.
  
Evaluation order in <I>initializer-list</I>s used in aggregate initialization
</H4><B>Section: </B>8.5.1&#160; [dcl.init.aggr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Scott Meyers
 &#160;&#160;&#160;

 <B>Date: </B>2010-02-09<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>



<P>The ordering imposed by 8.5.1 [dcl.init.aggr] paragraph
17 applies only to &#8220;the full-expressions in an
<I>initializer-clause</I>&#8221; (i.e., what follows an
<TT>=</TT> in an aggregate initializer); this leaves unspecified
the order in which the expressions in an <I>initializer-list</I>
(the term used by the <I>braced-init-list</I> form of
initializer, with no <TT>=</TT>) are evaluated.</P>

<P><B>Notes from the November, 2010 meeting:</B></P>

<P>The CWG favored guaranteeing the order of evaluation of
<I>initializer-clause</I>s appearing in a <I>braced-init-list</I>,
regardless of whether the <I>braced-init-list</I> is an aggregate
initialization or constructor call.</P>

<P><B>Proposed resolution (January, 2011):</B></P>

<OL><LI><P>Delete 8.5.1 [dcl.init.aggr] paragraph 17:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The full-expressions in an <I>initializer-clause</I> are
evaluated in the order in which they appear.</SPAN>

</BLOCKQUOTE>

<LI><P>Insert the following as a new paragraph between paragraphs
3 and 4 of 8.5.4 [dcl.init.list]</P></LI>

<BLOCKQUOTE>

<SPAN style="font-weight:bold;background-color:#A0FFA0">Within the <I>initializer-list</I> of a <I>braced-init-list</I>,
the <I>initializer-clause</I>s, including any that result from pack
expansions (14.5.3 [temp.variadic]), are evaluated in the order
in which they appear. That is, every value computation and side effect
associated with a given <I>initializer-clause</I> is sequenced before
every value computation and side effect associated with any
<I>initializer-clause</I> that follows it in the comma-separated list
of the <I>initializer-list</I>. [<I>Note:</I> This evaluation ordering
holds regardless of the semantics of the initialization; for example,
it applies when the elements of the <I>initializer-list</I> are
interpreted as arguments of a constructor call, even though ordinarily
there are no sequencing constraints on the arguments of a call.
&#8212;<I>end note</I>]</SPAN>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1070"></A><H4>1070.
  
Missing initializer clauses in aggregate initialization
</H4><B>Section: </B>8.5.1&#160; [dcl.init.aggr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-06-01<BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>



<A HREF="
     cwg_defects.html#990">Issue 990</A> added the following text to
8.5.4 [dcl.init.list] paragraph 3:

<UL><LI><P>Otherwise, if the initializer list has no elements and
<TT>T</TT> is an aggregate, each of the members of <TT>T</TT> is
initialized from an empty initializer
list. [<I>Example:</I>...</P></LI></UL>

<P>A better way to handle this would be to delete that bullet and
change 8.5.1 [dcl.init.aggr] paragraph 7 as follows:</P>

<BLOCKQUOTE>

If there are fewer <I>initializer-clause</I>s in the list than there
are members in the aggregate, then each member not explicitly
initialized shall be <SPAN style="text-decoration:line-through;background-color:#FFA0A0">value-initialized (8.5 [dcl.init])</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">initialized from an empty initializer list
(8.5.4 [dcl.init.list])</SPAN>.

</BLOCKQUOTE>

<P>This makes <TT>{ }</TT> less of a special case and makes the
following example work:</P>

<PRE>
    struct A {
       A(std::initializer_list&lt;int&gt;);
    };
    struct B {
       int i;
       A a;
    };
    B b = { 1 };
</PRE>

<P><B>Proposed resolution (August, 2010):</B></P>

<OL><LI><P>Delete 8.5.4 [dcl.init.list] paragraph 3 bullet 2,
includeing the example:</P></LI>

<UL><LI><SPAN style="text-decoration:line-through;background-color:#FFA0A0">Otherwise, if the initializer list has no
elements and <TT>T</TT> is an aggregate, each of the members
of <TT>T</TT> is initialized from an empty initializer
list. [<I>Example:</I>...</SPAN></LI></UL>

<LI><P>Change 8.5.1 [dcl.init.aggr] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

If there are fewer <I>initializer-clause</I>s in the list than there
are members in the aggregate, then each member not explicitly
initialized shall be <SPAN style="text-decoration:line-through;background-color:#FFA0A0">value-initialized (8.5 [dcl.init])</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">initialized from an empty initializer list
(8.5.4 [dcl.init.list])</SPAN>.

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1138"></A><H4>1138.
  
Rvalue-ness check for rvalue reference binding is wrong
</H4><B>Section: </B>8.5.3&#160; [dcl.init.ref]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US48">N3092 comment
  US&#160;48<BR></A>
<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#GB37">N3092 comment
  GB&#160;37<BR></A>
<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#DE10">N3092 comment
  DE&#160;10<BR></A>

<P>The requirement that an rvalue reference must be bound to an rvalue
is found in 8.5.3 [dcl.init.ref] paragraph 5 bullet 2:</P>

<UL><LI><P>Otherwise, the reference shall be an lvalue
reference to a non-volatile const type (i.e., <I>cv1</I> shall be
<TT>const</TT>), or the reference shall be an rvalue reference and
the initializer expression shall be an rvalue or have a
function type.</P></LI></UL>

<P>This is not quite correct, as it is phrased in terms of the value
category of the initializer expression itself rather than that of
the result of any conversions applied to the initializer.  It should
be permitted to bind an rvalue reference to a temporary created from
an lvalue, for instance, or to the rvalue result of a conversion
function for an lvalue object of class type.  Also, it should <I>not</I>
be permitted to bind an rvalue reference to the lvalue result of a
conversion function for a class rvalue.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change 8.5.3 [dcl.init.ref] paragraph 5 as follows:</P>

<BLOCKQUOTE>

<P>A reference to type &#8220;<I>cv1</I> <TT>T1</TT>&#8221;
is initialized by an expression of type &#8220;<I>cv2</I>
<TT>T2</TT>&#8221; as follows:</P>

<UL><LI><P>If the reference is an lvalue reference and the
initializer expression</P></LI>

<UL><LI><P>is an lvalue (but is not a bit-field), and
&#8220;<I>cv1</I> <TT>T1</TT>&#8221; is reference-compatible
with &#8220;<I>cv2</I> <TT>T2</TT>,&#8221; or</P></LI>

<LI><P>has a class type (i.e., <TT>T2</TT> is a class type),
where <TT>T1</TT> is not reference-related to <TT>T2</TT>,
and can be implicitly converted to an lvalue of type
&#8220;<I>cv3</I> <TT>T3</TT>,&#8221; where
&#8220;<I>cv1</I> <TT>T1</TT>&#8221; is reference-compatible
with &#8220;<I>cv3</I> <TT>T3</TT>&#8221;<SUP>105</SUP>
(this conversion is selected by enumerating the applicable
conversion functions (13.3.1.6 [over.match.ref]) and
choosing the best one through overload resolution
(13.3 [over.match])),</P></LI>

</UL>

<P>then the reference is bound to the initializer expression
lvalue in the first case and to the lvalue result of the
conversion in the second case (or, in either case, to the
appropriate base class subobject of the object).
[<I>Note:</I> the usual lvalue-to-rvalue (4.1 [conv.lval]), array-to-pointer (4.2 [conv.array]),
and function-to-pointer (4.3 [conv.func]) standard
conversions are not needed, and therefore are suppressed,
when such direct bindings to lvalues are done. &#8212;<I>end
note</I>]</P>

<P>[<I>Example:</I></P>

<PRE>
  double d = 2.0;
  double&amp; rd = d;          //<SPAN style="font-family:Times;font-style:italic"> </SPAN>rd<SPAN style="font-family:Times;font-style:italic"> refers to </SPAN>d
  const double&amp; rcd = d;   //<SPAN style="font-family:Times;font-style:italic"> </SPAN>rcd<SPAN style="font-family:Times;font-style:italic"> refers to </SPAN>d
  struct A { };
  struct B : A { <SPAN style="font-weight:bold;background-color:#A0FFA0">operator int&amp;();</SPAN> } b;
  A&amp; ra = b;               //<SPAN style="font-family:Times;font-style:italic"> </SPAN>ra<SPAN style="font-family:Times;font-style:italic"> refers to </SPAN>A<SPAN style="font-family:Times;font-style:italic"> subobject in </SPAN>b
  const A&amp; rca = b;        //<SPAN style="font-family:Times;font-style:italic"> </SPAN>rca<SPAN style="font-family:Times;font-style:italic"> refers to </SPAN>A<SPAN style="font-family:Times;font-style:italic"> subobject in </SPAN>b
<SPAN style="font-weight:bold;background-color:#A0FFA0">  int&amp; ir = B();           //<SPAN style="font-family:Times;font-style:italic"> </SPAN>ir<SPAN style="font-family:Times;font-style:italic"> refers to the result of </SPAN>B::operator int&amp;</SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

<LI><P>Otherwise, the reference shall be an lvalue reference
to a non-volatile const type (i.e., <I>cv1</I> shall be
<TT>const</TT>), or the reference shall be an rvalue
reference <SPAN style="text-decoration:line-through;background-color:#FFA0A0">and the initializer expression shall be an rvalue
or have a function type</SPAN>. [<I>Example:</I></P></LI>

<PRE>
  double&amp; rd2 = 2.0;       //<SPAN style="font-family:Times;font-style:italic"> error: not an lvalue and reference not </SPAN>const
  int  i = 2;
  double&amp; rd3 = i;         //<SPAN style="font-family:Times;font-style:italic"> error: type mismatch and reference not </SPAN>const
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">  double&amp;&amp; rd4 = i;        //<SPAN style="font-family:Times;font-style:italic"> error: rvalue reference cannot bind to lvalue</SPAN></SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">If the initializer expression</SPAN></P></LI>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">is an xvalue, class prvalue, array prvalue or
function lvalue and &#8220;<I>cv1</I> <TT>T1</TT>&#8221; is
reference-compatible with &#8220;<I>cv2</I>
<TT>T2</TT>&#8221;, or</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">has a class type (i.e., <TT>T2</TT> is a class type),
where <TT>T1</TT> is not reference-related to <TT>T2</TT>,
and can be implicitly converted to an xvalue, class prvalue,
or function lvalue of type &#8220;<I>cv3</I>
<TT>T3</TT>,&#8221; where &#8220;<I>cv1</I>
<TT>T1</TT>&#8221; is reference-compatible with
&#8220;<I>cv3</I> <TT>T3</TT>&#8221;,</SPAN></P></LI>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">then the reference is bound to the value of the
initializer expression in the first case and to the result
of the conversion in the second case (or, in either case, to
an appropriate base class subobject). In the second case, if
the reference is an rvalue reference and the second standard
conversion sequence of the user-defined conversion sequence
includes an lvalue-to-rvalue conversion, the program is
ill-formed.</SPAN></P>

</UL>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">If <TT>T1</TT> is a function type, then</SPAN></P></LI>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">if <TT>T2</TT> is the same type as <TT>T1</TT>,
the reference is bound to the initializer expression
lvalue;</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">if <TT>T2</TT> is a class type and the initializer
expression can be implicitly converted to an lvalue of type
<TT>T1</TT> (this conversion is selected by enumerating the
applicable conversion functions (13.3.1.6 [over.match.ref]) and choosing the best one through overload
resolution (13.3 [over.match])), the reference is
bound to the function lvalue that is the result of the
conversion;</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">otherwise, the program is ill-formed.</SPAN></P></LI>

</UL>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">Otherwise, if <TT>T2</TT> is a class type and</SPAN></P></LI>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">the initializer expression is an rvalue and
&#8220;<I>cv1</I> <TT>T1</TT>&#8221; is reference-compatible
with &#8220;<I>cv2</I> <TT>T2</TT>&#8221;, or</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>T1</TT> is not reference-related to <TT>T2</TT>
and the initializer expression can be implicitly converted
to an rvalue of type &#8220;<I>cv3</I> <TT>T3</TT>&#8221;
(this conversion is selected by enumerating the applicable
conversion functions (13.3.1.6 [over.match.ref]) and
choosing the best one through overload resolution
(13.3 [over.match])),</SPAN></P></LI>

</UL>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">then the reference is bound to the initializer expression
rvalue in the first case and to the object that is the
result of the conversion in the second case (or, in either
case, to the appropriate base class subobject of the
object).</SPAN></P>

<P>[<I>Example:</I></P>

<PRE>
  struct A { };
  struct B : A { } b;
  extern B f();
  const A&amp; rca = f();      //<SPAN style="font-family:Times;font-style:italic"> bound to the </SPAN>A<SPAN style="font-family:Times;font-style:italic"> subobject of the </SPAN>B<SPAN style="font-family:Times;font-style:italic"> rvalue.</SPAN>
  A&amp;&amp; <SPAN style="text-decoration:line-through;background-color:#FFA0A0">rcb</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">rra</SPAN> = f();       //<SPAN style="font-family:Times;font-style:italic"> same as above</SPAN>
  struct X {
  operator B();
<SPAN style="font-weight:bold;background-color:#A0FFA0">  operator int&amp;();</SPAN>
  } x;
  const A&amp; r = x;                     //<SPAN style="font-family:Times;font-style:italic"> bound to the </SPAN>A<SPAN style="font-family:Times;font-style:italic"> subobject of the result of the conversion</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  int&amp;&amp; rri = static_cast&lt;int&amp;&amp;&gt;(i);  //<SPAN style="font-family:Times;font-style:italic"> bound directly to </SPAN>i
  B&amp;&amp; rrb = x;                        //<SPAN style="font-family:Times;font-style:italic"> bound directly to the result of </SPAN>operator B
  int&amp;&amp; rri2 = X();                   //<SPAN style="font-family:Times;font-style:italic"> error: lvalue-to-rvalue conversion applied to result of </SPAN>operator int&amp;</SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">If the initializer expression is an rvalue, with
<TT>T2</TT> an array type, and &#8220;<I>cv1</I>
<TT>T1</TT>&#8221; is reference-compatible with
&#8220;<I>cv2</I> <TT>T2</TT>,&#8221; the reference is bound
to the object represented by the rvalue (see 3.10 [basic.lval]).</SPAN></P></LI>

<LI><P>Otherwise, a temporary of type &#8220;<I>cv1</I>
<TT>T1</TT>&#8221; is created and initialized from the
initializer expression using the rules for a non-reference
copy-initialization (8.5 [dcl.init]).  The
reference is then bound to the temporary.  If <TT>T1</TT> is
reference-related to <TT>T2</TT>, <I>cv1</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">must</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">shall</SPAN> be the same cv-qualification as, or greater
cv-qualification than, <I>cv2</I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">; otherwise, the
program is ill-formed</SPAN>. <SPAN style="font-weight:bold;background-color:#A0FFA0">If <TT>T1</TT> is
reference-related to <TT>T2</TT> and the reference is an
rvalue reference, the initializer expression shall not be an
lvalue.</SPAN> [<I>Example:</I></P></LI>

<PRE>
  const double&amp; rcd2 = 2;     //<SPAN style="font-family:Times;font-style:italic"> </SPAN>rcd2<SPAN style="font-family:Times;font-style:italic"> refers to temporary with value </SPAN>2.0
  double&amp;&amp; <SPAN style="text-decoration:line-through;background-color:#FFA0A0">rcd3</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">rrd</SPAN> = 2;      //<SPAN style="font-family:Times;font-style:italic"> </SPAN><SPAN style="text-decoration:line-through;background-color:#FFA0A0">rcd3</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">rrd</SPAN><SPAN style="font-family:Times;font-style:italic"> refers to temporary with value </SPAN>2.0
  const volatile int cvi = 1;
  const int&amp; r = cvi;         //<SPAN style="font-family:Times;font-style:italic"> error: type qualifiers dropped</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  double&amp;&amp; rrd2 = d;          //<SPAN style="font-family:Times;font-style:italic"> error: copying lvalue of related type</SPAN>
  double&amp;&amp; rrd3 = i;          //<SPAN style="font-family:Times;font-style:italic"> </SPAN>rrd3<SPAN style="font-family:Times;font-style:italic"> refers to temporary with value </SPAN>2.0</SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

</UL>

</UL>

<P>In all cases except the last (i.e., creating and
initializing a temporary from the initializer expression),
the reference is said to <I>bind directly</I> to the
initializer expression.</P>

</BLOCKQUOTE>

<P>This resolution also resolves <A HREF="
     cwg_defects.html#1139">issue 1139</A>.</P>

<BR><BR><HR><A NAME="1139"></A><H4>1139.
  
Rvalue reference binding to scalar xvalues
</H4><B>Section: </B>8.5.3&#160; [dcl.init.ref]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US49">N3092 comment
  US&#160;49<BR></A>



<P>The current wording of 8.5.3 [dcl.init.ref] paragraph 5 does
not specify direct binding of an rvalue reference to a scalar xvalue;
instead, it requires creation of a temporary and binding the rvalue
reference to the temporary.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>This issue is resolved by the resolution of <A HREF="
     cwg_defects.html#1138">1138</A>.</P>

<BR><BR><HR><A NAME="1236"></A><H4>1236.
  
Inconsistently-interrelated examples
</H4><B>Section: </B>8.5.3&#160; [dcl.init.ref]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Doug Gregor
 &#160;&#160;&#160;

 <B>Date: </B>2011-01-20<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>The examples in 8.5.3 [dcl.init.ref] paragraph 5 are
not consistent as to whether earlier code fragments are assumed to
be part of the example or not.  For instance, the variables
<TT>i</TT> and <TT>d</TT> are used as initializers without
declaration in later fragments, presumably intended to refer to
the declarations introduced in the first couple.  However, the
third fragment declares <TT>rca</TT>, which is an incompatible
redeclaration of a name declared in the first fragment.</P>

<BR><BR><HR><A NAME="1095"></A><H4>1095.
  
List-initialization of references
</H4><B>Section: </B>8.5.4&#160; [dcl.init.list]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2010-07-26<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>The current wording of the WP appears not to allow for list-initialization
of a reference like the following:</P>

<PRE>
    int i;
    int&amp; ir{i};
</PRE>

<P>First, 8.5 [dcl.init] paragraph 16 bullet 1 reads,</P>

<UL><LI><P>If the initializer is a braced-init-list, the
object is list-initialized (8.5.4).</P></LI></UL>

<P>A reference is not an object, so this does not appear to apply;
however, the second bullet sends reference initialization off to
8.5.3 [dcl.init.ref], which does not cover
<I>braced-init-list</I>s: paragraph 5 of that section deals only
with initilizer expressions, and a <I>braced-init-list</I> is not
an expression.</P>

<P>Assuming that the use of &#8220;object&#8221; in the first bullet
is just an oversight, 8.5.4 [dcl.init.list] also does not
cover the case of a reference to a scalar type whose initalizer
is a <I>braced-init-list</I> with a single element.  Bullet 7 of
paragraph 3 reads,</P>

<UL><LI><P>Otherwise, if the initializer list has a single
element, the object is initialized from that
element</P></LI></UL>

<P> and would cover this case except that, again, a
reference is not an object.  As a result, such an
initialization would end up in the last bullet and
consequently be ill-formed.</P>

<P>Presumably all that is needed is to add &#8220;or
reference&#8221; to the appropriate bullets of 8.5 [dcl.init]
paragraph 16 and 8.5.4 [dcl.init.list] paragraph 3.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<OL><LI><P>Change 8.5 [dcl.init] paragraph 16 bullet 1
as follows:</P></LI>

<UL><LI><P>If the initializer is a <I>braced-init-list</I>, the object
<SPAN style="font-weight:bold;background-color:#A0FFA0">or reference</SPAN> is list-initialized (8.5.4 [dcl.init.list]).</P></LI></UL>

<LI><P>Change 8.5.4 [dcl.init.list] paragraph 3 bullet 7 as
follows:</P></LI>

<UL><LI><P>Otherwise, if the initializer list has a single element,
the object <SPAN style="font-weight:bold;background-color:#A0FFA0">or reference</SPAN> is initialized from that element;
if a narrowing conversion (see below) is required to convert the
element to <TT>T</TT>, the program is ill-formed.</P></LI></UL>

</OL>

<BR><BR><HR><A NAME="1232"></A><H4>1232.
  
Creation of array temporaries using a <I>braced-init-list</I>
</H4><B>Section: </B>8.5.4&#160; [dcl.init.list]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Andrew Koenig
 &#160;&#160;&#160;

 <B>Date: </B>2011-01-03<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>By analogy with the variable definition</P>

<PRE>
    int arr[3] = {1, 2, 3};
</PRE>

<P>it should be possible to write something like</P>

<PRE>
   void f(const int(&amp;)[3]);
   void g() {
     f({1, 2, 3});
   }
</PRE>

<P>There are currently at least two problems with the latter usage.
First, the variable initializer relies on brace elision, which appears
to be defined only for variable declarations (8.5.1 [dcl.init.aggr]
paragraph 11), and possibly only for certain forms of variable
declarations.</P>

<P>Second, the call would require creation of an array temporary to
which the parameter reference would be bound, and the current Standard
does not describe array temporaries (although rvalue arrays can occur
as members of class rvalues).  This is also contrary to the direction
established by CWG in considering <A HREF="
     cwg_closed.html#1058">1058</A>.</P>

<BR><BR><HR><A NAME="355"></A><H4>355.
  
Global-scope <TT>::</TT> in <I>nested-name-specifier</I>
</H4><B>Section: </B>9&#160; [class]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Clark Nelson
 &#160;&#160;&#160;

 <B>Date: </B>16 May 2002<BR>


<P>[Voted into the WP at the March, 2011 meeting as paper N3259.]</P>



<P>
In looking at a large handful of core issues related to
<I>elaborated-type-specifier</I>s and the naming of classes in general, I
discovered an odd fact. It turns out that there is exactly one place in the
grammar where <I>nested-name-specifier</I>
is not immediately preceded by "<TT>::</TT><SUB><I>opt</I></SUB>":
in <I>class-head</I>, which is used only for class definitions. So technically,
this example is ill-formed, and should evoke a syntax error:
</P>
<PRE>
  struct A;
  struct ::A { };
</PRE>
<P>
However, all of EDG, GCC and Microsoft's compiler accept it without a qualm.
In fact, I couldn't get any of them to even warn about it.</P>

<P><B>Suggested resolution:</B></P>

<P>It would simplify the grammar, and apparently better reflect existing
practice, to factor the global-scope operator into the rule for
<I>nested-name-specifier</I>.</P>

<P><B>Proposed resolution (February, 2011):</B></P>

<P>The proposed resolution will be submitted as a separate document.</P>

<BR><BR><HR><A NAME="1140"></A><H4>1140.
  
Incorrect redefinition of POD class
</H4><B>Section: </B>9&#160; [class]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US50">N3092 comment
  US&#160;50<BR></A>

<P>The class</P>

<PRE>
    struct A { const int i; };
</PRE>

<P>was a POD in C++98, but is not a POD under the FCD rules
because it does not have a trivial default constructor.
C++0x POD was intended to be a superset of C++98 POD.</P>

<P><U>Suggested resolution</U>: Change POD to be standard
layout and trivially copyable.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>This issue is resolved by the resolution of <A HREF="
     cwg_defects.html#1135">issue 1135</A>.</P>

<BR><BR><HR><A NAME="1215"></A><H4>1215.
  
Definition of POD struct
</H4><B>Section: </B>9&#160; [class]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2010-10-28<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>The definition of a POD struct in 9 [class] paragraph 9
is not (but should be) restricted to non-union class types.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change 9 [class] paragraph 9 as follows:</P>

<BLOCKQUOTE>

A <I>POD struct</I><SUP>109</SUP> is a <SPAN style="font-weight:bold;background-color:#A0FFA0">non-union</SPAN> class that
is both a trivial class and a standard-layout class...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="924"></A><H4>924.
  
<I>alias-declaration</I> as a class member
</H4><B>Section: </B>9.2&#160; [class.mem]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>23 June, 2009<BR><BR>


<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#FI10">N3092 comment
  FI&#160;10<BR></A>

<P>[Voted into WP at August, 21010 meeting.]</P>

<P>The grammar for <I>member-declaration</I> in 9.2 [class.mem] does not include a production for the
<I>alias-declaration</I> form of typedef declarations, meaning that
something like</P>

<PRE>
    struct S {
      using UINT = unsigned int;
    };
</PRE>

<P>is ill-formed.  This seems like an oversight.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>In the grammar in 9.2 [class.mem], add the indicated
production to the definition of <I>member-declaration</I>:</P>

<UL><I>member-declaration:</I>
<UL><I>decl-specifier-seq<SUB>opt</SUB> attribute-specifier<SUB>opt</SUB> member-declarator-list<SUB>opt</SUB></I> <TT>;</TT></UL>
<UL><I>function-definition</I> <TT>;</TT><SUB><I>opt</I></SUB></UL>
<UL><TT>::</TT><SUB><I>opt</I></SUB> <I>nested-name-specifier</I> <TT>template</TT><SUB><I>opt</I></SUB> <I>unqualified-id</I> <TT>;</TT></UL>
<UL><I>using-declaration</I></UL>
<UL><I>static_assert-declaration</I></UL>
<UL><I>template-declaration</I></UL>
<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><I>alias-declaration</I></SPAN></UL>
</UL>

<BR><BR><HR><A NAME="1035"></A><H4>1035.
  
Omitted and required <I>decl-specifier</I>s
</H4><B>Section: </B>9.2&#160; [class.mem]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>2010-02-25<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>According to 9.2 [class.mem] paragraph 6,</P>

<BLOCKQUOTE>

 The <I>decl-specifier-seq</I> is omitted in constructor, destructor,
 and conversion function declarations only.

</BLOCKQUOTE>

<P>This is incorrect, as some <I>decl-specifier</I>s (<TT>explicit</TT>,
<TT>virtual</TT>, <TT>inline</TT>, <TT>constexpr</TT>) are permitted
in these declarations.  Conversely, C.1.6 [diff.dcl],
&#8220;Banning implicit int,&#8221; says,</P>

<BLOCKQUOTE>

In C++ a <I>decl-specifier-seq</I> must contain a <I>type-specifier</I>.

</BLOCKQUOTE>

<P>This is also incorrect for these declarations.</P>

<P><B>Proposed resolution (February, 2011):</B></P>

<OL><LI><P>Change 9.2 [class.mem] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

The <I>decl-specifier-seq</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">is</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">may be</SPAN> omitted
in constructor, destructor, and conversion function declarations
only<SPAN style="font-weight:bold;background-color:#A0FFA0">; when declaring another kind of member the
<I>decl-specifier-seq</I> shall contain a <I>type-specifier</I> that
is not a <I>cv-qualifier</I></SPAN>.  The <I>member-declarator-list</I>
can be omitted...

</BLOCKQUOTE>

<LI><P>Change C.1.6 [diff.dcl], &#8220;Banning implicit
int,&#8221; as follows:</P></LI>

<BLOCKQUOTE>

In C++ a <I>decl-specifier-seq</I> must contain a
<I>type-specifier</I><SPAN style="font-weight:bold;background-color:#A0FFA0">, unless it is followed by a declarator for
a constructor, a destructor, or a conversion function</SPAN>.  In the
following example...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1072"></A><H4>1072.
  
Scoped enumerator with the same name as its containing class
</H4><B>Section: </B>9.2&#160; [class.mem]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Pavel Minaev
 &#160;&#160;&#160;

 <B>Date: </B>2010-06-02<BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<P>9.2 [class.mem] paragraph 13 requires that all enumerators
of a member enumeration type have names different from that of the
containing class.  This is only necessary for an unscoped enumeration;
scoped enumerators are not in the scope of the containing class.</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<P>Change 9.2 [class.mem] paragraph 14 bullet 4 as follows:</P>

<UL><LI>every enumerator of every member of class T that is an
<SPAN style="font-weight:bold;background-color:#A0FFA0">unscoped</SPAN> enumerated type; and</LI></UL>

<BR><BR><HR><A NAME="1142"></A><H4>1142.
  
<TT>friend</TT> declaration of member function of containing class
</H4><B>Section: </B>9.3&#160; [class.mfct]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US52">N3092 comment
  US&#160;52<BR></A>

<P>The current wording of 9.3 [class.mfct] paragraph
7 allows friend declarations to name member functions &#8220;after
their class has been defined.&#8221; This appears to prohibit a
friend declaration in a nested class defined inside its
containing class that names a member function of the
containing class, because the containing class is still
considered to be incomplete at that point.</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<P>Change 9.3 [class.mfct] paragraph 7 as follows:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Member</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Previously-declared member</SPAN> functions may
be mentioned in friend declarations <SPAN style="text-decoration:line-through;background-color:#FFA0A0">after their class has been
defined</SPAN>.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1017"></A><H4>1017.
  
Member access transformation in unevaluated operands
</H4><B>Section: </B>9.3.1&#160; [class.mfct.non-static]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Johannes Schaub
 &#160;&#160;&#160;

 <B>Date: </B>2009-12-30<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3282.]</P>

<P>The following innocuous-appearing code is currently ill-formed:</P>

<PRE>
    struct A {
        int a;
    };

    struct B {
        void f() {
            decltype(A::a) i;    // ill-formed
        }
    };
</PRE>

<P>The reason is that, according to 9.3.1 [class.mfct.non-static]
paragraph 3, the reference to <TT>A::a</TT> is transformed into
<TT>(*this).A::a</TT>, and there is no <TT>A</TT> subobject of
<TT>B</TT>.  It would seem reasonable to suppress this transformation
in unevaluated operands, where a reference to a non-static member
is permitted without an object expression.</P>

<P>(See also <A HREF="
     cwg_closed.html#1005">issue 1005</A>.)</P>

<P><B>Notes from the November, 2010 meeting:</B></P>

The CWG agreed that the resolution of <A HREF="
     cwg_defects.html#515">issue 515</A>
was ill-advised and should be reversed.

<BR><BR><HR><A NAME="1207"></A><H4>1207.
  
Type of class member in <I>trailing-return-type</I>
</H4><B>Section: </B>9.3.1&#160; [class.mfct.non-static]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-10-06<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3282.]</P>



<P>Consider the following example:</P>

<PRE>
    struct vector {
        struct iterator { };
        struct const_iterator { };
        iterator begin();
        const_iterator begin() const;
    };
    class block {
        vector v;
        auto end() const -&gt; decltype(v.begin()) { return v.begin(); }
    };
</PRE>

<P>Because the transformation of a member name into a class member
access expression (9.3.1 [class.mfct.non-static] paragraph 3) only
occurs inside the body of a non-static member function, the type
of <TT>v</TT> in the <I>trailing-return-type</I> is non-const but
is const in the return expression, resulting in a type mismatch
between the return expression and the return type of the function.</P>

<P>One possibility would be to include the <I>trailing-return-type</I>
as being subject to the transformation in 9.3.1 [class.mfct.non-static].
Note, however, that <TT>this</TT> is currently not in scope at that
point (see <A HREF="
     cwg_defects.html#945">issue 945</A>).</P>

<P><B>Notes from the November, 2010 meeting:</B></P>

<P>The CWG felt that, because <TT>this</TT> is effectively an
implicit parameter, the best approach would be to model its usability
on the visibility of parameters: it could be named wherever a
parameter of the function is in scope.</P>

<P><B>Proposed resolution (February, 2011):</B></P>

<OL><LI><P>Change 5.1.1 [expr.prim.general] paragraph 2 as follows,
adding three new paragraphs:</P></LI>

<BLOCKQUOTE>

<P>The keyword <TT>this</TT> names a pointer to the object for which a
non-static member function (9.3.2 [class.this]) is invoked or
a non-static data member's initializer (9.2 [class.mem]) is
evaluated. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The keyword <TT>this</TT> shall be used only inside the
body of a non-static member function (9.3 [class.mfct]) of the
nearest enclosing class or in a <I>brace-or-equal-initializer</I> for
a non-static data member (9.2 [class.mem]).  The type of the
expression is a pointer to the class of the function or non-static
data member, possibly with cv-qualifiers on the class type. The
expression is a prvalue.</SPAN></P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">If a <I>function-definition</I> or <I>member-declarator</I>
declares a member function of a class <TT>X</TT>, the expression
<TT>this</TT> is a prvalue of type &#8220;pointer to
<I>cv-qualifier-seq</I> <TT>X</TT>&#8221; between the optional
<I>cv-qualifier-seq</I> and the end of the <I>function-definition</I>
or <I>member-declarator</I>. It shall not appear before the optional
<I>cv-qualifier-seq</I> and it shall not appear within the declaration
of a static member function (although its type and value category is
defined within a static member function as it is within a non-static
member function). [<I>Note:</I> the type and value category is defined
even for the case of a static member function because declaration
matching does not occur until the complete declarator is known, and
<TT>this</TT> may be used in the <I>trailing-return-type</I> of the
declarator. &#8212;<I>end note</I>]</SPAN></P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">Otherwise, if a <I>member-declarator</I> declares a
non-static data member (9.2 [class.mem]) of a class <TT>X</TT>,
the expression <TT>this</TT> is a prvalue of type &#8220;pointer to
<TT>X</TT>&#8221; within the optional <I>brace-or-equal-initializer</I>.
It shall not appear elsewhere in the <I>member-declarator</I>.</SPAN></P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">The expression <TT>this</TT> shall not appear in any other
context.</SPAN></P>

<P>[<I>Example:</I>...</P>

</BLOCKQUOTE>

<LI><P>Change 5.1.1 [expr.prim.general] paragraph 10 as follows:</P></LI>

<BLOCKQUOTE>

<P>An <I>id-expression</I> that denotes a non-static data member or
non-static member function of a class can only be used:</P>

<UL><LI><P>...</P></LI>

<LI><SPAN style="text-decoration:line-through;background-color:#FFA0A0">in the body of</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">beyond the optional
<I>cv-qualifier-seq</I> in the <I>member-declarator</I> or
<I>function-definition</I> that declares</SPAN> a non-static member
function of that class or of a class derived from that class
(9.3.1 [class.mfct.non-static]), or</LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 9.3.1 [class.mfct.non-static] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

When an <I>id-expression</I> (5.1 [expr.prim]) that is not
part of a class member access syntax (5.2.5 [expr.ref]) and
not used to form a pointer to member (5.3.1 [expr.unary.op]) is
used in the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">body</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">declaration</SPAN> of a
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-static</SPAN> member function of class <TT>X</TT>, if name
lookup (3.4 [basic.lookup]) resolves the name...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1208"></A><H4>1208.
  
Explicit <TT>noexcept</TT> in defaulted definition
</H4><B>Section: </B>9.3.1&#160; [class.mfct.non-static]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2010-10-07<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>



<P>It is currently not permitted to specify an
<I>exception-specification</I> in a defaulted definition.  It
would be nice to be able to do so (providing the explicit
specification matches the one that would be implicitly supplied)
for documentation purposes.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>This issue is resolved by the resolution of <A HREF="
     cwg_defects.html#1135">issue 1135</A>.</P>

<BR><BR><HR><A NAME="1101"></A><H4>1101.
  
Non-integral initialized static data members
</H4><B>Section: </B>9.4.2&#160; [class.static.data]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-02<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>According to 9.4.2 [class.static.data] paragraph 3,</P>

<BLOCKQUOTE>

If a <TT>static</TT> data member is of <TT>const</TT>
literal type, its declaration in the class definition can
specify a <I>brace-or-equal-initializer</I> in which every
<I>initializer-clause</I> that is an
<I>assignment-expression</I> is a constant expression.  A
<TT>static</TT> data member of literal type can be declared in the
class definition with the <TT>constexpr</TT> specifier; if so, its
declaration shall specify a <I>brace-or-equal-initializer</I> in
which every <I>initializer-clause</I> that is an
<I>assignment-expression</I> is a constant expression.
[<I>Note:</I> In both these cases, the member may appear in
constant expressions. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<P>However, 5.19 [expr.const] paragraph 2 bullet 7
allows only integral and enumeration types in constant
expressions for the <TT>const</TT> case; the other types
require <TT>constexpr</TT> to be considered constant
expressions.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change 9.4.2 [class.static.data] paragraph 3 as follows:</P>

<BLOCKQUOTE>

If a <SPAN style="font-weight:bold;background-color:#A0FFA0">non-volatile <TT>const</TT></SPAN> <TT>static</TT> data
member is of <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>const</TT> literal</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">integral or
enumeration</SPAN> type, its declaration in the class definition can
specify a
<I>brace-or-equal-initializer</I> in which every
<I>initializer-clause</I> that is an <I>assignment-expression</I> is a
constant expression <SPAN style="font-weight:bold;background-color:#A0FFA0">(5.19 [expr.const])</SPAN>. A
<TT>static</TT> data member of literal type can be declared in the
class definition with the <TT>constexpr</TT> specifier...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="741"></A><H4>741.
  
&#8220;plain&#8221; <TT>long long</TT> bit-fields
</H4><B>Section: </B>9.6&#160; [class.bit]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>7 November, 2008<BR>


<P>[Voted into WP at August, 21010 meeting.]</P>

<P>The type <TT>long long</TT> is missing from the list of bit-field
types in 9.6 [class.bit] paragraph 3 for which the
implementation can choose the signedness.  This was presumably an
oversight.  (If that is the case, we may want to reconsider the
handling of 4.5 [conv.prom] paragraph 3: a <TT>long long</TT>
bit-field that the implementation treats as unsigned will &#8212;
pending the outcome of <A HREF="
     cwg_defects.html#739">issue 739</A> &#8212;
still promote to <TT>signed long long</TT>, which can lead to
unexpected results for bit-fields with the same number of bits as
<TT>long long</TT>.)</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 9.6 [class.bit] paragraph 3 as follows:</P>

<BLOCKQUOTE>

...It is implementation-defined whether a plain (neither
explicitly signed nor unsigned) <TT>char</TT>, <TT>short</TT>,
<TT>int</TT><SPAN style="text-decoration:line-through;background-color:#FFA0A0"> or</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">,</SPAN> <TT>long</TT><SPAN style="font-weight:bold;background-color:#A0FFA0">, or
<TT>long long</TT></SPAN> bit-field is signed or unsigned...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="696"></A><H4>696.
  
Use of block-scope constants in local classes
</H4><B>Section: </B>9.8&#160; [class.local]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>29 May, 2008<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

<P>According to 9.8 [class.local] paragraph 1,</P>

<BLOCKQUOTE>

Declarations in a local class can use only type names, static variables,
extern variables and functions, and enumerators from the enclosing scope.

</BLOCKQUOTE>

<P>This would presumably make both of the members of <TT>S2</TT> below
ill-formed:</P>

<PRE>
    void test () {
      const int local_const = 7;
      struct S2 {
        int member:local_const;
        void f() { int j = local_const; }
      };
    }
</PRE>

<P>Should there be an exception to this rule for constant values?
Current implementations seem to accept the reference to
<TT>local_const</TT> in the bit-field declaration but not in the
member function definition.  Should they be the same or different?</P>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>The CWG agreed that both uses of <TT>local_const</TT> in the
example above should be accepted.  The intent of the restriction
was to avoid the need to pass a frame pointer into local class
member functions, so uses of local const variables as values
should be permitted.</P>

<P><B>Notes from the October, 2009 meeting:</B></P>

<P>There was interest in an approach that would allow
explicitly-captured constants to appear in constant expressions
but also to be &#8220;used.&#8221; Another suggestion was to have
variables captured if they appear in either &#8220;use&#8221; or
&#8220;non-use&#8221; contexts.</P>

<P><B>Proposed resolution (February, 2011):</B></P>

<OL><LI><P>Change 5.1.2 [expr.prim.lambda] paragraph 17 as
follows:</P></LI>

<BLOCKQUOTE>

<P>Every <I>id-expression</I> that is an odr-use (3.2 [basic.def.odr]) of an entity captured by copy is transformed into an
access to the corresponding unnamed data member of the closure
type. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> an <I>id-expression</I> that is not an
odr-use refers to the original entity, never to a member of the
closure type. Furthermore, such an <I>id-expression</I> does not cause
the implicit capture of the entity. &#8212;<I>end note</I>]</SPAN> If
<TT>this</TT> is captured, each odr-use of <TT>this</TT> is
transformed into an access to the corresponding unnamed data member of
the closure type, cast (5.4 [expr.cast]) to the type of
<TT>this</TT>. [<I>Note:</I> the cast ensures that the transformed
expression is a prvalue. &#8212;<I>end note</I>]
<SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  void f(const int*);
  void g() {
    const int N = 10;
    [=] {
      int arr[N];    //<SPAN style="font-family:Times;font-style:italic"> OK: not an odr-use, refers to automatic variable</SPAN>
      f(&amp;N);         //<SPAN style="font-family:Times;font-style:italic"> OK: causes </SPAN>N<SPAN style="font-family:Times;font-style:italic"> to be captured; </SPAN>&amp;N<SPAN style="font-family:Times;font-style:italic"> points to the</SPAN>
                     //<SPAN style="font-family:Times;font-style:italic"> corresponding member of the closure type</SPAN>
    }
  }</SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

<LI>Change 9.8 [class.local] paragraph 1 as follows:</LI>

<BLOCKQUOTE>

<P>...Declarations in a local class <SPAN style="text-decoration:line-through;background-color:#FFA0A0">can use only type names,
static variables, extern variables and functions, and enumerators from
the</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">shall not odr-use (3.2 [basic.def.odr]) a variable
with automatic storage duration from an</SPAN> enclosing
scope. [<I>Example:</I></P>

<PRE>
  int x;
  void f() {
    static int s ;
    int x;
<SPAN style="font-weight:bold;background-color:#A0FFA0">    const int N = 5;</SPAN>
    extern int <SPAN style="text-decoration:line-through;background-color:#FFA0A0">g</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">q</SPAN>();

    struct local {
      int g() { return x; }     //<SPAN style="font-family:Times;font-style:italic"> error: <SPAN style="font-weight:bold;background-color:#A0FFA0">odr-use of automatic variable</SPAN> </SPAN>x<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><SPAN style="font-family:Times;font-style:italic"> has automatic storage duration</SPAN></SPAN>
      int h() { return s; }     //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
      int k() { return ::x; }   //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
      int l() { return <SPAN style="text-decoration:line-through;background-color:#FFA0A0">g</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">q</SPAN>(); } //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">      int m() { return N; }     //<SPAN style="font-family:Times;font-style:italic"> OK: not an odr-use</SPAN>
      int* n() { return &amp;N; }   //<SPAN style="font-family:Times;font-style:italic"> error: odr-use of automatic variable </SPAN>N</SPAN>
    };
  }

  local* p = 0;                 //<SPAN style="font-family:Times;font-style:italic"> error: </SPAN>local<SPAN style="font-family:Times;font-style:italic"> not in scope</SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="580"></A><H4>580.
  
Access in <I>template-parameter</I>s of member and friend definitions
</H4><B>Section: </B>11&#160; [class.access]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>16 May 2006<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>The resolution of <A HREF="
     cwg_defects.html#372">issue 372</A> leaves
unclear whether the following are well-formed or not:</P>

<PRE>
    class C {
        typedef int I;                // private
        template &lt;int&gt; struct X;
        template &lt;int&gt; friend struct Y;
    }

    template &lt;C::I&gt; struct C::X { };  // C::I accessible to member?

    template &lt;C::I&gt; struct Y { };     // C::I accessible to friend?
</PRE>

<P>Presumably the answer to both questions is &#8220;yes,&#8221; but
the new wording does not address <I>template-parameter</I>s.</P>

<P><B>Proposed resolution (June, 2008):</B></P>

<P>Change 11 [class.access] paragraph 6 as follows:</P>

<BLOCKQUOTE>

...For purposes of access control, the <I>base-specifier</I>s of a class<SPAN style="font-weight:bold;background-color:#A0FFA0">, the
<I>template-parameter</I>s of a <I>template-declaration</I>,</SPAN> and
the definitions of class members that appear outside of the class
definition are considered to be within the scope of that class...

</BLOCKQUOTE>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>The proposed resolution preserves the word &#8220;scope&#8221;
as a holdover from the original specification prior to <A HREF="
     cwg_defects.html#372">issue 372</A>, which intended to change access
determination from a scope-based model to an entity-based model.
The resolution should eliminate all references to scope and simply
use the entity-based model.</P>

<P>(See also <A HREF="
     cwg_active.html#718">issue 718</A>.)</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 11 [class.access] paragraphs 6-7 as follows:</P>

<BLOCKQUOTE>

<P>All access controls in Clause 11 [class.access] affect
the ability to access a class member name from <SPAN style="font-weight:bold;background-color:#A0FFA0">a declaration
of</SPAN> a particular <SPAN style="text-decoration:line-through;background-color:#FFA0A0">scope</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">entity, including
references appearing in those parts of the declaration that
precede the name of the entity being declared and implicit
references to constructors, conversion functions, and destructors
involved in the creation and destruction of a static data
member</SPAN>.  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">For purposes of access control, the
<I>base-specifier</I>s of a class and the definitions of class
members that appear outside of the class definition are
considered to be within the scope of that class.  In particular,
access controls apply as usual to member names accessed as part
of a function return type, even though it is not possible to
determine the access privileges of that use without first parsing
the rest of the function declarator.  Similarly, access control
for implicit calls to the constructors, the conversion functions,
or the destructor called to create and destroy a static data
member is performed as if these calls appeared in the scope of
the member's class.</SPAN> [<I>Example:</I></P>

<PRE>
  class A {
    typedef int I;    //<SPAN style="font-family:Times;font-style:italic"> private member</SPAN>
    I f();
    friend I g(I);
    static I x;
<SPAN style="font-weight:bold;background-color:#A0FFA0">    template&lt;int&gt; struct X;
    template&lt;int&gt; friend struct Y;</SPAN>
  protected:
    struct B { };
  };

  A::I A::f() { return 0; }
  A::I g(A::I p = A::x);
  A::I g(A::I p) { return 0; }
  A::I A::x = 0;
<SPAN style="font-weight:bold;background-color:#A0FFA0">  template&lt;A::I&gt; struct A::X { };
  template&lt;A::I&gt; struct Y { };
</SPAN>
  struct D: A::B, A { };
</PRE>

<P>Here, all the uses of <TT>A::I</TT> are well-formed because
<TT>A::f</TT><SPAN style="text-decoration:line-through;background-color:#FFA0A0"> and</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">,</SPAN> <TT>A::x</TT><SPAN style="font-weight:bold;background-color:#A0FFA0">, and
<TT>A::X</TT></SPAN> are members of class <TT>A</TT> and
<TT>g</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">is a friend</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">and <TT>Y</TT> are
friends</SPAN> of class <TT>A</TT>. This implies, for example,
that access checking on the first use of <TT>A::I</TT> must be
deferred until it is determined that this use of <TT>A::I</TT> is
as the return type of a member of class <TT>A</TT>. Similarly,
the use of <TT>A::B</TT> as a <I>base-specifier</I> is
well-formed because <TT>D</TT> is derived from <TT>A</TT>, so
checking of <I>base-specifier</I>s must be deferred until the
entire <I>base-specifier-list</I> has been seen.  &#8212;<I>end
example</I>]</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="738"></A><H4>738.
  
<TT>constexpr</TT> not permitted by the syntax of constructor declarations
</H4><B>Section: </B>12.1&#160; [class.ctor]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>James Widman
 &#160;&#160;&#160;

 <B>Date: </B>27 October, 2008<BR>


<P>[Voted into WP at August, 21010 meeting.]</P>



<P>According to 12.1 [class.ctor] paragraph 1, only
<I>function-specifier</I>s are permitted in the declaration of a
constructor, and <TT>constexpr</TT> is not a <I>function-specifier</I>.
(See also <A HREF="
     cwg_defects.html#263">issue 263</A>, in which the resolution
of a similar concern regarding the <TT>friend</TT> specifier did not
change 12.1 [class.ctor] paragraph 1 but perhaps should have
done so.)</P>



<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 12.1 [class.ctor] paragraph 1 as follows:</P>

<BLOCKQUOTE>

<P>Constructors do not have names.  A special declarator syntax
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">using an optional sequence of <I>function-specifier</I>s
(7.1.2 [dcl.fct.spec]) followed by the constructor's class
name followed by a parameter list</SPAN> is used to declare or define
the constructor. <SPAN style="font-weight:bold;background-color:#A0FFA0">The syntax uses</SPAN></P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">an optional <I>decl-specifier-seq</I> in which each
<I>decl-specifier</I> is either a <I>function-specifier</I> or
<TT>constexpr</TT>,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">the constructor's class name, and</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">a parameter list</SPAN></P></LI>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">in that order.</SPAN> In such a declaration, optional
parentheses around the constructor class name are
ignored. [<I>Example:</I>...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1145"></A><H4>1145.
  
Defaulting and triviality
</H4><B>Section: </B>12.1&#160; [class.ctor]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>FI
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-03<BR><BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#FI4">N3092 comment
  FI&#160;4<BR></A>

<P>What effect does defaulting have on triviality? Related
to <A HREF="
     cwg_defects.html#1135">issue 1135</A>, non-public special
members defaulted on their first declaration should retain
triviality, because they shouldn't be considered
user-provided. Related to <A HREF="
     cwg_defects.html#1137">issue 1137</A>, defaulted member functions that are virtual
should not be considered trivial, but there's no reason why
non-virtuals could not be.</P>

<P>Furthermore, a class with a non-public explicitly-defaulted
constructor isn't ever trivially constructible under the
current rules. If such a class is used as a subobject, the
constructor of the aggregating class should be trivial if it
can access the non-public explicitly defaulted constructor
of a subobject.</P>

<P><U>Suggested resolution</U>: Change the triviality rules
so that a class can have a trivial default constructor if
the class has access to the default constructors of its
subobjects and the default constructors of the subobjects
are explicitly defaulted on first declaration, even if said
defaulted constructors are non-public.</P>

<P>See also <A HREF="
     cwg_defects.html#1149">issue 1149</A>.</P>

<P><B>Rationale (August, 2010):</B></P>

<P>The consensus of the CWG was that this change should not be
made at this point in the standardization process, but that it
might be considered at a later date.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>This issue is resolved by the resolution of <A HREF="
     cwg_defects.html#1135">issue 1135</A>.</P>

<BR><BR><HR><A NAME="1191"></A><H4>1191.
  
Deleted subobject destructors and implicitly-defined constructors
</H4><B>Section: </B>12.1&#160; [class.ctor]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-09-02<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>



<P>Consider the following example:</P>

<PRE>
    struct A {
       A();
       ~A() = delete;
    };

    struct B: A { };
    B* b = new B;
</PRE>

<P>Under the current rules, <TT>B()</TT> is not deleted, but is
ill-formed because it calls the deleted <TT>~A::A()</TT> if it exits
via an exception after the completion of the construction of
<TT>A</TT>. A deleted subobject destructor should be added to the list
of reasons for implicit deletion in 12.1 [class.ctor] and
12.8 [class.copy].</P>

<P><B>Notes from the November, 2010 meeting:</B></P>

<P>The CWG agreed that a change was needed, but only if one or more
base and/or member constructors are non-trivial.</P>

<P><B>Proposed resolution (January, 2011):</B></P>

<OL><LI><P>Add a new bullet to 12.1 [class.ctor] paragraph 5 as
follows:</P></LI>

<BLOCKQUOTE>

<P>...A defaulted default constructor for class <TT>X</TT> is defined
as deleted if:</P>

<UL><LI><P>...</P></LI>

<LI><P><TT>X</TT> is a non-union class and all members of any
anonymous union member are of const-qualified type (or array thereof),
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN></P></LI>

<LI><P>any direct or virtual base class, or non-static data member
with no <I>brace-or-equal-initializer</I>, has class type <TT>M</TT>
(or array thereof) and either <TT>M</TT> has no default constructor or
overload resolution (13.3 [over.match]) as applied to
<TT>M</TT>'s default constructor results in an ambiguity or in a
function that is deleted or inaccessible from the defaulted default
constructor<SPAN style="text-decoration:line-through;background-color:#FFA0A0">.</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">, or</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">any direct or virtual base class or non-static data member
has a type with a destructor that is deleted or inaccessible from the
defaulted default constructor.</SPAN></P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Add a new bullet to 12.8 [class.copy] paragraph 12 as
follows:</P></LI>

<BLOCKQUOTE>

<P>...A defaulted copy/move constructor for a class <TT>X</TT> is
defined as deleted (8.4.3 [dcl.fct.def.delete]) if X has:</P>

<UL><LI><P>a variant member with a non-trivial corresponding
constructor and <TT>X</TT> is a union-like class,</P></LI>

<LI><P>a non-static data member of class type <TT>M</TT> (or array
thereof) that cannot be copied/moved because overload resolution
(13.3 [over.match]), as applied to <TT>M</TT>'s corresponding
constructor, results in an ambiguity or a function that is deleted or
inaccessible from the defaulted constructor, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN></P></LI>

<LI><P>a direct or virtual base class <TT>B</TT> that cannot be
copied/moved because overload resolution (13.3 [over.match]),
as applied to <TT>B</TT>'s corresponding constructor, results in an
ambiguity or a function that is deleted or inaccessible from the
defaulted constructor, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">any direct or virtual base class or non-static data member
of a type with a destructor that is deleted or inaccessible from the
defaulted constructor,</SPAN></P></LI>

<LI><P>for the copy constructor, a non-static data member of rvalue
reference type, or</P></LI>

<LI><P>for the move constructor, a non-static data member or direct or
virtual base class with a type that does not have a move constructor
and is not trivially copyable.</P></LI>

</UL>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1237"></A><H4>1237.
  
Deprecated implicit copy assignment in example
</H4><B>Section: </B>12.2&#160; [class.temporary]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Ryou Ezoe
 &#160;&#160;&#160;

 <B>Date: </B>2011-01-25<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>An implicit declaration of a copy assignment operator is deprecated
if the class has a user-declared copy constructor or a user-declared
destructor.  However, the example in 12.2 [class.temporary] relies
on such an implicit declaration; an explicit declaration for the copy
assignment operator for class X should be provided:</P>

<PRE>
    class X {
    public:
      X(int);
      X(const X&amp;);
      ~X();
    };

    class Y {
    public:
      Y(int);
      Y(Y&amp;&amp;);
      ~Y();
    };

    X f(X);
    Y g(Y);

    void h() {
      X a(1);
      X b = f(X(2));
      Y c = g(Y(3));
      a = f(a);  //<SPAN style="font-family:Times;font-style:italic"> relies on implicitly-declared </SPAN>X::operator=(const X&amp;)
    }
</PRE>

<BR><BR><HR><A NAME="1029"></A><H4>1029.
  
Type of a destructor call
</H4><B>Section: </B>12.4&#160; [class.dtor]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Johannes Schaub
 &#160;&#160;&#160;

 <B>Date: </B>2010-02-08<BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>



<P>The Standard does not define the type of a destructor call.
Although that is not of any practical importance, it should do so as
a matter of completeness.  (5.2.4 [expr.pseudo] paragraph 1
defines the type of a pseudo-destructor call as <TT>void</TT>.)</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<P>Change 5.2.2 [expr.call] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">If the <I>postfix-expression</I> designates a
destructor (12.4 [class.dtor]), the type of the function call
expression is <TT>void</TT>; otherwise, the</SPAN> type of the function
call expression is the return type of the statically chosen function
(i.e., ignoring the <TT>virtual</TT> keyword), even if the type of the
function actually called is different. This type shall be a complete
object type, a reference type or the type <TT>void</TT>.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1081"></A><H4>1081.
  
Defaulted destructor and unusable operator delete
</H4><B>Section: </B>12.4&#160; [class.dtor]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-06-22<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>



<P>A defaulted destructor should be implicitly defined as deleted
if <TT>operator delete</TT> is deleted or inaccessible.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change 12.4 [class.dtor] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<P>...A defaulted destructor for a class <TT>X</TT> is defined as
deleted if:</P>

<UL><LI><P><TT>X</TT> is a union-like class that has a variant member
with a non-trivial destructor,</P></LI>

<LI><P>any of the non-static data members has class type <TT>M</TT>
(or array thereof) and <TT>M</TT> has a deleted destructor or a
destructor that is inaccessible from the defaulted destructor,
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN></P></LI>

<LI><P>any direct or virtual base class has a deleted destructor or a
destructor that is inaccessible from the defaulted
destructor<SPAN style="text-decoration:line-through;background-color:#FFA0A0">.</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">or, for a virtual destructor, lookup of the non-array
deallocation function results in an ambiguity or in a function that is
deleted or inaccessible from the defaulted destructor.</SPAN></P></LI>

</UL>

<P>A destructor is trivial if...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1146"></A><H4>1146.
  
<I>exception-specification</I>s of defaulted functions
</H4><B>Section: </B>12.4&#160; [class.dtor]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>GB
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-03<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#GB39">N3092 comment
  GB&#160;39<BR></A>
<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#GB41">N3092 comment
  GB&#160;41<BR></A>

<P>The note in 12.4 [class.dtor] paragraph 4 says,</P>

<BLOCKQUOTE>

An explictly defaulted definition has no implicit
<I>exception-specification</I>.

</BLOCKQUOTE>

<P>There are similar notes in 12.8 [class.copy] paragraphs
15 and 29.</P>

<P>However, 8.4.2 [dcl.fct.def.default] paragraph 2 bullet 4 says that
a special member function that is explicitly defaulted on its first
declaration</P>

<BLOCKQUOTE>

is implicitly considered to have the same
<I>exception-specification</I> as if it had been implicitly
declared (15.4 [except.spec])

</BLOCKQUOTE>

<P>The notes are incorrect.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<OL><LI><P>Change 12.4 [class.dtor] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

[<I>Note:</I> an implicitly- declared destructor has an
exception-specification (15.4).  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">An explictly defaulted
definition has no implicit
exception-specification.</SPAN> &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraph 15 as follows:</P></LI>

<BLOCKQUOTE>

[<I>Note:</I> an implicitly-declared copy/move constructor
has an exception-specification (15.4).  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">An
explicitly-defaulted definition (8.4.2) has no implicit
exception-specification.</SPAN> &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraph 29 as follows:</P></LI>

<BLOCKQUOTE>

[<I>Note:</I> An implicitly-declared copy/move assignment
operator has an exception- specification (15.4). <SPAN style="text-decoration:line-through;background-color:#FFA0A0">An
explicitly-defaulted definition has no implicit
exception-specification.</SPAN> &#8212;<I>end note</I>]

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1147"></A><H4>1147.
  
Destructors should be default <TT>nothrow</TT>
</H4><B>Section: </B>12.4&#160; [class.dtor]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>GB
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-03<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting as paper N3204.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#GB40">N3092 comment
  GB&#160;40<BR></A>
<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#CH9">N3092 comment
  CH&#160;9<BR></A>

<P>A user-declared destructor that does not supply an
exception specification should be considered as if declared
<TT>noexcept(true)</TT> rather than
<TT>noexcept(false)</TT>.</P>

<P>(Duplicate of <A HREF="
     cwg_defects.html#1123">issue 1123</A>.)</P>

<BR><BR><HR><A NAME="1241"></A><H4>1241.
  
Which members does a destructor destroy?
</H4><B>Section: </B>12.4&#160; [class.dtor]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Ryou Ezoe
 &#160;&#160;&#160;

 <B>Date: </B>2011-02-08<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>The current wording of 12.4 [class.dtor] paragraph 7 says,</P>

<BLOCKQUOTE>

After executing the body of the destructor and destroying any
automatic objects allocated within the body, a destructor for class
<TT>X</TT> calls the destructors for <TT>X</TT>'s direct non-variant
members...

</BLOCKQUOTE>

<P>This is incorrect; it is only the non-static members that are
destroyed.</P>

<BR><BR><HR><A NAME="655"></A><H4>655.
  
Initialization not specified for forwarding constructors
</H4><B>Section: </B>12.6.2&#160; [class.base.init]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>17 October 2007<BR>


<P>[Voted into WP at August, 21010 meeting.]</P>



<P>The changes for delegating constructors overlooked the need to
change 12.6.2 [class.base.init] paragraph 3:</P>

<BLOCKQUOTE>

<P>The <I>expression-list</I> in a <I>mem-initializer</I> is used to
initialize the base class or non-static data member subobject denoted
by the <I>mem-initializer-id</I>. The semantics of
a <I>mem-initializer</I> are as follows:</P>

<UL>
<LI><P>if the <I>expression-list</I> of the <I>mem-initializer</I> is
omitted, the base class or member subobject is value-initialized (see
8.5 [dcl.init]);</P></LI>

<LI><P>otherwise, the subobject indicated
by <I>mem-initializer-id</I> is direct-initialized using
<I>expression-list</I> as the <I>initializer</I> (see 8.5 [dcl.init]).</P></LI>
</UL>

<P>The initialization of each base and member constitutes a
full-expression. Any expression in a <I>mem-initializer</I> is
evaluated as part of the full-expression that performs the
initialization.</P>

</BLOCKQUOTE>

<P>This paragraph deals only with subobjects; it needs to be made more
general to apply to the complete object as well when
the <I>mem-initializer-id</I> designates the constructor's class.</P>

<P><B>Proposed resolution (June, 2008):</B></P>

<P>Change 12.6.2 [class.base.init] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">The <I>expression-list</I> in a <I>mem-initializer</I> is used
to initialize the base class or non-static data member subobject
denoted by the <I>mem-initializer-id</I>. The semantics of a
<I>mem-initializer</I> are</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">A <I>mem-initializer</I> in which the
<I>mem-initializer-id</I> names the constructor's class initializes the
object by invoking the selected target constructor with the
<I>mem-initializer</I>'s <I>expression-list</I>. A
<I>mem-initializer</I> in which the <I>mem-initializer-id</I> names a base
class or non-static data member initializes the designated subobject</SPAN>
as follows:</P>

<UL><LI><P>if the <I>expression-list</I> of the <I>mem-initializer</I>
is omitted, the base class or member subobject is value-initialized
(see 8.5 [dcl.init]);</P></LI>

<LI><P>otherwise, the subobject indicated by <I>mem-initializer-id</I> is
direct-initialized using <I>expression-list</I> as the initializer (see
8.5 [dcl.init]).</P></LI>

</UL>

<P>...</P>

<P>The initialization <SPAN style="text-decoration:line-through;background-color:#FFA0A0">of each base and member</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">performed by
each <I>mem-initializer</I></SPAN> constitutes a full-expression. Any
expression...</P>

</BLOCKQUOTE>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>This text was significantly modified by N2756 (nonstatic data
member initializers) and needs to be reworked in light of those
changes.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<OL><LI><P>Change 12.6.2 [class.base.init] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

<P>The <I>expression-list</I> or <I>braced-init-list</I> in a
<I>mem-initializer</I> is used to initialize the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">base class
or non-static data member subobject denoted by the
<I>mem-initializer-id</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">designated subobject (or, in
the case of a delegating constructor, the complete class
object)</SPAN> according to the initialization rules of
8.5 [dcl.init] for direct-initialization.</P>

<P>[<I>Example: ...</I></P>

<P>&#8212;<I>end example</I>] The initialization <SPAN style="text-decoration:line-through;background-color:#FFA0A0">of each base and
member</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">performed by each <I>mem-initializer</I></SPAN>
constitutes a full-expression...</P>

</BLOCKQUOTE>

<LI><P>Change 12.6.2 [class.base.init] paragraph 8 as
follows:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">If</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">In a non-delegating constructor, if</SPAN> a given
non-static data member or base class is not named by a
<I>mem-initializer-id</I>...

</BLOCKQUOTE>

<LI><P>Change 12.6.2 [class.base.init] paragraph 10 as follows:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Initialization</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">In a non-delegating constructor,
initialization</SPAN> proceeds in the following order:

</BLOCKQUOTE>

<LI><P>Change 12.6.2 [class.base.init] paragraph 12 as follows
(this is an unrelated change correcting an error noticed while
preparing the resolution of this issue):</P></LI>

<BLOCKQUOTE>

Names in the <I>expression-list</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">or
<I>braced-init-list</I></SPAN> of a <I>mem-initializer</I> are
evaluated in the scope of the constructor...

</BLOCKQUOTE>

<LI><P>Change the next-to-last bullet of the note in 8.5.4 [dcl.init.list] paragraph 1 as follows:</P></LI>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">as a base-or-member initializer</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">in a
<I>mem-initializer</I></SPAN> (12.6.2 [class.base.init])
</P></LI></UL>

</OL>

<BR><BR><HR><A NAME="838"></A><H4>838.
  
Use of <TT>this</TT> in a <I>brace-or-equal-initializer</I>
</H4><B>Section: </B>12.6.2&#160; [class.base.init]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>12 March, 2009<BR>


<P>References to non-static data members inside the body of a non-static
member function (which includes the <I>mem-initializer</I>s of a
constructor definition) are implicitly transformed to member access
expressions using <TT>(*this)</TT> (9.3.1 [class.mfct.non-static]
paragraph 3).  Although 5.1.1 [expr.prim.general] paragraph 3
permits use of <TT>this</TT> in a <I>brace-or-equal-initializer</I>
for a non-static data member, 12.6.2 [class.base.init] does not
give details about the value of <TT>this</TT> in that context, and
there is no parallel to the transformation of member references into
class member access expressions. This leaves use of non-static data
members in this context underspecified.</P>

<P><B>Proposed resolution (March, 2011):</B></P>

<P>This issue is resolved by the resolution of issues
<A HREF="
     cwg_defects.html#1017">1017</A> and <A HREF="
     cwg_defects.html#1207">1207</A>
in document N3282.</P>

<BR><BR><HR><A NAME="1242"></A><H4>1242.
  
Initializing variant class members
</H4><B>Section: </B>12.6.2&#160; [class.base.init]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Ryou Ezoe
 &#160;&#160;&#160;

 <B>Date: </B>2011-02-08<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>The current wording of 12.6.2 [class.base.init] paragraph 5 says,</P>

<BLOCKQUOTE>

A <I>ctor-initializer</I> may initialize the member of an anonymous union
that is a member of the constructor's class.

</BLOCKQUOTE>

<P>The wording &#8220;the member&#8221; is strange; furthermore, this
should be restricted to non-static data members.  That could be
accomplished by using the existing term &#8220;variant members,&#8221;
which is defined in 9.5 [class.union] paragraph 8 to be
&#8220;the non-static data members of all anonymous unions that are
members of&#8221; the class (which by definition must be non-static
data members, since a storage class specifier is not allowed on an
anonymous union in class scope).</P>

<BR><BR><HR><A NAME="1202"></A><H4>1202.
  
Calling virtual functions during destruction
</H4><B>Section: </B>12.7&#160; [class.cdtor]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Bjarne Stroustrup
 &#160;&#160;&#160;

 <B>Date: </B>2010-09-21<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>According to 12.7 [class.cdtor] paragraph 4,</P>

<BLOCKQUOTE>

Member functions, including virtual functions (10.3 [class.virtual]), can be called during construction or destruction
(12.6.2 [class.base.init]).  When a virtual function is called
directly or indirectly from a constructor (including the
<I>mem-initializer</I> or <I>brace-or-equal-initializer</I> for a
non-static data member) or from a destructor, and the object to which
the call applies is the object under construction or destruction, the
function called is the one defined in the constructor or
destructor's own class or in one of its bases, but not a function
overriding it in a class derived from the constructor or
destructor's class, or overriding it in one of the other base
classes of the most derived object (1.8 [intro.object]).

</BLOCKQUOTE>

<P>This is clear regarding virtual functions called during the
initialization of a class's members, but it does not specifically
address the polymorphic behavior of the class during the destruction
of the members.  Presumably the behavior during destruction should
be the exact inverse of that of the constructor, i.e., the class's
virtual functions should still be called during member
destruction.</P>

<P>In addition, the wording</P>

<BLOCKQUOTE>

If the virtual function call uses an explicit class member access
(5.2.5 [expr.ref]) and the object-expression refers to the
object under construction or destruction but its type is neither the
constructor or destructor's own class or one of its bases, the
result of the call is undefined.

</BLOCKQUOTE>

<P>should be clarified that &#8220;refers to the object under
construction&#8221; does not include referring to member
subobjects but only to base or more-derived classes of the class
under construction or destruction.</P>

<BR><BR><HR><A NAME="1020"></A><H4>1020.
  
Implicitly-defined copy constructors and explicit base class constructors
</H4><B>Section: </B>12.8&#160; [class.copy]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Niels Dekker
 &#160;&#160;&#160;

 <B>Date: </B>2010-01-12<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#FI19">N3092 comment
  FI&#160;19<BR></A>



<P>It is not clear whether the current specification allows a defaulted
copy constructor to call an explicit constructor to copy a base or
member subobject, and if so, whether that is desirable or not.  See also
issues <A HREF="
     cwg_defects.html#535">535</A> and
<A HREF="
     cwg_closed.html#1118">1118</A>.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#1051">issue 1051</A>.</P>

<BR><BR><HR><A NAME="1051"></A><H4>1051.
  
Reference members and generated copy constructors
</H4><B>Section: </B>12.8&#160; [class.copy]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>2010-03-11<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US62">N3092 comment
  US&#160;62<BR></A>

<P>The new wording describing generated copy constructors
(12.8 [class.copy] paragraph 16) does not describe the
initialization of members with reference type.</P>

<P>See also <A HREF="
     cwg_closed.html#992">issue 992</A>.</P>

<P><B>Proposed resolution (October, 2010):</B></P>

<OL><LI><P>Change 12.8 [class.copy] paragraph 12 as follows:</P></LI>

<BLOCKQUOTE>

<P>An implicitly-declared copy/move constructor is an <TT>inline
public</TT> member of its class. A defaulted copy/move constructor for
a class <TT>X</TT> is defined as deleted (8.4.3 [dcl.fct.def.delete])
if <TT>X</TT> has:</P>

<UL><LI><P>a variant member with a non-trivial corresponding
constructor and <TT>X</TT> is a union-like class,</P></LI>

<LI><P>a non-static data member of class type <TT>M</TT> (or array
thereof) that cannot be copied/moved because overload resolution
(13.3 [over.match]), as applied to <TT>M</TT>'s corresponding
constructor, results in an ambiguity or a function that is deleted or
inaccessible from the defaulted constructor, or</P></LI>

<LI><P>a direct or virtual base class <TT>B</TT> that cannot be
copied/moved because overload resolution (13.3 [over.match]),
as applied to <TT>B</TT>'s corresponding constructor, results in an
ambiguity or a function that is deleted or inaccessible from the
defaulted constructor, or</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">for the copy constructor, a non-static data member of
rvalue reference type, or</SPAN></P></LI>

<LI><P>for the move constructor, a non-static data member or direct or
virtual base class with a type that does not have a move constructor
and is not trivially copyable.</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraph 16 as follows:</P></LI>

<BLOCKQUOTE>

<P>The implicitly-defined copy<SPAN style="font-weight:bold;background-color:#A0FFA0">/move</SPAN> constructor for a
non-union class <TT>X</TT> performs a memberwise copy<SPAN style="font-weight:bold;background-color:#A0FFA0">/move</SPAN>
of its <SPAN style="text-decoration:line-through;background-color:#FFA0A0">subobjects</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">bases and members</SPAN>.
[<I>Note:</I> <I>brace-or-equal-initializer</I>s of non-static data
members are ignored.  See also the example in 12.6.2 [class.base.init]. &#8212;<I>end note</I>] The order of
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">copying</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">initialization</SPAN> is the same as the order
of initialization of bases and members in a user-defined constructor
(see 12.6.2 [class.base.init]). <SPAN style="font-weight:bold;background-color:#A0FFA0">Let <TT>x</TT> be either the
parameter of the constructor or, for the move constructor, an xvalue
referring to the parameter.</SPAN> Each <SPAN style="text-decoration:line-through;background-color:#FFA0A0">subobject</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">base
or non-static data member</SPAN> is copied<SPAN style="font-weight:bold;background-color:#A0FFA0">/moved</SPAN> in the
manner appropriate to its type:</P>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">if the subobject is of class type, the copy
constructor for the class is used;</SPAN></P></LI>

<LI><P>if the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">subobject</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">member</SPAN> is an array, each
element is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">copied, in the manner appropriate to the element
type</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">direct-initialized with the corresponding subobject of
<TT>x</TT></SPAN>;</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">if a member <TT>m</TT> has rvalue reference type
<TT>T&amp;&amp;</TT>, it is direct-initialized with
<TT>static_cast&lt;T&amp;&amp;&gt;(x.m);</TT></SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">otherwise, the base or member is direct-initialized with
the corresponding base or member of <TT>x</TT>.</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">if the subobject is of scalar type, the built-in
assignment operator is used.</SPAN></P></LI>

</UL>

<P>Virtual base class subobjects shall be <SPAN style="text-decoration:line-through;background-color:#FFA0A0">copied</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">initialized</SPAN> only once by the implicitly-defined
copy<SPAN style="font-weight:bold;background-color:#A0FFA0">/move</SPAN> constructor (see 12.6.2 [class.base.init]).</P>

</BLOCKQUOTE>

<LI><P>Delete 12.8 [class.copy] paragraph 17:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">The implicitly-defined move constructor for a non-union class
<TT>X</TT> performs a memberwise move of its subobjects.
[<I>Note:</I> <I>brace-or-equal-initializer</I>s of non-static data
members are ignored.  See also the example in 12.6.2 [class.base.init]. &#8212;<I>end note</I>] The order of moving is the
same as the order of initialization of bases and members in a
user-defined constructor (see 12.6.2 [class.base.init]). Given a
parameter named <TT>x</TT>, each base or non-static data member is
moved in the manner appropriate to its type:</SPAN></P>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">a named member <TT>m</TT> of reference or class
type <TT>T</TT> is direct-initialized with the expression
<TT>static_cast&lt;T&amp;&amp;&gt;(x.m)</TT>;</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">a base class <TT>B</TT> is direct-initialized with
the expression
<TT>static_cast&lt;B&amp;&amp;&gt;(x)</TT>;</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">an array is initialized by moving each element in the
manner appropriate to the element type;</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">a scalar type is initialized with the built-in
assignment operator.</SPAN></P></LI>

</UL>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">Virtual base class subobjects shall be moved only once by
the implicitly-defined move constructor (see 12.6.2 [class.base.init]).</SPAN></P>

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraph 18 as follows:</P></LI>

<BLOCKQUOTE>

The implicitly-defined copy<SPAN style="font-weight:bold;background-color:#A0FFA0">/move</SPAN> constructor for
a union <TT>X</TT> copies the object representation
(3.9 [basic.types]) of <TT>X</TT>.

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraph 28 as follows:</P></LI>

<BLOCKQUOTE>

A copy/move assignment operator that is defaulted and not defined as
deleted is <I>implicitly defined</I> when <SPAN style="text-decoration:line-through;background-color:#FFA0A0">is assigned a value of
its class type or a value of a class type derived from its class
type</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">it is used (3.2 [basic.def.odr]) (e.g., when it
is selected by overload resolution to assign to</SPAN> an object of its
class type<SPAN style="font-weight:bold;background-color:#A0FFA0">)</SPAN> or when it is explicitly defaulted after its
first declaration.

</BLOCKQUOTE>

<LI><P>Change 12.8 [class.copy] paragraph 30 as follows:</P></LI>

<BLOCKQUOTE>

<P>The implicitly-defined copy<SPAN style="font-weight:bold;background-color:#A0FFA0">/move</SPAN> assignment operator for
a non-union class <TT>X</TT> performs memberwise copy<SPAN style="font-weight:bold;background-color:#A0FFA0">/move</SPAN>
assignment of its subobjects. The direct base classes of <TT>X</TT>
are assigned first, in the order of their declaration in the
<I>base-specifier-list</I>, and then the immediate non-static data
members of <TT>X</TT> are assigned, in the order in which they were
declared in the class definition. <SPAN style="font-weight:bold;background-color:#A0FFA0">Let <TT>x</TT> be either the
parameter of the function or, for the move assignment operator, an
xvalue referring to the parameter.</SPAN> Each subobject is assigned in
the manner appropriate to its type:</P>

<UL><LI><P>if the subobject is of class type, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the copy assignment
operator for the class is used</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">as if by a call to
<TT>operator=</TT> with the subobject as the object expression and the
corresponding subobject of <TT>x</TT> as a single function
argument</SPAN> (as if by explicit qualification; that is, ignoring any
possible virtual overriding functions in more derived
classes);</P></LI>

<LI><P>if the subobject is an array, each element is assigned, in the
manner appropriate to the element type;</P></LI>

<LI><P>if the subobject is of scalar type, the built-in assignment
operator is used.</P></LI>

</UL>

<P>It is unspecified whether subobjects representing virtual base
classes are assigned more than once by the implicitly-defined copy
assignment operator. [<I>Example:</I></P>

<PRE>
  struct V { };
  struct A : virtual V { };
  struct B : virtual V { };
  struct C : B, A { };
</PRE>

<P>It is unspecified whether the virtual base class subobject
<TT>V</TT> is assigned twice by the implicitly-defined copy assignment
operator for <TT>C</TT>. &#8212;<I>end example</I>] <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I>
This does not apply to move assignment, as a defaulted move assignment
operator is deleted if the class has virtual bases. &#8212;<I>end
note</I>]</SPAN></P>

</BLOCKQUOTE>

<LI><P>Delete 12.8 [class.copy] paragraph 31:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">The implicitly-defined move assignment operator for a
non-union class <TT>X</TT> performs memberwise assignment of its
subobjects.  The direct base classes of <TT>X</TT> are assigned first,
in the order of their declaration in the <I>base-specifier-list</I>,
and then the immediate non-static data members of <TT>X</TT> are
assigned, in the order in which they were declared in the class
definition.  Given a parameter named <TT>x</TT>, each subobject is
assigned in the manner appropriate to its type:</SPAN></P>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">if the subobject is a named member <TT>c</TT> of class type
<TT>C</TT>, as if by the expression <TT>this-&gt;c =
static_cast&lt;C&amp;&amp;&gt;(x.c)</TT>;</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">if the subobject is a direct base class <TT>B</TT>, as if by
the expression
<TT>this-&gt;B::operator=(static_cast&lt;B&amp;&amp;&gt;(x))</TT>;</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">if the subobject is an array, each element is moved, in the
manner appropriate to the element type;</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">if the subobject is of scalar type, the built-in assignment
operator is used.</SPAN></P></LI>

</UL>

</BLOCKQUOTE>

</OL>

<P>This resolution also resolves issues <A HREF="
     cwg_defects.html#1020">1020</A>,
<A HREF="
     cwg_defects.html#1064">1064</A> and <A HREF="
     cwg_defects.html#1066">1066</A>.</P>

<BR><BR><HR><A NAME="1064"></A><H4>1064.
  
Defaulted move constructor for a union
</H4><B>Section: </B>12.8&#160; [class.copy]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>2010-03-23<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US63">N3092 comment
  US&#160;63<BR></A>

<P>The new wording in 12.8 [class.copy] specifies the behavior
of an implicitly-defined copy constructor for a non-union class
(paragraph 16), an implicitly-defined move constructor for a non-union
class (paragraph 17), and an implicitly-defined copy constructor for a
union (paragraph 18), but not an implicitly-defined move constructor for
a union.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#1051">issue 1051</A>.</P>

<BR><BR><HR><A NAME="1066"></A><H4>1066.
  
When is a copy/move assignment operator implicitly defined?
</H4><B>Section: </B>12.8&#160; [class.copy]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>2010-03-24<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US64">N3092 comment
  US&#160;64<BR></A>

<P>According to 12.8 [class.copy] paragraph 28,</P>

<BLOCKQUOTE>

A copy/move assignment operator that is defaulted and not defined
as deleted is <I>implicitly defined</I> when an object of its
class type is assigned a value of its class type or a value of a
class type derived from its class type or when it is explicitly
defaulted after its first declaration.

</BLOCKQUOTE>

<P>This sounds as if any assignment to a class object, regardless
of whether it is a copy or a move assignment, defines both the
copy and move operators.  Presumably an assignment should only
define the assignment operator chosen by overload resolution for
the operation.  (Compare the corresponding wording in paragraph 14
for the copy/move constructors: &#8220;...<I>implicitly defined</I>
if it is used to initialize an object of its class type...&#8221;)</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#1051">issue 1051</A>.</P>

<BR><BR><HR><A NAME="1080"></A><H4>1080.
  
Confusing relationship between templates and copy constructors
</H4><B>Section: </B>12.8&#160; [class.copy]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-06-19<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>



<P>12.8 [class.copy] paragraphs 6-7 currently read,</P>

<BLOCKQUOTE>

<P>A declaration of a constructor for a class <TT>X</TT> is ill-formed
if its first parameter is of type (optionally cv-qualified) <TT>X</TT>
and either there are no other parameters or else all other parameters
have default arguments.</P>

<P> A member function template is never instantiated to perform the
copy of a class object to an object of its class
type. [<I>Example:</I></P>

<PRE>
    struct S {
        template&lt;typename T&gt; S(T);
        template&lt;typename T&gt; S(T&amp;&amp;);
        S();
    };

    S f();
    const S g;

    void h() {
        S a( f() ); //<SPAN style="font-family:Times;font-style:italic"> does not instantiate member template;</SPAN>
                    //<SPAN style="font-family:Times;font-style:italic"> uses the implicitly generated move constructor</SPAN>
        S a(g);     //<SPAN style="font-family:Times;font-style:italic"> does not instantiate the member template;</SPAN>
                    //<SPAN style="font-family:Times;font-style:italic"> uses the implicitly generated copy constructor</SPAN>
    }
</PRE>

</BLOCKQUOTE>

<P>These paragraphs were previously a single paragraph, and the second
sentence was intended to mean that</P>

<PRE>
    template &lt;class T&gt; A(T):
</PRE>

<P>will never be instantiated to produce <TT>A(A)</TT>.  It should
not have been split and the example should not have been amended to
include move construction.</P>

<P><U>Lawrence Crowl</U>: I suggest something along the lines of</P>

<BLOCKQUOTE>

A member function template is never instantiated to match the
signature of an ill-formed constructor.

</BLOCKQUOTE>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Merge 12.8 [class.copy] paragraphs 6 and 7 and change the
text as follows:</P>

<BLOCKQUOTE>

<P>A declaration of a constructor for a class <TT>X</TT> is ill-formed
if its first parameter is of type (optionally cv-qualified) <TT>X</TT>
and either there are no other parameters or else all other parameters
have default arguments.  A member function template is never
instantiated to <SPAN style="text-decoration:line-through;background-color:#FFA0A0">perform the copy of a class object to an object
of its class type</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">produce such a constructor
signature</SPAN>. [<I>Example:</I></P>

<PRE>
  struct S {
    template&lt;typename T&gt; S(T);
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">    template&lt;typename T&gt; S(T&amp;&amp;);</SPAN>
    S();
  };

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">  S f();</SPAN>
  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">const</SPAN> S g;

  void h() {
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">    S a( f() ); //<SPAN style="font-family:Times;font-style:italic"> does not instantiate member template;</SPAN>
                //<SPAN style="font-family:Times;font-style:italic"> uses the implicitly generated move constructor</SPAN></SPAN>
    S a(g);     //<SPAN style="font-family:Times;font-style:italic"> does not instantiate the member template <SPAN style="font-weight:bold;background-color:#A0FFA0">to produce </SPAN></SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">S::S&lt;S&gt;(S)</SPAN><SPAN style="font-family:Times;font-style:italic">;</SPAN>
                //<SPAN style="font-family:Times;font-style:italic"> uses the implicitly <SPAN style="text-decoration:line-through;background-color:#FFA0A0">generated</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">declared</SPAN> copy constructor</SPAN>
}
</PRE>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1082"></A><H4>1082.
  
Implicit copy function if subobject has none?
</H4><B>Section: </B>12.8&#160; [class.copy]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-06-22<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>It seems odd to have an implicitly declared copy constructor (and
the same for the copy assignment operator) if one of the subobjects
does not have one.  For example,</P>

<PRE>
    struct A {
       A();
       A(A&amp;&amp;);
    };

    struct B: A { };

    B b;
    B b2(b); //<SPAN style="font-family:Times;font-style:italic"> error when implicitly defining </SPAN>B(B&amp;)<SPAN style="font-family:Times;font-style:italic">, should not be declared</SPAN>
</PRE>

<P>If we don't declare it in that case, we need to decide what happens
if one base has only a move constructor and another has only a copy
constructor.</P>

<P><B>Notes from the November, 2010 meeting:</B></P>

<P>The consensus of the CWG was to change the behavior so that all
classes have a declaration of a copy constructor, but that it is
defined as deleted in the cases where the declaration is omitted
by the current rules.</P>

<BR><BR><HR><A NAME="1148"></A><H4>1148.
  
Copy elision and move construction of function parameters
</H4><B>Section: </B>12.8&#160; [class.copy]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>DE
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-03<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#DE11">N3092 comment
  DE&#160;11<BR></A>

<P>It is unclear whether copy elision is permitted when returning a
parameter of class type.  If not, it should still be possible to
move, rather than copy, the return value.</P>

<P><U>Suggested resolution</U>: Amend paragraph 34 to
explicitly exclude function parameters from copy
elision. Amend paragraph 35 to include function parameters
as eligible for move-construction.</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<OL><LI><P>Change 12.8 [class.copy] paragraph 34 bullets 1 and 2
as follows:</P></LI>

<UL><LI><P>in a <TT>return</TT> statement in a function with a class
return type, when the expression is the name of a non-volatile
automatic object <SPAN style="font-weight:bold;background-color:#A0FFA0">(other than a function or catch-clause
parameter)</SPAN> with the same cv-unqualified type as the function
return type, the copy/move operation can be omitted by constructing
the automatic object directly into the function's return
value</P></LI>

<LI><P>in a <I>throw-expression</I>, when the operand is the name of a
non-volatile automatic object <SPAN style="font-weight:bold;background-color:#A0FFA0">(other than a function or
catch-clause parameter)</SPAN> whose scope does not extend beyond the
end of the innermost enclosing <I>try-block</I> (if there is one), the
copy/move operation from the operand to the exception object
(15.1 [except.throw]) can be omitted by constructing the
automatic object directly into the exception object</P></LI>

</UL>

<P>Change 12.8 [class.copy] paragraph 35 as follows:</P>

<BLOCKQUOTE>

When the criteria for elision of a copy operation are met<SPAN style="font-weight:bold;background-color:#A0FFA0">, or
would be met save for the fact that the source object is a function
parameter,</SPAN> and the object to be copied is designated by an
lvalue, overload resolution...

</BLOCKQUOTE>

</OL>

<I>[Drafting note: the change to paragraph 35 intentionally omits
catch-clause parameters out of concern that a rethrow during the
move would throw a stripped exception object.  This should not be
problematic in most cases, since exception objects are typically
small.]</I>

<BR><BR><HR><A NAME="1149"></A><H4>1149.
  
Trivial non-public copy operators in subobjects
</H4><B>Section: </B>12.8&#160; [class.copy]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>FI
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-03<BR><BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#FI5">N3092 comment
  FI&#160;5<BR></A>

<P>A class with a non-public explicitly-defaulted copy
constructor isn't ever trivially copyable under the current
rules. If such a class is used as a subobject, the copy
constructor of the aggregating class should be trivial if it
can access the non-public explicitly defaulted copy
constructor of a subobject.</P>

<P>See also <A HREF="
     cwg_defects.html#1145">issue 1145</A>.</P>

<P><B>Rationale (August, 2010):</B></P>

<P>The consensus of the CWG was that this change should not be
made at this point in the standardization process, but that it
might be considered at a later date.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>This issue is resolved by the resolution of <A HREF="
     cwg_defects.html#1135">issue 1135</A>.</P>

<BR><BR><HR><A NAME="1224"></A><H4>1224.
  
<TT>constexpr</TT> defaulted copy constructors
</H4><B>Section: </B>12.8&#160; [class.copy]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-10-25<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>12.1 [class.ctor] allows for a defaulted default
constructor to be <TT>constexpr</TT>, but 12.8 [class.copy]
does not do the same for a defaulted copy constructor.  This seems
wrong.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change 12.8 [class.copy] paragraph 14 as follows:</P>

<BLOCKQUOTE>

A copy/move constructor that is defaulted and not defined as deleted
is <I>implicitly defined</I> if it is odr-used (3.2 [basic.def.odr]) to initialize an object of its class type from a copy of
an object of its class type or of a class type derived from its class
type<SUP>123</SUP> or when it is explicitly defaulted after its first
declaration.  [<I>Note:</I> the copy/move constructor is implicitly
defined even if the implementation elided its odr-use (3.2 [basic.def.odr], 12.2 [class.temporary]). &#8212;<I>end note</I>]
<SPAN style="font-weight:bold;background-color:#A0FFA0">If the implicitly-defined constructor would satisfy the
requirements of a <TT>constexpr</TT> constructor (7.1.5 [dcl.constexpr]), the implicitly-defined constructor is
<TT>constexpr</TT>.</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1016"></A><H4>1016.
  
Overloadable declarations, function templates, and references
</H4><B>Section: </B>13&#160; [over]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Johannes Schaub
 &#160;&#160;&#160;

 <B>Date: </B>2009-12-27<BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<P>According to 13 [over] paragraph 1,</P>

<BLOCKQUOTE>

Only function declarations can be overloaded; object and
type declarations cannot be overloaded.

</BLOCKQUOTE>

<P>There are two problems with this statement.  First, it does not allow
for overloading function templates.  (There may be other places in the
Standard that refer to &#8220;functions&#8221; but should include
function templates, as well.)</P>

<P>Second, the restriction on &#8220;object&#8221; declarations should
presumably be on &#8220;variable&#8221; declarations instead, since one
can also not overload reference declarations.</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<P>Change 13 [over] paragraph 1 as follows:</P>

<BLOCKQUOTE>

...Only function <SPAN style="font-weight:bold;background-color:#A0FFA0">and function template</SPAN> declarations can be
overloaded; <SPAN style="text-decoration:line-through;background-color:#FFA0A0">object</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">variable</SPAN> and type
declarations cannot be overloaded.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1087"></A><H4>1087.
  
Additional applications of issue 899
</H4><B>Section: </B>13.3.1.4&#160; [over.match.copy]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-06-25<BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>



<P>The resolution of <A HREF="
     cwg_defects.html#899">issue 899</A> needs to be
extended to cover move constructors and template constructors as well.
</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<UL><LI><P>When the type of the initializer expression is a class type
&#8220;<I>cv</I> <TT>S</TT>&#8221;, the non-explicit conversion
functions of <TT>S</TT> and its base classes are considered. When
initializing a temporary to be bound to the first parameter of a
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">copy</SPAN> constructor <SPAN style="text-decoration:line-through;background-color:#FFA0A0">(12.8 [class.copy])</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">that takes a reference to possibly cv-qualified <TT>T</TT> as its
first argument,</SPAN> called with a single argument in the context of
direct-initialization, explicit conversion functions are also
considered.  Those that are not hidden within <TT>S</TT> and yield a
type whose cv-unqualified version is the same type as <TT>T</TT> or is
a derived class thereof are candidate functions.  Conversion functions
that return &#8220;reference to <TT>X</TT>&#8221; return lvalues or
xvalues, depending on the type of reference, of type <TT>X</TT> and
are therefore considered to yield <TT>X</TT> for this process of
selecting candidate functions.</P></LI></UL>

<P>For example</P>

<PRE>
    struct C {
       template &lt;class T = int&gt; C(C&amp;, T = 0);
    };

    struct A {
       explicit operator C&amp;() const;
    };

    int main() {
       A a;
       C c (a); //<SPAN style="font-family:Times;font-style:italic"> should use template constructor</SPAN>
    }
</PRE>

<BR><BR><HR><A NAME="1151"></A><H4>1151.
  
Overload resolution with initializer-list and non-list constructors
</H4><B>Section: </B>13.3.1.7&#160; [over.match.list]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-03<BR><BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US66">N3092 comment
  US&#160;66<BR></A>

<P>Overload resolution should first look for a viable list
constructor, then look for a non-list constructor if no list
constructor is viable.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<OL><LI><P>Change 8.5.4 [dcl.init.list] paragraph 3 bullet 5
as follows:</P></LI>

<UL><LI><P>Otherwise, if <TT>T</TT> is a class type,
constructors are considered. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">If <TT>T</TT> has an
initializer-list constructor, the argument list consists of
the initializer list as a single argument; otherwise, the
argument list consists of the elements of the initializer
list.</SPAN> The applicable constructors are enumerated
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">(13.3.1.7 [over.match.list])</SPAN> and the best one
is chosen through overload resolution (<SPAN style="font-weight:bold;background-color:#A0FFA0">13.3.1.7 [over.match.list],</SPAN> 13.3 [over.match]). If a
narrowing conversion (see below) is required to convert any
of the arguments, the program is ill-formed.
[<I>Example:</I>...</P></LI></UL>

<LI><P>Change 13.3.1.7 [over.match.list] as follows:</P></LI>

<BLOCKQUOTE>

<P>When objects of non-aggregate class type
<SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>T</TT></SPAN> are list-initialized (8.5.4 [dcl.init.list]), overload resolution selects the constructor
<SPAN style="font-weight:bold;background-color:#A0FFA0">in two phases</SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">as follows, where <TT>T</TT> is the cv-unqualified class
type of the object being initialized</SPAN>:</P>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">If <TT>T</TT> has an initializer-list
constructor (8.5.4 [dcl.init.list]),</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">Initially, the candidate functions are the
initializer-list constructors (8.5.4 [dcl.init.list])
of the class <TT>T</TT> and</SPAN> the argument list consists
of the initializer list as a single argument<SPAN style="font-weight:bold;background-color:#A0FFA0">.</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">; otherwise,</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">If no viable
initializer-list constructor is found, overload resolution is
performed again, where the candidate functions are all the
constructors of the class <TT>T</TT> and</SPAN> the
argument list consists of the elements of the initializer
list.</P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">For direct-list-initialization, the candidate
functions are all the constructors of the class
<TT>T</TT>.</SPAN></P></LI>

</UL>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">For</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">In</SPAN>
copy-list-initialization, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the candidate functions are
all the constructors of <TT>T</TT>.  However,</SPAN> if an
<TT>explicit</TT> constructor is chosen, the initialization
is ill-formed. [<I>Note:</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">This differs from other
situations (13.3.1.3 [over.match.ctor], 13.3.1.4 [over.match.copy]), where only converting constructors are
considered for copy-initialization.</SPAN> This restriction
only applies if this initialization is part of the final
result of overload resolution<SPAN style="font-weight:bold;background-color:#A0FFA0">.</SPAN> &#8212;<I>end
note</I>]</P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1229"></A><H4>1229.
  
Overload resolution with empty <I>braced-init-list</I> argument
</H4><B>Section: </B>13.3.1.7&#160; [over.match.list]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Johannes Schaub
 &#160;&#160;&#160;

 <B>Date: </B>2010-12-09<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>The changes for <A HREF="
     cwg_defects.html#990">issue 990</A> did not address
the description of overload resolution when an argument is an empty
<I>braced-init-list</I>.  For example:</P>

<PRE>
    struct A {
      A();
      A(std::initializer_list&lt;int&gt;);
      A(std::initializer_list&lt;double&gt;);
    };

    A a{};       //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>

    void f(A);

    void g() {
      f({});     //<SPAN style="font-family:Times;font-style:italic"> ambiguous</SPAN>
    }
</PRE>

<BR><BR><HR><A NAME="1152"></A><H4>1152.
  
Rules for determining existence of implicit conversion sequence
</H4><B>Section: </B>13.3.2&#160; [over.match.viable]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-03<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US67">N3092 comment
  US&#160;67<BR></A>

<P>To determine whether there is an implicit conversion
sequence that converts the argument to the corresponding
parameter, 13.3.2 [over.match.viable] paragraph 3 uses
13.3.3.1 [over.best.ics] instead of just saying
&#8220;there is an ICS if-and-only-if a copy initialization
would be well-formed.&#8221; Apparently this is intended,
but to a casual reader or an implementor reading these rules
for the first time for a new implementation, it's not clear
why that's desirable. A note should be added to explain the
rationale.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change 13.3.3.1.4 [over.ics.ref] paragraph 3 as follows:</P>

<BLOCKQUOTE>

Except for an implicit object parameter, for which see
13.3.1 [over.match.funcs], a standard conversion sequence
cannot be formed if it requires binding an lvalue reference
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">to non-const</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">other than a reference to a non-volatile
const type</SPAN> to an rvalue or binding an rvalue reference to
an lvalue.  [<I>Note:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1079"></A><H4>1079.
  
Overload resolution involving aggregate initialization
</H4><B>Section: </B>13.3.3.2&#160; [over.ics.rank]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-06-15<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>The current wording makes some calls involving aggregate
initialization ambiguous that should not be.  For example, the
calls below to <TT>f</TT> and <TT>g</TT> should each prefer the
second overload:</P>

<PRE>
    struct A { int i; };

    void f (const A &amp;);
    void f (A &amp;&amp;);

    void g (A, double);
    void g (A, int);

    int main() {
       f ( { 1 } );
       g ( { 1 }, 1 );
    }
</PRE>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change 13.3.3.2 [over.ics.rank]
paragraph 3 bullet 2 as follows:</P>

<UL><LI><P>User-defined conversion sequence <TT>U1</TT> is a better
conversion sequence than another user-defined conversion sequence
<TT>U2</TT> if they contain the same user-defined conversion function
or constructor <SPAN style="font-weight:bold;background-color:#A0FFA0">or aggregate initialization</SPAN> and if the
second standard conversion sequence of <TT>U1</TT> is better than the
second standard conversion sequence of <TT>U2</TT>.</P></LI></UL>

<BR><BR><HR><A NAME="1238"></A><H4>1238.
  
Overloading ambiguity binding reference to function
</H4><B>Section: </B>13.3.3.2&#160; [over.ics.rank]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Doug Gregor
 &#160;&#160;&#160;

 <B>Date: </B>2011-01-25<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>Currently overload resolution does not distinguish between binding
an lvalue reference to a function lvalue and an rvalue reference to a
function lvalue.  The former should be preferred.</P>

<P>In a related point, the current wording of 13.3.3.1.4 [over.ics.ref]
paragraph 3 forbids binding an rvalue reference to an lvalue; this should
be changed to allow binding an rvalue reference to a function lvalue.</P>

<BR><BR><HR><A NAME="1153"></A><H4>1153.
  
Type matching in address of overloaded function
</H4><B>Section: </B>13.4&#160; [over.over]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-03<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US68">N3092 comment
  US&#160;68<BR></A>

<P>Overload resolution within the operand of a unary &amp;
operator is done by selecting the function &#8220;whose type
matches the target type required in the context.&#8221; The
criterion for determining whether the types match,
however, is not defined. At least three possibilities
suggest themselves:</P>

<OL><LI><P>The types are identical.</P></LI>

<LI><P>The source type can be implicitly converted to
the target type.</P></LI>

<LI><P>The expression would be well-formed if the
function under consideration were not
overloaded.</P></LI>

</OL>

<P>This question arises for pointer-to-member types, where
there is an implicit conversion from a
pointer-to-base-member to a pointer-to-derived-member, as
well as when the context is an explicit type conversion
(which allows, for <TT>static_cast</TT>, a conversion from
pointer-to-derived-member to a pointer-to-base-member and,
in the <TT>reinterpret_cast</TT> interpretation of
functional and old-style casts, essentially any
conversion).</P>

<P><B>Notes from the August, 2010 meeting:</B></P>

<P>CWG observed that the only case in which the types might not
match exactly was for pointers to member functions.  In this case,
the approach should be to ignore the class of which the functions
are members and just match (exactly) on the function type.</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<OL><LI><P>Change 13.4 [over.over] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...The function selected is the one whose type <SPAN style="text-decoration:line-through;background-color:#FFA0A0">matches</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">is identical to</SPAN> the <SPAN style="font-weight:bold;background-color:#A0FFA0">function type of the</SPAN> target
type required in the context.  <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> That is, the class
of which the function is a member is ignored when matching a
pointer-to-member-function type. &#8212;<I>end note</I>]</SPAN> The
target can be...

</BLOCKQUOTE>

<LI>Change 13.4 [over.over] paragraph 3 as follows:</LI>

<BLOCKQUOTE>

Non-member functions and static member functions match targets of
type &#8220;pointer-to-function&#8221; or &#8220;reference-
to-function.&#8221; Nonstatic member functions match targets of type
&#8220;pointer-to-member-function<SPAN style="text-decoration:line-through;background-color:#FFA0A0">;</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">.</SPAN>&#8221;
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">the function type of the pointer to member is used to select the
member function from the set of overloaded member functions.</SPAN> If
a non-static member function is selected, the reference to the
overloaded function name is required to have the form of a pointer to
member as described in 5.3.1 [expr.unary.op].

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1009"></A><H4>1009.
  
Missing cases in the <I>declarator-id</I> of a function template declaration
</H4><B>Section: </B>14&#160; [temp]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Johannes Schaub
 &#160;&#160;&#160;

 <B>Date: </B>2009-11-28<BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<P>According to 14 [temp] paragraph 2,</P>

<BLOCKQUOTE>

In a function template declaration, the last component of the
<I>declarator-id</I> shall be a <I>template-name</I> or
<I>operator-function-id</I> (i.e., not a <I>template-id</I>).

</BLOCKQUOTE>

<P>This is too restrictive; it should also allow
<I>conversion-function-id</I>s and
<I>literal-operator-id</I>s.</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<P>Change 14 [temp] paragraph 2 as follows:</P>

<BLOCKQUOTE>

A <I>template-declaration</I> can appear only as a namespace scope or
class scope declaration.  In a function template declaration, the last
component of the <I>declarator-id</I> shall <SPAN style="font-weight:bold;background-color:#A0FFA0">not</SPAN> be a
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>template-id</I></SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>template-name</I> or
<I>operator-function-id</I> (i.e., not a
<I>template-id</I>)</SPAN>. [<I>Note:</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">in</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">That last
component may be an <I>identifier</I>, an <I>operator-function-id</I>,
a <I>conversion-function-id</I>, or a <I>literal-operator-id.</I>
In</SPAN> a class template declaration, if the class name is a
<I>simple-template-id</I>, the declaration declares a class template
partial specialization (14.5.5 [temp.class.spec]). &#8212;<I>end
note</I>]

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1096"></A><H4>1096.
  
Missing requirement for template definitions
</H4><B>Section: </B>14&#160; [temp]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2010-07-28<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>



<P>The removal of the <TT>export</TT> keyword inadvertently deleted
the text (previously found in 14 [temp] paragraph 8 of
the 2003 Standard),</P>

<BLOCKQUOTE>

A non-exported template must be defined in every
translation unit in which it is implicitly instantiated
(14.7.1 [temp.inst]), unless the corresponding
specialization is explicitly instantiated (14.7.2 [temp.explicit]) in some translation unit; no diagnostic is
required.

</BLOCKQUOTE>

<P>This requirement must be reinstated.</P>

<P><B>Proposed resolution (January, 2011):</B></P>

<P>Add the following as a new paragraph following 14 [temp]
paragraph 5:</P>

<BLOCKQUOTE>

<SPAN style="font-weight:bold;background-color:#A0FFA0">A function template, member function of a class template, or
static data member of a class template shall be defined in every
translation unit in which it is implicitly instantiated (14.7.1 [temp.inst]), unless the corresponding specialization is explicitly
instantiated (14.7.2 [temp.explicit]) in some translation unit;
no diagnostic is required.</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="691"></A><H4>691.
  
Template parameter packs in class template partial specializations
</H4><B>Section: </B>14.1&#160; [temp.param]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Doug Gregor
 &#160;&#160;&#160;

 <B>Date: </B>9 April, 2008<BR>


<P>[Voted into WP at August, 21010 meeting.]</P>



<P>14.1 [temp.param] paragraph 11 currently says,</P>

<BLOCKQUOTE>

If a <I>template-parameter</I> of a class template is a template
parameter pack, it shall be the last
<I>template-parameter</I>. [<I>Note:</I> These are not
requirements for function templates because template arguments
might be deduced (14.8.2 [temp.deduct])...

</BLOCKQUOTE>

<P>This restriction was only meant to apply to primary class
templates, not partial specializations.</P>

<P><U>Suggested resolution</U>:</P>

<BLOCKQUOTE>

If a <I>template-parameter</I> of a <SPAN style="font-weight:bold;background-color:#A0FFA0">primary</SPAN> class template
is a template parameter pack, it shall be the last
<I>template-parameter</I>. [<I>Note:</I> These are not
requirements for function templates <SPAN style="font-weight:bold;background-color:#A0FFA0">or class template partial
specializations</SPAN> because template arguments might be deduced
(14.8.2 [temp.deduct])...

</BLOCKQUOTE>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 14.1 [temp.param] paragraph 11 as follows:</P>

<BLOCKQUOTE>

If a <I>template-parameter</I> of a class template has a default
<I>template-argument</I>, each subsequent
<I>template-parameter</I> shall either have a default
<I>template-argument</I> supplied or be a template parameter pack.  If a
<I>template-parameter</I> of a <SPAN style="font-weight:bold;background-color:#A0FFA0">primary</SPAN> class template
is a template parameter pack, it shall be the last
<I>template-parameter</I>. [<I>Note:</I> These are not
requirements for function templates <SPAN style="font-weight:bold;background-color:#A0FFA0">or class template partial
specializations</SPAN> because template arguments
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">might</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">can</SPAN> be deduced (14.8.2 [temp.deduct]). [<I>Example:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="778"></A><H4>778.
  
Template parameter packs in non-type template parameters
</H4><B>Section: </B>14.1&#160; [temp.param]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Michael Wong
 &#160;&#160;&#160;

 <B>Date: </B>13 February, 2009<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3270.]</P>

<P>Consider an example like:</P>

<PRE>
    template &lt;typename T, T Value&gt; struct bar { };
    template &lt;typename... T, T ...Value&gt; void foo(bar&lt;T, Value&gt;);
</PRE>

<P>The current wording in 14.1 [temp.param] is unclear as to
whether this is permitted or not. For comparison,
8.3.5 [dcl.fct] paragraph 13 says,</P>

<BLOCKQUOTE>

A <I>declarator-id</I> or <I>abstract-declarator</I> containing an
ellipsis shall only be used in a <I>parameter-declaration</I>.  Such a
<I>parameter-declaration</I> is a parameter pack (14.5.3 [temp.variadic]). When it is part of a
<I>parameter-declaration-clause</I>, the parameter pack is a function
parameter pack (14.5.3 [temp.variadic]).  [<I>Note:</I>
Otherwise, the <I>parameter-declaration</I> is part of a
<I>template-parameter-list</I> and the parameter pack is a template
parameter pack; see 14.1 [temp.param]. &#8212;<I>end note</I>]
A function parameter pack, if present, shall occur at the end of the
<I>parameter-declaration-list</I>.  The type <TT>T</TT> of the
<I>declarator-id</I> of the function parameter pack shall contain a
template parameter pack; each template parameter pack in <TT>T</TT> is
expanded by the function parameter pack.

</BLOCKQUOTE>

<P>The requirement here that the type of a function parameter pack
must contain a template parameter pack is not repeated for template
non-type parameters in 14.1 [temp.param], nor is the statement
that it expands the template parameter pack.</P>

<P>A related issue is that neither function nor template parameter
packs are listed in 14.5.3 [temp.variadic] paragraph 4 among
the contexts in which a pack expansion can appear.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<OL><LI><P>Change 5.3.3 [expr.sizeof] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

The identifier in a <TT>sizeof...</TT> expression shall name a
parameter pack. The <TT>sizeof...</TT> operator yields the number of
arguments provided for the parameter pack <I>identifier</I>. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The
parameter pack is expanded (14.5.3 [temp.variadic]) by the
<TT>sizeof...</TT> operator</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">A <TT>sizeof...</TT> expression
is a pack expansion (14.5.3 [temp.variadic])</SPAN>. [<I>Example:</I>...

</BLOCKQUOTE>

<LI><P>Change 8.3.5 [dcl.fct] paragraph 13 as follows:</P></LI>

<BLOCKQUOTE>

A <I>declarator-id</I> or <I>abstract-declarator</I> containing an
ellipsis shall only be used in a <I>parameter-declaration</I>.  Such a
<I>parameter-declaration</I> is a parameter pack (14.5.3 [temp.variadic]). When it is part of a
<I>parameter-declaration-clause</I>, the parameter pack is a function
parameter pack (14.5.3 [temp.variadic]).  [<I>Note:</I>
Otherwise, the <I>parameter-declaration</I> is part of a
<I>template-parameter-list</I> and the parameter pack is a template
parameter pack; see 14.1 [temp.param].  &#8212;<I>end
note</I>] <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The type <TT>T</TT> of the <I>declarator-id</I> of the
function parameter pack shall contain a template parameter pack; each
template parameter pack in <TT>T</TT> is expanded by the function
parameter pack</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">A function parameter pack is a pack
expansion (14.5.3 [temp.variadic])</SPAN>. [<I>Example:</I>...

</BLOCKQUOTE>

<LI><P>Change 14.1 [temp.param] paragraph 15 as follows:</P></LI>

<BLOCKQUOTE>

<P>If a <I>template-parameter</I> is a <I>type-parameter</I> with an
ellipsis prior to its optional <I>identifier</I> or is a
<I>parameter-declaration</I> that declares a parameter pack
(8.3.5 [dcl.fct]), then the <I>template-parameter</I> is a
template parameter pack (14.5.3 [temp.variadic]). <SPAN style="font-weight:bold;background-color:#A0FFA0">A template
parameter pack that is a <I>parameter-declaration</I> whose type
contains one or more unexpanded parameter packs is a pack
expansion. Similarly, a template parameter pack that is a
<I>type-parameter</I> with a <I>template-parameter-list</I> containing
one or more unexpanded parameter packs is a pack expansion.</SPAN>
[<I>Example:</I></P>

<PRE>
  template &lt;class... Types&gt; class Tuple; // Types<SPAN style="font-family:Times;font-style:italic"> is a template type parameter pack <SPAN style="font-weight:bold;background-color:#A0FFA0">and a pack expansion</SPAN></SPAN>
  template &lt;class T, int... Dims&gt; struct multi_array; // Dims<SPAN style="font-family:Times;font-style:italic"> is a non-type template parameter pack <SPAN style="font-weight:bold;background-color:#A0FFA0">but not a pack expansion</SPAN></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  template &lt;class T, T... Values&gt; struct static_array; // Values<SPAN style="font-family:Times;font-style:italic"> is a non-type template parameter pack and a pack expansion</SPAN></SPAN>
</PRE>

</BLOCKQUOTE>

<LI><P>Change 14.5.3 [temp.variadic] paragraphs 4-6 and add a new
paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

<P>A <I>pack expansion</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">is a sequence of tokens that names one
or more parameter packs, followed by an ellipsis.  The sequence of
tokens is called the <I>pattern of the expansion</I>; its syntax</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">consists of a <I>pattern</I> and an ellipsis, the instantiation
of which produces zero or more instantiations of the pattern in a list
(described below).  The form of the pattern</SPAN> depends on the
context in which the expansion occurs. Pack expansions can occur in
the following contexts:</P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">In a function parameter pack (8.3.5 [dcl.fct]);
the pattern is the <I>parameter-declaration</I> without the
ellipsis.</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">In a template parameter pack that is a pack expansion
(14.1 [temp.param]):</SPAN></P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">if the template parameter pack is a
<I>parameter-declaration</I>; the pattern is the
<I>parameter-declaration</I> without the ellipsis,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">if the template parameter pack is a <I>type-parameter</I>
with a <I>template-parameter-list</I>; the pattern is the corresponding
<I>type-parameter</I> without the ellipsis.</SPAN></P></LI>

</UL>

</LI>

<LI><P>...</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">In a <TT>sizeof...</TT> expression (5.3.3 [expr.sizeof]),
the pattern is an <I>identifier</I>.</SPAN></P></LI>

</UL>

<P>[<I>Example:...</I></P>

<P>A parameter pack whose name appears within the pattern of a pack
expansion is expanded by that pack expansion.  An appearance of the
name of a parameter pack is only expanded by the innermost enclosing
pack expansion.  The pattern of a pack expansion shall name one or
more parameter packs that are not expanded by a nested pack
expansion<SPAN style="font-weight:bold;background-color:#A0FFA0">; such parameter packs are called
<I>unexpanded</I> parameter packs in the pattern</SPAN>. All of the
parameter packs expanded...</P>

<PRE>
  ...
  void g(Args ... args) {  <SPAN style="font-weight:bold;background-color:#A0FFA0">//<SPAN style="font-family:Times;font-style:italic"> OK: &#8220;</SPAN>Args<SPAN style="font-family:Times;font-style:italic">&#8221; is expanded by the function parameter pack &#8220;</SPAN>args<SPAN style="font-family:Times;font-style:italic">&#8221;</SPAN></SPAN>
  ...
</PRE>

<P>The instantiation of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">an</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">a pack</SPAN> expansion
<SPAN style="font-weight:bold;background-color:#A0FFA0">that is not a <TT>sizeof...</TT> expression</SPAN> produces a
list...</P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">The instantiation of a <TT>sizeof...</TT> expression
(5.3.3 [expr.sizeof]) produces an integral constant containing
the number of elements in the parameter pack it expands.</SPAN></P>

</BLOCKQUOTE>

</OL>

<P>This resolution also resolves issues <A HREF="
     cwg_defects.html#1182">1182</A>
and <A HREF="
     cwg_defects.html#1183">1183</A>.</P>

<P><B>Additional note (February, 2011):</B></P>

<P>A problematic case is a function like</P>

<PRE>
  template&lt;typename... T, T... t&gt; void f(T...) { }
</PRE>

<P>where each element of the nontype pack actually has a different
type.  This causes problems for template argument deduction, since
<TT>T</TT> and <TT>t</TT> are supposed to be deduced independently,
but they're linked through their sizes.  There doesn't appear to be
any use case for this kind of example, so it should be ill-formed.</P>

<P>The rule should probably be to consider a non-type template
parameter pack that expands any template parameter packs from the same
<I>template-parameter-list</I> as ill-formed.</P>

<BR><BR><HR><A NAME="1006"></A><H4>1006.
  
<TT>std::nullptr_t</TT> as a non-type template parameter
</H4><B>Section: </B>14.1&#160; [temp.param]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>2009-11-20<BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>



<P><TT>std::nullptr_t</TT> is not currently allowed by
14.1 [temp.param] paragraph 4 to be used as the type of a
non-type template parameter.  However, this could arise for a
template with a non-type template parameter with a dependent type
in a template intended for use with pointers, e.g.,</P>

<PRE>
    template&lt;typename T, T t&gt; void f();
    ...
    f&lt;std::nullptr_t, nullptr&gt;();
</PRE>

<P>or in a case of delegation.</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<P>Change 14.1 [temp.param] paragraph 4 as follows:</P>

<BLOCKQUOTE>

<P>A non-type <I>template-parameter</I> shall have one of the following
(optionally <I>cv-qualified</I>) types:</P>

<UL><LI><P>integral or enumeration type,</P></LI>

<LI><P>pointer to object or pointer to function,</P></LI>

<LI><P>lvalue reference to object or lvalue reference to function,</P></LI>

<LI><P>pointer to member<SPAN style="text-decoration:line-through;background-color:#FFA0A0">.</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>std::nullptr_t</TT>.</SPAN></P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1068"></A><H4>1068.
  
Template aliases with default arguments and template parameter packs
</H4><B>Section: </B>14.1&#160; [temp.param]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Nikolay Ivchenkov
 &#160;&#160;&#160;

 <B>Date: </B>2010-03-27<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

<P>Since there appear to be no restrictions against it, it would
appear that default arguments and template parameter packs can be
used with template aliases just as with other templates.  If that
is the case, then, the current wording in 14.1 [temp.param]
paragraph 11 requires adjustment:</P>

<BLOCKQUOTE>

If a <I>template-parameter</I> of a class template has a default
<I>template-argument</I>, each subsequent
<I>template-parameter</I> shall either have a default
<I>template-argument</I> supplied or be a template parameter
pack.  If a <I>template-parameter</I> of a class template is a
template parameter pack, it shall be the last
<I>template-parameter</I>.

</BLOCKQUOTE>

<P>Presumably these restrictions should also apply to template
aliases, but as written, they only apply to class templates.</P>

<P><B>Proposed resolution (January, 2011):</B></P>

<P>Change 14.1 [temp.param] paragraph 11 as follows:</P>

<BLOCKQUOTE>

If a <I>template-parameter</I> of a class template <SPAN style="font-weight:bold;background-color:#A0FFA0">or alias
template</SPAN> has a default <I>template-argument</I>, each subsequent
<I>template-parameter</I> shall either have a default
<I>template-argument</I> supplied or be a template parameter pack.  If
a <I>template-parameter</I> of a primary class template <SPAN style="font-weight:bold;background-color:#A0FFA0">or alias
template</SPAN> is a template parameter pack, it shall be the last
<I>template-parameter</I>.  [<I>Note:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1246"></A><H4>1246.
  
Non-deduced non-final parameter packs
</H4><B>Section: </B>14.1&#160; [temp.param]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>2011-02-23<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>According to 14.1 [temp.param] paragraph 11,</P>

<BLOCKQUOTE>

If a <I>template-parameter</I> of a class template has a default
<I>template-argument</I>, each subsequent <I>template-parameter</I>
shall either have a default <I>template-argument</I> supplied or be a
template parameter pack.  If a <I>template-parameter</I> of a primary
class template is a template parameter pack, it shall be the last
<I>template-parameter</I>. [<I>Note:</I> These are not requirements
for function templates or class template partial specializations
because template arguments can be deduced (14.8.2 [temp.deduct])...

</BLOCKQUOTE>

<P>Should the Standard forbid non-final parameter packs in cases where
the declaration does not allow the template arguments to be deduced?
For example,</P>

<PRE>
    template&lt;typename... T, typename... U&gt; void f() { }
    template&lt;typename... T, typename U&gt; void g() { }
</PRE>

<P>(See also <A HREF="
     cwg_active.html#549">issue 549</A>.)</P>

<BR><BR><HR><A NAME="96"></A><H4>96.
  
Syntactic disambiguation using the <TT>template</TT> keyword
</H4><B>Section: </B>14.2&#160; [temp.names]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>16 Feb 1999<BR>



<P>[Voted into WP at August, 2010 meeting.]</P>

<P>The following is the wording from
14.2 [temp.names]

paragraphs 4 and 5 that discusses the use of the "template" keyword following
<TT>.</TT> or <TT>-&gt;</TT> and in qualified names.</P>
<UL>When the name of a member template specialization appears after <TT>.</TT>
or <TT>-&gt;</TT> in a <I>postfix-expression</I>, or after <I>nested-name-specifier</I>
in a <I>qualified-id</I>, and the <I>postfix-expression</I> or <I>qualified-id</I>
explicitly depends on a <I>template-parameter</I>
(14.6.2 [temp.dep]
),
the member template name must be prefixed by the keyword <TT>template</TT>.
Otherwise the name is assumed to name a non-template. [<I>Example:</I>
<PRE>
    class X {
    public:
        template&lt;std::size_t&gt; X* alloc();
        template&lt;std::size_t&gt; static X* adjust();
    };
    
    template&lt;class T&gt; void f(T* p) {
        T* p1 = p-&gt;alloc&lt;200&gt;();
                // ill-formed: &lt; means less than
    
        T* p2 = p-&gt;template alloc&lt;200&gt;();
                // OK: &lt; starts template argument list
     
        T::adjust&lt;100&gt;();
                // ill-formed: &lt; means less than
     
        T::template adjust&lt;100&gt;();
                // OK: &lt; starts explicit qualification
    }
</PRE>
&#8212;<I>end example</I>]

<P>If a name prefixed by the keyword <TT>template</TT> is not the name
of a member template, the program is ill-formed.
[<I>Note:</I> the keyword <TT>template</TT>
may not be applied to non-template members of class templates. ]</P></UL>
The whole point of this feature is to say that the "<TT>template</TT>"
keyword is needed to indicate that a "<TT>&lt;</TT>" begins a template
parameter list in certain contexts. The constraints in paragraph 5 leave
open to debate certain cases.

<P>First, I think it should be made more clear that the template name must
be followed by a template argument list when the "<TT>template</TT>" keyword
is used in these contexts. If we don't make this clear, we would have to
add several semantic clarifications instead. For example, if you say "<TT>p-&gt;template
f()</TT>", and "<TT>f</TT>" is an overload set containing both templates
and nontemplates: a) is this valid? b) are the nontemplates in the overload
set ignored? If the user is forced to write "<TT>p-&gt;template f&lt;&gt;()</TT>"
it is clear that this is valid, and it is equally clear that nontemplates
in the overload set are ignored. As this feature was added purely to provide
syntactic guidance, I think it is important that it otherwise have no semantic
implications.</P>

<P>I propose that paragraph 5 be modified to:</P>
<UL>If a name prefixed by the keyword <TT>template</TT> is not the name
of a member template, or an overload set containing one or more member
templates, the program is ill-formed. If the name prefixed by the <TT>template</TT>
keyword is not followed by a <I>template-argument-list</I>, the program
is ill-formed.</UL>

<P>(See also <A HREF="
     cwg_defects.html#30">issue 30</A> and document
J16/00-0008 = WG21 N1231.)</P>

<P><B>Notes from 04/00 meeting:</B></P>

<P>The discussion of this issue revived interest in issues
<A HREF="
     cwg_defects.html#11">11</A> and <A HREF="
     cwg_closed.html#109">109</A>.

</P>

<P><B>Notes from the October 2003 meeting:</B></P>

<P>We reviewed John Spicer's paper N1528 and agreed with his
recommendations therein.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 14.2 [temp.names] paragraph 5 as follows:</P>

<BLOCKQUOTE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">If a</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">A</SPAN> name prefixed by the keyword
<TT>template</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">is not the name of a template,</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">shall be a <I>template-id</I> or the name shall refer to a
class template</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the program is ill-formed</SPAN>.
[<I>Note:</I> the keyword <TT>template</TT> may not be applied to
non-template members of class templates. &#8212;<I>end note</I>]
[<I>Note:</I> as is the case with the <TT>typename</TT> prefix,
the <TT>template</TT> prefix is allowed in cases where it is not
strictly necessary; i.e., when the <I>nested-name-specifier</I>
or the expression on the left of the <TT>-&gt;</TT> or <TT>.</TT>
is not dependent on a <I>template-parameter</I>, or the use does
not appear in the scope of a template. &#8212;<I>end note</I>]
<SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  template &lt;class T&gt; struct A {
    void f(int);
    template &lt;class U&gt; void f(U); };

  template &lt;class T&gt; void f(T t) {
    A&lt;T&gt; a;
    a.template f&lt;&gt;(t); //<SPAN style="font-family:Times;font-style:italic"> OK: calls template</SPAN>
    a.template f(t);   //<SPAN style="font-family:Times;font-style:italic"> error: not a template-id</SPAN>
  }

  template &lt;class T&gt; struct B {template &lt;class T2&gt; struct C {}; };
  //<SPAN style="font-family:Times;font-style:italic"> OK: </SPAN>T::template C<SPAN style="font-family:Times;font-style:italic"> names a class template:</SPAN>
  template &lt;class T, template &lt;class X&gt; class TT = T::template C&gt; struct D {};
  D&lt;B&lt;int&gt;&gt; db;</SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="431"></A><H4>431.
  
Defect in wording in 14.2
</H4><B>Section: </B>14.2&#160; [temp.names]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Mat Marcus
 &#160;&#160;&#160;

 <B>Date: </B>10 August 2003<BR>


<P>[Voted into WP at August, 2010 meeting.]</P>



<P>Consider this example:</P>
<PRE>
   class Foo {
   public:
       template&lt; typename T &gt; T *get();
   };

   template&lt; typename U &gt;
   U *testFoo( Foo &amp;foo ) {
       return foo.get&lt; U &gt;(); //#1
   }
</PRE>
<P>I am under the impression that this should compile without requiring
the insertion of the template keyword before get in the expression at
//#1. This notion is supported by this note excerpted from
14.2 [temp.names]/5:</P>
<BLOCKQUOTE>
   [Note: just as is the case with the typename prefix, the template
   prefix is allowed in cases where it is not strictly necessary;
   i.e.,  when the expression on the left of the -&gt; or ., or the
   nested-name-specifier is not dependent on a template parameter.]
</BLOCKQUOTE>

<P>But 14.2 [temp.names]/4 contains this text:</P>
<BLOCKQUOTE>
   When the name of a member template specialization appears after .
   or -&gt; in a postfix-expression, or after nested-name-specifier in
   a qualified-id, and the postfix-expression or qualified-id
   explicitly depends on a template-parameter (14.6.2), the member
   template name must be prefixed by the keyword template. Otherwise
   the name is assumed to name a non-template.
</BLOCKQUOTE>

<P>The only way that I can read this to support my assumption above is if
I assume that the phrase postfix-expression is used twice above with
different meaning. That is I read the first use as referring to the
full expression while the second use refers to the subexpression
preceding the operator. Is this the correct determination of intent? I
find this text confusing. Would it be an improvement if the second
occurrence of "postfix-expression" should be replaced by "the
subexpression preceding the operator". Of course that begs the
question "where is subexpression actually defined in the standard?"</P>

<P><U>John Spicer:</U>
I agree that the code should work, and that we should tweak 
the wording.</P>

<P><B>Proposed resolution (March, 2010):</B></P>

<P>Change 14.2 [temp.names] paragraph 4 as follows:</P>

<BLOCKQUOTE>

When the name of a member template specialization appears after
<TT>.</TT> or <TT>-&gt;</TT> in a <I>postfix-expression</I>, or
after a <I>nested-name-specifier</I> in a <I>qualified-id</I>,
and the <SPAN style="font-weight:bold;background-color:#A0FFA0">object or pointer expression of the</SPAN>
<I>postfix-expression</I> or <SPAN style="font-weight:bold;background-color:#A0FFA0">the
<I>nested-name-specifier</I> in the</SPAN> <I>qualified-id</I>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">explicitly</SPAN> depends on a
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>template-parameter</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">template
parameter</SPAN> (14.6.2 [temp.dep]) but does not refer
to a member of the current instantiation (14.6.2.1 [temp.dep.type]), the member template name must be prefixed by
the keyword <TT>template</TT>.  Otherwise the name is assumed to
name a non-template. [<I>Example:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="773"></A><H4>773.
  
Parentheses in address non-type template arguments
</H4><B>Section: </B>14.3.2&#160; [temp.arg.nontype]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Doug Gregor
 &#160;&#160;&#160;

 <B>Date: </B>11 February, 2009<BR>


<P>[Voted into WP at August, 21010 meeting.]</P>

<P>According to 14.3.2 [temp.arg.nontype] paragraph 1, bullet 3, one
of the acceptable forms of a non-type, non-template template argument
is:</P>

<BLOCKQUOTE>

the address of an object or function... expressed as <TT>&amp;</TT>
<I>id-expression</I> where the <TT>&amp;</TT> is optional if the name
refers to a function or array, or if the corresponding
<I>template-parameter</I> is a reference

</BLOCKQUOTE>

<P>It is not clear from this whether a template argument like
<TT>(&amp;i)</TT> satisfies the requirement or not.</P>

<P><B>Notes from the March, 2009 meeting:</B></P>

<P>The consensus of the CWG was that the parentheses should be
allowed.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 14.3.2 [temp.arg.nontype] paragraph 1 bullet 3 as follows:</P>

<UL><LI><P>the address of an object or function with external linkage,
including function templates and function <I>template-id</I>s but
excluding non-static class members, expressed <SPAN style="font-weight:bold;background-color:#A0FFA0">(ignoring
parentheses)</SPAN> as <TT>&amp;</TT> <I>id-expression</I><SPAN style="font-weight:bold;background-color:#A0FFA0">, except
that</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">where</SPAN> the <TT>&amp;</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">is optional</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">may be omitted</SPAN> if the name refers to a function or
array<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, or</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">and shall be omitted</SPAN> if the
corresponding <I>template-parameter</I> is a reference; or</P></LI>

</UL>

<P><I>[Drafting note: The change requiring the omission of the
<TT>&amp;</TT> in the reference case fixes an existing problem that
is not related to this issue.]</I></P>

<BR><BR><HR><A NAME="1025"></A><H4>1025.
  
Use of a reference as a non-type template argument
</H4><B>Section: </B>14.3.2&#160; [temp.arg.nontype]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>2010-01-31<BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<P>The current wording of 14.3.2 [temp.arg.nontype] paragraph 1 does
not prevent the use a reference as a non-type template argument.  It
simply requires</P>

<BLOCKQUOTE>

the address of an object or function with external linkage... expressed
as <TT>&amp;</TT> <I>id-expression</I>...

</BLOCKQUOTE>

<P>This would presumably (but unintentionally?) allow an example like
the following:</P>

<PRE>
    struct S { };
    template&lt;S*&gt; struct X { };
    S s;
    S&amp; ref = s;
    X&lt;&amp;ref&gt; xr;   // well-formed?
</PRE>

<P>The expression <TT>&amp;ref</TT> is not a constant expression, but
the current wording of 14.3.2 [temp.arg.nontype] does not require a
constant expression.</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<P>Change 14.3.2 [temp.arg.nontype] paragraph 1 bullet 3 as follows:</P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">a constant expression (5.19 [expr.const]) that
designates</SPAN> the address of an object or function with external
linkage, including function templates and function <I>template-id</I>s
but excluding non-static class members, expressed (ignoring
parentheses) as <TT>&amp;</TT> <I>id-expression</I>, except that the
<TT>&amp;</TT> may be omitted if the name refers to a function or
array and shall be omitted if the corresponding
<I>template-parameter</I> is a reference; or</P></LI></UL>

<BR><BR><HR><A NAME="1154"></A><H4>1154.
  
Address of <TT>thread_local</TT> variable as non-type template argument
</H4><B>Section: </B>14.3.2&#160; [temp.arg.nontype]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-03<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US69">N3092 comment
  US&#160;69<BR></A>

<P>The standard permits the address of a
<TT>thread_local</TT> object as a non-type template
argument. The addresses of these objects are not constant,
however. Such template arguments should require objects of
static storage duration.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>This issue is resolved by the resolution of <A HREF="
     cwg_defects.html#1155">issue 1155</A>.</P>

<BR><BR><HR><A NAME="1155"></A><H4>1155.
  
Internal-linkage non-type template arguments
</H4><B>Section: </B>14.3.2&#160; [temp.arg.nontype]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-03<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#DE12">N3092 comment
  DE&#160;12<BR></A>

<P>Now that local classes can be used as template arguments,
it seems odd that there are &#8220;external linkage&#8221;
restrictions on non-type template parameters. The addresses
of objects and functions with internal linkage should be
permitted as well.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change 14.3.2 [temp.arg.nontype] paragraph 1 bullet 3 as follows:</P>

<UL><LI><P>the address of an object <SPAN style="font-weight:bold;background-color:#A0FFA0">with static storage
duration and external or internal linkage</SPAN> or
<SPAN style="font-weight:bold;background-color:#A0FFA0">a</SPAN> function with external <SPAN style="font-weight:bold;background-color:#A0FFA0">or internal</SPAN>
linkage, including function templates...</P></LI></UL>

<P>This resolution also resolves <A HREF="
     cwg_defects.html#1154">issue 1154</A>.</P>

<BR><BR><HR><A NAME="1244"></A><H4>1244.
  
Equivalence of alias templates and class templates
</H4><B>Section: </B>14.4&#160; [temp.type]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Johannes Schaub
 &#160;&#160;&#160;

 <B>Date: </B>2011-02-22<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>The example in 14.4 [temp.type] paragraph 1 reads in
significant part,</P>

<PRE>
    template&lt;template&lt;class&gt; class TT&gt; struct X { };
    template&lt;class&gt; struct Y { };
    template&lt;class T&gt; using Z = Y&lt;T&gt;;
    X&lt;Y&gt; y;
    X&lt;Z&gt; z;
</PRE>

<P>and says that <TT>y</TT> and <TT>z</TT> have the same type.</P>

<P>This would only be true if alias template <TT>Z</TT> were
considered to be equivalent to class template <TT>Y</TT>.  However,
14.5.7 [temp.alias] describes equivalence only for
specializations of alias templates, not for the alias templates
themselves.  Either such rules should be specified, which could
be tricky, or the example should be deleted.</P>

<BR><BR><HR><A NAME="1206"></A><H4>1206.
  
Defining opaque enumeration members of class templates
</H4><B>Section: </B>14.5.1&#160; [temp.class]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-10-06<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>Presumably an out-of-class definition for an opaque enumeration
member of a class template is intended to be allowed; however, the
current wording of 14.5.1 [temp.class] provides only for
out-of-class definitions of member functions, member classes,
static data members, and member templates, not for opaque
enumerations.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<OL><LI><P>Change 14 [temp] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<P>...The <I>declaration</I> in a <I>template-declaration</I> shall</P>

<UL><LI><P>declare or define a function or class, or</P></LI>

<LI><P>define a member function, a member class<SPAN style="font-weight:bold;background-color:#A0FFA0">, a member
enumeration,</SPAN> or a static data member of a class template or of a
class nested within a class template, or</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 14.5.1 [temp.class] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

When a member function, a member class, <SPAN style="font-weight:bold;background-color:#A0FFA0">a member
enumeration,</SPAN> a static data member or a member template of a
class template is defined outside of the class template definition...

</BLOCKQUOTE>

<LI><P>Add a new section following 14.5.1.3 [temp.static]:</P></LI>

<BLOCKQUOTE>

<P><B><SPAN style="font-weight:bold;background-color:#A0FFA0">14.5.1.4 Enumeration members of class templates
[temp.mem.enum]</SPAN></B></P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">An enumeration member of a class template may be defined outside
the class template definition. [<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  template&lt;class T&gt; struct A {
    enum E: T;
  };
  A&lt;int&gt; a;
  template&lt;class T&gt; enum A&lt;T&gt;::E: T { e1, e2 };
  A&lt;int&gt;::E e = A&lt;int&gt;::e1;</SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

<LI><P>Change 14.7 [temp.spec] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

A function instantiated from a function template is called an
instantiated function. A class instantiated from a class template is
called an instantiated class. A member function, a member class,
<SPAN style="font-weight:bold;background-color:#A0FFA0">a member enumeration,</SPAN> or a static data member of a class
template instantiated from the member definition of the class template
is called, respectively, an instantiated member function, member
class<SPAN style="font-weight:bold;background-color:#A0FFA0">, member enumeration,</SPAN> or static data member.  A member
function...

</BLOCKQUOTE>

<LI><P>Change 14.7.1 [temp.inst] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...The implicit instantiation of a class template specialization
causes the implicit instantiation of the declarations, but not of the
definitions or default arguments, of the class member functions,
member classes, <SPAN style="font-weight:bold;background-color:#A0FFA0">scoped member enumerations,</SPAN> static data
members and member templates; and it causes the implicit instantiation
of the definitions of <SPAN style="font-weight:bold;background-color:#A0FFA0">unscoped member enumerations and</SPAN> member
anonymous unions. Unless a member...

</BLOCKQUOTE>

<LI><P>Change 14.7.3 [temp.expl.spec] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<P>An explicit specialization of any of the following:</P>

<UL><LI><P>function template</P></LI>

<LI><P>class template</P></LI>

<LI><P>member function of a class template</P></LI>

<LI><P>static data member of a class template</P></LI>

<LI><P>member class of a class template</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">member enumeration of a class template</SPAN></P></LI>

<LI><P>member class template of a class or class template</P></LI>

<LI><P>member function template of a class or class template</P></LI>

<P>can be declared by a declaration introduced by
<TT>template&lt;&gt;</TT>...</P>

</UL>

</BLOCKQUOTE>

<LI><P>Change 14.7.3 [temp.expl.spec] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

A member function, a member class<SPAN style="font-weight:bold;background-color:#A0FFA0">, a member enumeration,</SPAN> or
a static data member of a class template may be explicitly specialized
for a class specialization that is implicitly instantiated...

</BLOCKQUOTE>

<LI><P>Add the indicated text to the example in 14.7 [temp.spec]
paragraph 6:</P></LI>

<PRE>
  template&lt;&gt; void sort&lt;&gt;(Array(&lt;char*&gt;&amp; v);        //<SPAN style="font-family:Times;font-style:italic"> OK: </SPAN>sort&lt;char*&gt;<SPAN style="font-family:Times;font-style:italic"> not yet used</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  template&lt;class T&gt; struct A {
    enum E: T;
    enum class S: T;
  };
  template&lt;&gt; enum A&lt;int&gt;::E: int { eint };         //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
  template&lt;&gt; enum class A&lt;int&gt;::S: int { sint };   //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
  template&lt;class T&gt; enum A&lt;T&gt;::E: T { eT };
  template&lt;class T&gt; enum class A&lt;T&gt;::S: T { sT };
  template&lt;&gt; enum A&lt;char&gt;::E: int { echar };       //<SPAN style="font-family:Times;font-style:italic"> ill-formed, </SPAN>A&lt;char&gt;::E<SPAN style="font-family:Times;font-style:italic"> was instantiated when </SPAN>A&lt;char&gt;<SPAN style="font-family:Times;font-style:italic"> was instantiated</SPAN>
  template&lt;&gt; enum class A&lt;char&gt;::S: int { schar }; //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN></SPAN>
</PRE>

<LI><P>Change 14.7.3 [temp.expl.spec] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

The placement of explicit specialization declarations for function
templates, class templates, member functions of class templates,
static data members of class templates, member classes of class
templates, <SPAN style="font-weight:bold;background-color:#A0FFA0">member enumerations of class templates,</SPAN> member
class templates of class templates, member function templates...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1245"></A><H4>1245.
  
Matching declarations involving <TT>decltype</TT>
</H4><B>Section: </B>14.5.1.1&#160; [temp.mem.func]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2011-02-22<BR>


<P>Type matching rules aren't well-specified in the current Standard,
but it seems reasonable to say that if a declaration uses <TT>decltype</TT>,
its definition must do so as well.  For example, the following should
be ill-formed:</P>

<PRE>
    template&lt;class T, T* u&gt; struct S {
      decltype(u) foo(T);
    };

    template&lt;class T, T *u&gt; T* S&lt;T, u&gt;::foo(T) {
       return nullptr;
    }
</PRE>

<P><B>Proposed resolution (March, 2011):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#1057">issue 1057</A> in document N3262.</P>

<BR><BR><HR><A NAME="1032"></A><H4>1032.
  
Empty pack expansions
</H4><B>Section: </B>14.5.3&#160; [temp.variadic]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>James Widman
 &#160;&#160;&#160;

 <B>Date: </B>2010-02-16<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>It was intended for empty pack expansions to be useful in contexts
like <I>base-specifier</I>s, e.g.,</P>

<PRE>
    template&lt;class... T&gt; struct A : T... {};
    A&lt;&gt; x; // ok?
</PRE>

<P>However, the current wording provides no description of how that
might work.  (More generally, the problem arises in any context
where the pack expansion follows a token that should only be
present when the pack expansion is non-empty: following another
argument in a function call, etc.)</P>

<BR><BR><HR><A NAME="1182"></A><H4>1182.
  
Incorrect description of pack expansion syntax
</H4><B>Section: </B>14.5.3&#160; [temp.variadic]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-26<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3270.]</P>

<P>According to 14.5.3 [temp.variadic] paragraph 4,</P>

<BLOCKQUOTE>

A <I>pack expansion</I> is a sequence of tokens that names one or more
parameter packs, followed by an ellipsis.

</BLOCKQUOTE>

<P>This is contradicted by 5.3.3 [expr.sizeof] paragraph 5,
which describes <TT>sizeof...(Types)</TT> as an expansion, as well
as the case where the expansion appears in a declarator like the
example given in 8.3.5 [dcl.fct] paragraph 13:
</P>

<PRE>
    template&lt;typename... T&gt; void f(T (* ...t)(int, int));
</PRE>

<P>This is also described as a pack expansion, although it does
not fit the syntactic summary.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#778">issue 778</A>.</P>

<BR><BR><HR><A NAME="1231"></A><H4>1231.
  
Variadic templates requiring an empty pack expansion
</H4><B>Section: </B>14.5.3&#160; [temp.variadic]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>2010-12-20<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>Should the Standard allow declarations of variadic templates or
member functions of class templates where only an empty expansion
would be well-formed?  For example,</P>

<PRE>
    template&lt;typename ... T&gt; struct A {
      void operator++(int, T... t);
    };
    template&lt;typename ... T&gt; union X: T... { };
    template&lt;typename ... T&gt; struct A: T..., T... { };
</PRE>

<BR><BR><HR><A NAME="674"></A><H4>674.
  
&#8220;matching specialization&#8221; for a friend declaration
</H4><B>Section: </B>14.5.4&#160; [temp.friend]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>James Widman
 &#160;&#160;&#160;

 <B>Date: </B>7 February, 2008<BR>


<P>[Voted into WP at August, 21010 meeting.]</P>



<P>14.5.4 [temp.friend] paragraph 1 bullet 3 says:</P>

<UL><LI><P>if the name of the friend is a <I>qualified-id</I> and a
matching specialization of a function template is found in the
specified class or namespace, the friend declaration refers to that
function template specialization, otherwise,</P></LI></UL>

<P>I'm not sure this says what it's supposed to say.  For example:</P>

<PRE>
    namespace N {
        template&lt;class T&gt; int f(T);
    }

    class A {
        friend int N::f(int);
        int m;
        A();
    };

    namespace N {
        template&lt; class T &gt; int f(T) {
            A a;            //<SPAN style="font-family:Times;font-style:italic"> ok for </SPAN>T=int<SPAN style="font-family:Times;font-style:italic">?</SPAN>
            return a.m;     //<SPAN style="font-family:Times;font-style:italic"> ok for </SPAN>T=int<SPAN style="font-family:Times;font-style:italic">?</SPAN>
        }
    }

    int m = N::f(42);       //<SPAN style="font-family:Times;font-style:italic"> ok?</SPAN>
    char c = N::f('a');     //<SPAN style="font-family:Times;font-style:italic"> Clearly ill-formed.</SPAN>
</PRE>

<P>The key is that the wording talks about a &#8220;matching
specialization,&#8221; which to me means that <TT>N::f&lt;int&gt;</TT> is befriended only
if that specialization existed in <TT>N</TT> before the friend declaration.  So
it's ill-formed as written, but if we move the call to <TT>N::f&lt;int&gt;</TT> up to
a point before the definition of <TT>A</TT>, it's well-formed.</P>

<P>That seems surprising, especially given that the first bullet does
not require a pre-existing specialization.  So I suggest replacing
bullet 3 with something like:</P>

<UL><LI><P>if the name of the friend is a <I>qualified-id</I> and a
matching function template is found in the specified class or
namespace, the friend declaration refers to the deduced specialization
of that function template, otherwise,</P></LI></UL>

<P><B>Proposed resolution (June, 2010):</B></P>

<P>Change 14.5.4 [temp.friend] paragraph 1 bullet 3 as follows:</P>

<BLOCKQUOTE>

<P>...For a friend function declaration that is not a template
declaration:</P>

<UL><LI><P>...</P></LI>

<LI><P>if the name of the friend is a <I>qualified-id</I> and a
matching <SPAN style="text-decoration:line-through;background-color:#FFA0A0">specialization of a</SPAN> function template is
found in the specified class or namespace, the friend declaration
refers to <SPAN style="text-decoration:line-through;background-color:#FFA0A0">that function template specialization</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">the deduced specialization of that function template
(14.8.2.6 [temp.deduct.decl])</SPAN>,
otherwise,</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<P>(This resolution depends on that of <A HREF="
     cwg_defects.html#873">issue 873</A>; in particular, the cross-reference to 14.8.2.6
[temp.deduct.decl] refers to a new section added by the resolution
of that issue.)</P>

<BR><BR><HR><A NAME="996"></A><H4>996.
  
Ambiguous partial specializations of member class templates
</H4><B>Section: </B>14.5.5&#160; [temp.class.spec]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Doug Gregor
 &#160;&#160;&#160;

 <B>Date: </B>28 Oct, 2009<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>Given an example like</P>

<PRE>
  template&lt;typename T, typename U&gt;
  struct Outer {
    template&lt;typename X, typename Y&gt; struct Inner;
    template&lt;typename Y&gt; struct Inner&lt;T, Y&gt; {};
    template&lt;typename Y&gt; struct Inner&lt;U, Y&gt; {};
  };
  Outer&lt;int, int&gt; outer;                      // #1
  Outer&lt;int, int&gt;::Inner&lt;int, float&gt; inner;   // #2
</PRE>

<P>Is #1 ill-formed because of the identical partial specializations?
If not, presumably #2 is ill-formed because of the resulting
ambiguity (14.5.5.1 [temp.class.spec.match] paragraph 1).</P>

<P><B>Notes from the November, 2010 meeting:</B></P>

<P>The instantiation of <TT>Outer&lt;int,int&gt;</TT> results in
duplicate declarations of the partial specialization, which are
ill-formed by 9.2 [class.mem] paragraph 1. No normative
change is required, but it might be helpful to add an example like
this somewhere.</P>

<BR><BR><HR><A NAME="532"></A><H4>532.
  
Member/nonmember operator template partial ordering
</H4><B>Section: </B>14.5.6.2&#160; [temp.func.order]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Nathan Sidwell
 &#160;&#160;&#160;

 <B>Date: </B>16 September 2005<BR>


<P>[Voted into WP at August, 2010 meeting.]</P>



<P>The Standard does not specify how member and nonmember function
templates are to be ordered.  This question arises with an example
like the following:</P>

<PRE>
    struct A {
        template&lt;class T&gt; void operator&lt;&lt;(T&amp;);
    };

    template&lt;class T&gt; struct B { };
    template&lt;class T&gt; void operator&lt;&lt;(A&amp;, B&lt;T&gt;&amp;);

    int main() {
        A a;
        B&lt;A&gt; b;
        a &lt;&lt; b;
    }
</PRE>

<P>The two candidates for &#8220;<TT>a &lt;&lt; b</TT>&#8221; are:</P>

<OL>

<LI><TT>A::operator&lt;&lt; &lt;B&lt;A&gt; &gt;(B&lt;A&gt;&amp;)</TT></LI>

<LI><TT>::operator&lt;&lt; &lt;A&gt;(A&amp;, B&lt;A&gt;&amp;)</TT></LI>

</OL>

<P>How should we treat the implicit <TT>this</TT> parameter of #1 and the
explicit first parameter of #2?</P>

<UL>

<P>Option 0: Make them unordered.</P>

<P>Option 1: If either function is a non-static member function, ignore
any <TT>this</TT> parameter and ignore the first parameter of any
non-member function.  This option will select #2, as
&#8220;<TT>B&lt;T&gt;&amp;</TT>&#8221; is more specialized than
&#8220;<TT>T&amp;</TT>&#8221;.</P>

<P>Option 2: Treat the <TT>this</TT> parameter as if it were of
reference to object type, and then perform comparison to the first
parameter of the other function.  The other function's first parameter
will either be another <TT>this</TT> parameter, or it will be a
by-value or by-reference object parameter.  In the example above,
this option will also select #2.</P>

</UL>

<P>The difference between option 1 and option 2 can be seen in the
following example:</P>

<PRE>
    struct A { };

    template&lt;class T&gt; struct B {
        template&lt;typename R&gt; int operator*(R&amp;);   //<SPAN style="font-family:Times;font-style:italic"> #1</SPAN>
    };

    template &lt;typename T&gt; int operator*(T&amp;, A&amp;);  //<SPAN style="font-family:Times;font-style:italic"> #2</SPAN>

    int main() {
        A a;
        B&lt;A&gt; b;
        b * a;
    }
</PRE>

<P>Should this select #1, select #2, or be ambiguous?  Option 1 will
select #2, because &#8220;<TT>A&amp;</TT>&#8221; is more specialized
than &#8220;<TT>T&amp;</TT>&#8221;.  Option 2 will make this example
ambiguous, because &#8220;<TT>B&lt;A&gt;&amp;</TT>&#8221; is more
specialized than &#8220;<TT>T&amp;</TT>&#8221;.</P>

<P>If one were considering two non-member templates,</P>

<PRE>
    template &lt;typename T&gt; int operator*(T&amp;, A&amp;);                 //<SPAN style="font-family:Times;font-style:italic"> #2</SPAN>
    template &lt;typename T, typename R&gt; int operator*(B&lt;A&gt;&amp;, R&amp;);  //<SPAN style="font-family:Times;font-style:italic"> #3</SPAN>
</PRE>

<P>the current rules would make these unordered.  Option 2 thus seems
more consistent with this existing behavior.</P>

<P><B>Notes from the April, 2006 meeting:</B></P>

<P>The group favored option 2.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 14.5.6.2 [temp.func.order] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<P>...and substitute it for each occurrence of that parameter in
the function type of the template. <SPAN style="font-weight:bold;background-color:#A0FFA0">If only one of the
function templates is a non-static member, that function template
is considered to have a new first parameter inserted in its
function parameter list. The new parameter is of type
&#8220;reference to <I>cv</I> <TT>A</TT>,&#8221; where <I>cv</I> are
the cv-qualifiers of the function template (if any) and
<TT>A</TT> is the class of which the function template is a
member. [<I>Note:</I> This allows a non-static member to be
ordered with respect to a nonmember function and for the results
to be equivalent to the ordering of two equivalent
nonmembers. &#8212;<I>end note</I>] [<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  struct A { };
  template&lt;class T&gt; struct B {
    template&lt;typename R&gt; int operator*(R&amp;); //<SPAN style="font-family:Times;font-style:italic"> #1</SPAN>
  };

  template&lt;typename T, typename R&gt; int operator*(T&amp;, R&amp;); //<SPAN style="font-family:Times;font-style:italic"> #2</SPAN>

  //<SPAN style="font-family:Times;font-style:italic"> The declaration of </SPAN>B::operator*<SPAN style="font-family:Times;font-style:italic"> is transformed into the equivalent of</SPAN>
  //<SPAN style="font-family:Times;font-style:italic"> </SPAN>template&lt;typename R&gt; int operator*(B&lt;A&gt;&amp;, R&amp;);  //<SPAN style="font-family:Times;font-style:italic"> #1a</SPAN>

  int main() {
    A a;
    B&lt;A&gt; b;
    b * a;   //<SPAN style="font-family:Times;font-style:italic"> calls #1a</SPAN>
  }</SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1156"></A><H4>1156.
  
Partial ordering in a non-call context
</H4><B>Section: </B>14.5.6.2&#160; [temp.func.order]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-03<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US70">N3092 comment
  US&#160;70<BR></A>

<P>14.8.2.4 [temp.deduct.partial] paragraph 3 specifies that
the deduction used in partial ordering in a non-call context
is based on the complete function type of the function
templates. The wording in 14.5.6.2 [temp.func.order]
paragraph 2 (and echoed in paragraph 4) reflects an earlier
specification, however, saying that the deduction uses only
&#8220;the function parameter types, or in the case of a
conversion function the return type.&#8221; This is a
contradiction.  The wording in 14.5.6.2 [temp.func.order]
should be changed.</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<OL><LI><P>Change 14.5.6.2 [temp.func.order] paragraph 2 as
follows:</P></LI>

<BLOCKQUOTE>

Partial ordering selects which of two function templates is more
specialized than the other by transforming each template in turn (see
next paragraph) and performing template argument deduction using the
function <SPAN style="text-decoration:line-through;background-color:#FFA0A0">parameter types, or in the case of a conversion function
the return</SPAN> type. The deduction process determines whether one of
the templates is more specialized than the other. If so, the more
specialized template is the one chosen by the partial ordering
process.

</BLOCKQUOTE>

<LI><P>Change 14.5.6.2 [temp.func.order] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

Using the transformed function template's function <SPAN style="text-decoration:line-through;background-color:#FFA0A0">parameter
list, or in the case of a conversion function its transformed
return</SPAN> type, perform type deduction against the function
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">parameter list (or return type)</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">type</SPAN> of the
other function <SPAN style="font-weight:bold;background-color:#A0FFA0">template</SPAN>. The mechanism for performing these
deductions is given in 14.8.2.4 [temp.deduct.partial].

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1235"></A><H4>1235.
  
&#8220;Unused&#8221; ellipsis and default arguments in partial ordering
</H4><B>Section: </B>14.5.6.2&#160; [temp.func.order]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>James Widman
 &#160;&#160;&#160;

 <B>Date: </B>2011-01-18<BR>




<P>The specification for how to handle default arguments and ellipsis
in partial ordering of function templates is confusing.
14.5.6.2 [temp.func.order] paragraph 5 currently reads,</P>

<BLOCKQUOTE>

The presence of unused ellipsis and default arguments has no effect on
the partial ordering of function templates.

</BLOCKQUOTE>

<P>It is not clear what &#8220;unused&#8221; means in this context.
According to the original issue resolution that resulted in this
wording (<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1997/N1053.pdf">N1053</A>,
item 6.55), the intent was that &#8220;When partial ordering of
function templates containing a different number of parameters is done,
only the common parameters are considered.&#8221; Presumably this
would include parameters with default arguments if each function had
such parameters in corresponding positions.</P>

<P>The wording needs to be revised to make this intent clear.</P>

<P><B>Proposed resolution (March, 2011):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#692">issue 692</A> in document N3281.</P>

<BR><BR><HR><A NAME="1056"></A><H4>1056.
  
Template aliases, member definitions, and the current instantiation
</H4><B>Section: </B>14.5.7&#160; [temp.alias]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>2010-03-17<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>According to 14.6.2.1 [temp.dep.type] paragraph 1, in a primary
class template a name refers to the current instantiation if it is the
injected-class-name or the name of the class template followed by the
template argument list of the template.  Although a <I>template-id</I>
referring to a specialization of a template alias is described as
&#8220;equivalent to&#8221; the associated type, a specialization of
a template alias is neither of the things that qualifies as naming the
current instantiation, so presumably the <TT>typename</TT> keyword in
the following example is required:</P>

<PRE>
    template &lt;class T&gt; struct A;
    template &lt;class T&gt; using B = A&lt;T&gt;;

    template &lt;class T&gt; struct A {
        struct C {};
        typename B&lt;T&gt;::C bc;  // typename needed
    };
</PRE>

<P>(However, the list in 14.6.2.1 [temp.dep.type] may not be
exactly what we want; it doesn't allow use of a typedef denoting
the type of the current instantiation, either, but that presumably
should be accepted.)</P>

<P>For analogous reasons, it should not be permitted to use a
template alias as a <I>nested-name-specifier</I> when defining the
members of a class template:</P>

<PRE>
    template &lt;class T&gt; struct A {
        void g();
    };
    template &lt;class T&gt; using B = A&lt;T&gt;;
    template &lt;class T&gt; void B&lt;T&gt;::g() {} // error
</PRE>

<P><B>Notes from the November, 2010 meeting:</B></P>

<P>The CWG disagreed with the suggested direction, feeling that aliases
should work like typedefs and that the examples should be accepted.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<OL><LI><P>Change 14.6.2.1 [temp.dep.type] paragraph 1 as
follows:</P></LI>

<BLOCKQUOTE>

<P>In the definition of a class template, a nested class of a class
template, a member of a class template, or a member of a nested class
of a class template, a name refers to the <I>current instantiation</I>
if it is</P>

<UL><LI><P>the injected-class-name (Clause <sectkon_ref ref="9">9 [class]</sectkon_ref>) of
the class template or nested class,</P></LI>

<LI><P>in the definition of a primary class template, the name of the
class template followed by the template argument list of the primary
template (as described below) enclosed in <TT>&lt;&gt;</TT> <SPAN style="font-weight:bold;background-color:#A0FFA0">(or
a template alias specialization equivalent to same)</SPAN>,</P></LI>

<LI><P>in the definition of a nested class of a class template, the
name of the nested class referenced as a member of the current
instantiation, or</P></LI>

<LI><P>in the definition of a partial specialization, the name of the
class template followed by the template argument list of the partial
specialization enclosed in <TT>&lt;&gt;</TT> <SPAN style="font-weight:bold;background-color:#A0FFA0">(or a template
alias specialization equivalent to same)</SPAN>. If the <I>n</I>th
template parameter is a parameter pack, the <I>n</I>th template
argument is a pack expansion (14.5.3 [temp.variadic]) whose
pattern is the name of the parameter pack.</P></LI>

</UL>

</BLOCKQUOTE>

<P>Change 14.6.2.1 [temp.dep.type] paragraph 3 as follows:</P>

A template argument that is equivalent to a template parameter (i.e.,
has the same constant value or the same type as the template
parameter) can be used in place of that template parameter in a
reference to the current instantiation<SPAN style="font-weight:bold;background-color:#A0FFA0">, except that a
<I>decltype-specifier</I> that denotes a dependent type is always
considered non-equivalent</SPAN>. In the case of a non-type
template argument, the argument must have been given the value of the
template parameter and not an expression in which the template
parameter appears as a subexpression. [<I>Example:</I>...

</OL>

<P>This resolution also resolves <A HREF="
     cwg_defects.html#1057">issue 1057</A>.</P>

<BR><BR><HR><A NAME="1158"></A><H4>1158.
  
Recursive instantiation via alias template
</H4><B>Section: </B>14.5.7&#160; [temp.alias]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-03<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US73">N3092 comment
  US&#160;73<BR></A>

<P>The current wording of 7.1.3 [dcl.typedef]
paragraph 2 requires that the identifier in an
<I>alias-declaration</I> &#8220;...shall not appear in the
<I>type-id</I>.&#8221; With template aliases, however, the
name of the alias can be used indirectly:</P>

<PRE>
    template&lt;typename T&gt; struct A;
    template&lt;typename T&gt; using B=typename A&lt;T&gt;::U;
    template&lt;typename T&gt; struct A {
      typedef B&lt;T&gt; U;
    };
    B&lt;short&gt; b;
</PRE>

<P>Here the instantiation of <TT>B&lt;short&gt;</TT> causes
the instantiation of <TT>A&lt;short&gt;</TT>, and the
typedef in <TT>A&lt;short&gt;</TT> ends up attempting to use
<TT>B&lt;short&gt;</TT>, which is still in the process of
being instantiated.</P>

<P>There should be an explicit prohibition of such uses.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Add the following as a new paragraph at the end of
14.5.7 [temp.alias]:</P>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">The <I>type-id</I> in an alias template declaration
shall not refer to the alias template being declared. The
type produced by an alias template specialization shall not
directly or indirectly make use of that
specialization. [<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  template &lt;class T&gt; struct A;
  template &lt;class T&gt; using B = typename A&lt;T&gt;::U;
  template &lt;class T&gt; struct A {
    typedef B&lt;T&gt; U;
  };
  B&lt;short&gt; b; //<SPAN style="font-family:Times;font-style:italic"> Error: instantiation of </SPAN>B&lt;short&gt;<SPAN style="font-family:Times;font-style:italic"> uses own type via </SPAN>A&lt;short&gt;::U.</SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

<I>[Note: this wording assumes the change from &#8220;template
alias&#8221; to &#8220;alias template&#8221; requested by comment
FI 11 on FCD N3092.]</I>

<BR><BR><HR><A NAME="1159"></A><H4>1159.
  
Class and enumeration definitions in template aliases
</H4><B>Section: </B>14.5.7&#160; [temp.alias]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-03<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US74">N3092 comment
  US&#160;74<BR></A>

<P>An <I>alias-declaration</I> allows a class or enumeration
type to be defined in its <I>type-id</I> (7.1.6 [dcl.type] paragraph 3). However, it's not clear that
this is desirable when the <I>alias-declaration</I> is part
of a template alias:</P>

<PRE>
    template&lt;typename T&gt; using A =
      struct { void f(T) { } };
</PRE>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change 7.1.6 [dcl.type] paragraph 3 as follows:</P>

<BLOCKQUOTE>

...A <I>type-specifier-seq</I> shall not define a class or
enumeration unless it appears in the <I>type-id</I> of an
<I>alias-declaration</I> (7.1.3 [dcl.typedef])
<SPAN style="font-weight:bold;background-color:#A0FFA0">that is not the <I>declaration</I> of a
<I>template-declaration</I></SPAN>.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1161"></A><H4>1161.
  
Dependent <I>nested-name-specifier</I> in a pointer-to-member declarator
</H4><B>Section: </B>14.6&#160; [temp.res]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>GB
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-03<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#GB44">N3092 comment
  GB&#160;44<BR></A>

<P>It is not clear from the current wording of 14.6 [temp.res]
whether the following is well-formed or not:</P>

<PRE>
    template&lt;typename T&gt; struct id { typedef T type; };
    template&lt;typename T&gt; void f() { int id&lt;T&gt;::type::*p = 0; }
    struct A { };
    int main() { f&lt;A&gt;(); }
</PRE>

<P>If <TT>typename</TT> is required before the use of
<TT>id&lt;T&gt;::type</TT>, it is not permitted by the current
syntax.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change 14.6 [temp.res] paragraph 5 as follows:</P>

<BLOCKQUOTE>

A qualified name used as the name in a <I>mem-initializer-id</I>, a
<I>base-specifier</I>, or an
<I>elaborated-type-specifier</I> is implicitly assumed to
name a type, without the use of the <TT>typename</TT>
keyword. <SPAN style="font-weight:bold;background-color:#A0FFA0">In a <I>nested-name-specifier</I> that
immediately contains a <I>nested-name-specifier</I> that
depends on a template parameter, the <I>identifier</I> or
<I>simple-template-id</I> is implicitly assumed to name a
type, without the use of the <TT>typename</TT>
keyword.</SPAN> [<I>Note:</I> the <TT>typename</TT> keyword
is not permitted by the syntax of these
constructs. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<BR><BR><HR><A NAME="448"></A><H4>448.
  
Set of template functions in call with dependent explicit argument
</H4><B>Section: </B>14.6.1&#160; [temp.local]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Mark Mitchell
 &#160;&#160;&#160;

 <B>Date: </B>4 Jan 2004<BR>


<P>[Voted into WP at August, 2010 meeting.]</P>

<P>Is this program valid?</P>
<PRE>
  template &lt;typename T&gt; int g(int);
  class h{};
  template &lt;typename T&gt; int l(){h j; return g&lt;T&gt;(j);}
  template &lt;typename T&gt; int g(const h&amp;);
  class j{};
  int jj(){return l&lt;j&gt;();}
</PRE>
<P>The key issue is when "g" is looked up, i.e., whether both overloaded
template "g" functions are available at the call site or only the
first.  Clearly, the entire postfix-expression "g&lt;T&gt;(j)" is dependent,
but when is the set of available template functions determined?</P>

<P>For consistency with the rules about when the set of available
overloads is determined when calling a function given by an
unqualified-id, I would think that we should postpone determining the
set of template functions if (and only if) any of the explicit
template arguments are dependent.</P>

<P><U>John Spicer:</U>
I agree that there should be a core issue for this.  The definition of 
"dependent name" (14.6.2 [temp.dep] paragraph 1)
should probably be modified to cover this case.  It 
currently only handles cases where the function name is a simple
identifier.</P>

<P><B>Notes from the March 2004 meeting:</B></P>

<P>A related issue is a call with a qualified name and dependent
arguments, e.g., <TT>x::y(depa, depb)</TT>.</P>

<P><B>Proposed resolution (June, 2010):</B></P>

<OL><LI><P>Change 14.6.2 [temp.dep] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<P>...In an expression of the form:</P>

<UL><I>postfix-expression</I> <TT>(</TT> <I>expression-list<SUB>opt</SUB></I> <TT>)</TT></UL>

<P>where the <I>postfix-expression</I> is an
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>unqualified-id</I></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>id-expression</I></SPAN>, the
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>unqualified-id</I></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>id-expression</I></SPAN> denotes a <I>dependent
name</I> if <SPAN style="text-decoration:line-through;background-color:#FFA0A0">and only if</SPAN> any of the expressions in
the <I>expression-list</I> is a type-dependent expression
(14.6.2.2 [temp.dep.expr]) <SPAN style="font-weight:bold;background-color:#A0FFA0">or if the
<I>unqualified-id</I> of the <I>id-expression</I> is a
<I>template-id</I> in which any of the template arguments depends
on a template parameter</SPAN>.  If an operand of an operator is a
type-dependent expression, the operator also denotes a dependent
name.  Such names are unbound and are looked up at the point of
the template instantiation (14.6.4.1 [temp.point]) in
both the context of the template definition and the context of
the point of instantiation.</P>

</BLOCKQUOTE>

<LI><P>Change 14.6.4.2 [temp.dep.candidate] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<P>For a function call that depends on a template parameter, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">if
the function name is an <I>unqualified-id</I>
or if the function is called using operator
notation,</SPAN> the candidate functions are found using the usual
lookup rules (3.4.1 [basic.lookup.unqual], 3.4.2 [basic.lookup.argdep]<SPAN style="font-weight:bold;background-color:#A0FFA0">, 3.4.3 [basic.lookup.qual]</SPAN>) except
that:</P>

<UL><LI><P>For the part of the lookup using unqualified name
lookup (3.4.1 [basic.lookup.unqual]) <SPAN style="font-weight:bold;background-color:#A0FFA0">or qualified name
lookup (3.4.3 [basic.lookup.qual])</SPAN>, only function
declarations from the template definition context are
found.</P></LI>

<LI><P>For the part of the lookup using associated
namespaces (3.4.2 [basic.lookup.argdep]), only function
declarations found in either the template definition context
or the template instantiation context are found.</P></LI>

</UL>

<P>If <SPAN style="font-weight:bold;background-color:#A0FFA0">the function name is an <I>unqualified-id</I>
and</SPAN> the call would be ill-formed or would find a better
match had the lookup within the associated namespaces considered
all the function declarations with external linkage introduced in
those namespaces in all translation units, not just considering
those declarations found in the template definition and template
instantiation contexts, then the program has undefined
behavior.</P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="458"></A><H4>458.
  
Hiding of member template parameters by other members
</H4><B>Section: </B>14.6.1&#160; [temp.local]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Gabriel Dos Reis
 &#160;&#160;&#160;

 <B>Date: </B>2 Feb 2004<BR>


<P>[Voted into WP at August, 2010 meeting.]</P>



<P>The list of cases in 14.6.1 [temp.local]
about when a template parameter is hidden
seems to be incomplete.</P>

<P>Consider</P>
<PRE>
      // example-1
    struct S {
       int C;
       template&lt;class&gt; void f();
    };

    template&lt;class C&gt;
      void S::f()
      {
         C c;           // #1
      }
</PRE>
<P>Someone asked whether line #1 is well-formed and I responded "no"
based on my understanding of the rules in 14.6.1.
After a second looking, I've realized that the above case is currently
missing from the list.</P>

<P>The list in 14.6.1 covers cases like
<PRE>
     // example-2
   template&lt;class T&gt;
     struct S {
        int C;
        void f();
     };

   template&lt;class C&gt;
     void S&lt;C&gt;::f()
     {
       C c;     // ERROR: 'C' is 'S::C' not the template parameter
     }
</PRE>
or
<PRE>
     // example-3
   struct A { int C; }

   template&lt;class C&gt;
      struct S : A {
        C c;    // ERROR: 'C' is 'A::C', not the template parameter
      };
</PRE>
But the case of a 'member template' is missing.  I believe it should
follow the same rule as above.  The reason is this.</P>

<P>In the case listed in 14.6.1 (having to do with members of classes),
the "algorithm" seems to be this:
<OL>
<LI>
put the "template parameter scope"[1] on the top of active
       scope stack.  That will make the template parameter
       declarations the innermost bindings.
</LI>
<LI>
Enter the class scope. That will push more scopes on the stack.
       In particular, any bindings from non-dependent base classes or
       from the class definition will hide any previous bindings,
       especially the template parameter declarations.
</LI>
</OL>
The above formulation uniformly covers paragraphs 5 and 7 of section
14.6.1 and gives a general view of how name lookup is supposed to 
happen.</P>

<P>I believe that any rule, coherent with 14.6.1/5 and 14.6.1/7, for
covering the  cases of member templates (example-1) will be described
by the above "algorithm".</P>

<P>Am I missing something?</P>

<P>[1] of course, the standard text does not formally speak of "template
    parameter scope", but we all know that the template parameters
    "live" somewhere.  I'm using that terminology to designate the
    declarative region of the template parameters.</P>

<P><U>Mike Miller:</U>
I have a somewhat different perspective on this question.  I
think your example-1 is fundamentally different from your
example-2 and example-3.  Looking, for instance, at your
example-2, I see four nested scopes:</P>
<PRE>
     namespace scope
       template scope (where the parameter is)
         class S scope
           S::f() block scope
</PRE>
<P>Naturally, S::C hides the template parameter C.  The same is
true of your example-3, with three scopes:</P>
<PRE>
     namespace scope
       template scope
         class S scope (includes 10.2 base class lookup)
</PRE>
<P>Again, it's clear that the C inherited from A hides the template
parameter in the containing scope.</P>

<P>The scopes I see in your example-1, however, are different:</P>
<PRE>
     namespace scope
       struct S scope
         template scope (where the parameter is)
           S::f() block scope
</PRE>
<P>Here it seems clear to me that the template parameter hides the
class member.</P>

<P>It might help to look at the case where the function template is
defined inline in the class:</P>
<PRE>
     struct S {
        int C;
        template&lt;class C&gt; int f() {
            C c;   // #1
        }
     };
</PRE>
<P>It would be pretty strange, I think, if the #1 C were the member
and not the template parameter.  It would also be odd if the
name lookup were different between an inline definition and an
out-of-line definition.</P>

<P>See also <A HREF="
     cwg_active.html#459">issue 459</A>.</P>

<P><B>Notes from the March 2004 meeting:</B></P>

<P>Basically, the standard is okay.  We think Gaby's desired
cases like #1 should be ill-formed.</P>

<P> There is a wording problem in 14.6.1 [temp.local] paragraph 7.
It says:</P>
<BLOCKQUOTE>
In the definition of a member of a class template that appears outside of the 
class template definition, the name of a member of this template hides
the name of a template-parameter.
</BLOCKQUOTE>

<P>It should say "hides the name of a template-parameter of the class template 
(but not a template-parameter of the member, if the member is itself a 
template)" or words to that effect.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 14.6.1 [temp.local] paragraph 8 as follows:</P>

<BLOCKQUOTE>

<P>In the definition of a member of a class template that appears
outside of the class template definition, the name of a member of
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">this</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">the class</SPAN> template hides the name of a
<I>template-parameter</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">of any enclosing class templates
(but not a <I>template-parameter</I> of the member, if the member
is a class or function template)</SPAN>. [<I>Example:</I></P>

<PRE>
  template&lt;class T&gt; struct A {
    struct B { /* ... */ };
<SPAN style="font-weight:bold;background-color:#A0FFA0">    typedef void C;</SPAN>
    void f();
<SPAN style="font-weight:bold;background-color:#A0FFA0">    template&lt;class U&gt; void g(U);</SPAN>
  };

  template&lt;class B&gt; void A&lt;B&gt;::f() {
    B b;   // A<SPAN style="font-family:Times;font-style:italic">'s </SPAN>B<SPAN style="font-family:Times;font-style:italic">, not the template parameter</SPAN>
  }

<SPAN style="font-weight:bold;background-color:#A0FFA0">  template&lt;class B&gt; template&lt;class C&gt; void A&lt;B&gt;::g(C) {
    B b;   // A<SPAN style="font-family:Times;font-style:italic">'s </SPAN>B<SPAN style="font-family:Times;font-style:italic">, not the template parameter</SPAN>
    C c;   // <SPAN style="font-family:Times;font-style:italic">the template parameter </SPAN>C<SPAN style="font-family:Times;font-style:italic">, not </SPAN>A<SPAN style="font-family:Times;font-style:italic">'s </SPAN>C
  }</SPAN>
</PRE>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="602"></A><H4>602.
  
When is the injected-class-name of a class template a template?
</H4><B>Section: </B>14.6.1&#160; [temp.local]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>23 October 2006<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>Consider the following example:</P>

<PRE>
    template&lt;class T&gt;
    struct A {
         template&lt;class U&gt;
             friend struct A; // Which A?
    };
</PRE>

<P>Presumably the lookup for <TT>A</TT> in the friend declaration finds
the injected-class-name of the template.  However, according to
14.6.1 [temp.local] paragraph 1,</P>

<BLOCKQUOTE>

The injected-class-name can be used with or without a
<I>template-argument-list</I>. When it is used without a
<I>template-argument-list</I>, it is equivalent to the
injected-class-name followed by the <I>template-parameter</I>s of the
class template enclosed in <TT>&lt;&gt;</TT>. When it is used with a
<I>template-argument-list</I>, it refers to the specified class
template specialization, which could be the current specialization or
another specialization.

</BLOCKQUOTE>

<P>If that rule applies, then this example is ill-formed (because you
can't have a <I>template-argument-list</I> in a class template
declaration that is not a partial specialization).</P>

<P><U>Mike Miller</U>: The injected-class-name has a dual nature, as
described in 14.6.1 [temp.local], acting as either a
template name or a class name, depending on the context; a template
argument list forces the name to be interpreted as a template.  It
seems reasonable that in this example the injected-class-name has to
be understood as referring to the class template; a template header is
at least as strong a contextual indicator as a template argument list.
However, the current wording doesn't say that.</P>

<P>(See also <A HREF="
     cwg_defects.html#1004">issue 1004</A>.)</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#1004">issue 1004</A>.</P>

<BR><BR><HR><A NAME="1004"></A><H4>1004.
  
Injected-class-names as arguments for template template parameters
</H4><B>Section: </B>14.6.1&#160; [temp.local]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2009-11-19<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>The injected-class-name of a class template can be used either
by itself, in which case it is a type denoting the current instantiation,
or followed by a template argument list, in which case it is a
<I>template-name</I>.  It would be helpful to extend this treatment
so that the injected-class-name could be used as an argument for a template
template parameter:</P>

<PRE>
    template &lt;class T&gt; struct A { };

    template &lt;template &lt;class&gt; class TTP&gt; struct B { };

    struct C: A&lt;int&gt; {
       B&lt;A&gt; b;
    };
</PRE>

<P>(This is accepted by g++.)</P>

<P><U>James Widman</U>:</P>

<P>It would not be so helpful when used with overloaded function
templates, for example:</P>

<PRE>
    template &lt;template &lt;class&gt; class TTP&gt;  void f(); // #1
    template &lt;                 class T  &gt;  void f(); // #2

    template &lt;class T&gt; struct A { };

    struct C: A&lt;int&gt; {
        void h(  ) {
            f&lt;A&gt;(); //  #1?  #2?  Substitution failure?
        }
    };
</PRE>

<P>(See also <A HREF="
     cwg_defects.html#602">issue 602</A>.)</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change 14.6.1 [temp.local] paragraphs 1-5 as follows:</P>

<BLOCKQUOTE>

<P>Like normal (non-template) classes, class templates have an
injected-class-name (Clause 9 [class]).  The
injected-class-name can be used <SPAN style="text-decoration:line-through;background-color:#FFA0A0">with or without a
<I>template-argument-list</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">as a <I>template-name</I>
or a <I>type-name</I></SPAN>. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">When it is used without a
<I>template-argument-list</I>, it is equivalent to the
injected-class-name followed by the <I>template-parameter</I>s of the
class template enclosed in <TT>&lt;&gt;</TT>.</SPAN> When it is used
with a <I>template-argument-list</I>, <SPAN style="font-weight:bold;background-color:#A0FFA0">as a
<I>template-argument</I> for a template <I>template-parameter</I>, or
as the final identifier in the <I>elaborated-type-specifier</I> of a
friend class template declaration</SPAN> it refers to the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">specified
class template specialization, which could be the current
specialization or another specialization.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">class template
itself.  Otherwise, it is equivalent to the <I>template-name</I>
followed by the <I>template-parameter</I>s of the class template
enclosed in <TT>&lt;&gt;</TT>.</SPAN></P>

<P>Within the scope of a class template specialization or partial
specialization, when the injected-class-name is not <SPAN style="text-decoration:line-through;background-color:#FFA0A0">followed by a
<TT>&lt;</TT></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">used as a <I>type-name</I></SPAN>, it is
equivalent to the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">injected-class-name</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>template-name</I></SPAN> followed by the
<I>template-argument</I>s of the class template specialization or
partial specialization enclosed in
<TT>&lt;&gt;</TT>. [<I>Example:</I></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  template&lt;template&lt;class&gt; class T&gt; class A { };</SPAN>
  template&lt;class T&gt; class Y;
  template&lt;&gt; class Y&lt;int&gt; {
    Y* p;           //<SPAN style="font-family:Times;font-style:italic"> meaning </SPAN>Y&lt;int&gt;
    Y&lt;char&gt;* q;     //<SPAN style="font-family:Times;font-style:italic"> meaning </SPAN>Y&lt;char&gt;
<SPAN style="font-weight:bold;background-color:#A0FFA0">    A&lt;Y&gt;* a;        //<SPAN style="font-family:Times;font-style:italic"> meaning </SPAN>A&lt;::Y&gt;
    class B {
      template&lt;class&gt; friend class Y;  //<SPAN style="font-family:Times;font-style:italic"> meaning </SPAN>::Y
    };</SPAN>
  };
</PRE>

<P>&#8212;<I>end example</I>]</P>

<P>The injected-class-name of a class template or class template
specialization can be used either <SPAN style="text-decoration:line-through;background-color:#FFA0A0">with or without a
<I>template-argument-list</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">as a <I>template-name</I> or
a <I>type-name</I></SPAN> wherever it is in scope. [<I>Example:</I></P>

<PRE>
  template &lt;class T&gt; struct Base {
    Base* p;
  };

  template &lt;class T&gt; struct Derived: public Base&lt;T&gt; {
    typename Derived::Base* p;    //<SPAN style="font-family:Times;font-style:italic"> meaning </SPAN>Derived::Base&lt;T&gt;
  };

<SPAN style="font-weight:bold;background-color:#A0FFA0">  template&lt;class T, template&lt;class&gt; class U = T::template Base&gt; struct Third { };
  Third&lt;Base&lt;int&gt;&gt; t; //<SPAN style="font-family:Times;font-style:italic"> OK, default argument uses injected-class-name as a template</SPAN></SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

<P>A lookup that finds an injected-class-name (10.2 [class.member.lookup]) can result in an ambiguity in certain cases (for
example, if it is found in more than one base class). If all of the
injected-class-names that are found refer to specializations of the
same class template, and if the name is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">followed by a
<I>template-argument-list</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">used as a
<I>template-name</I></SPAN>, the reference refers to the class template
itself and not a specialization thereof, and is not
ambiguous. [<I>Example:</I></P>

<PRE>
  template &lt;class T&gt; struct Base { };
  template &lt;class T&gt; struct Derived: Base&lt;int&gt;, Base&lt;char&gt; {
    typename Derived::Base b;             //<SPAN style="font-family:Times;font-style:italic"> error: ambiguous</SPAN>
    typename Derived::Base&lt;double&gt; d;     //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
  };
</PRE>

<P>&#8212;<I>end example</I>]</P>

<P>When the normal name of the template (i.e., the name from the
enclosing scope, not the injected-class-name) is used <SPAN style="text-decoration:line-through;background-color:#FFA0A0">without a
<I>template-argument-list</I></SPAN>, it <SPAN style="font-weight:bold;background-color:#A0FFA0">always</SPAN> refers to
the class template itself and not a specialization of the
template. [<I>Example:...</I></P>

</BLOCKQUOTE>

<P>This resolution also resolves <A HREF="
     cwg_defects.html#602">issue 602</A>.</P>

<BR><BR><HR><A NAME="1233"></A><H4>1233.
  
Pack expansions and dependent calls
</H4><B>Section: </B>14.6.2&#160; [temp.dep]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>2011-01-11<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>In an example like</P>

<PRE>
  void f(int, int, int);
  template&lt;int ...N&gt; void g() {
    f((N+N)...);
  }
  void h() {
    g&lt;1, 2, 3&gt;();
  }
</PRE>

<P>the call to <TT>f</TT> needs to be dependent; however, the arguments
are not type-dependent, so the criteria of 14.6.2 [temp.dep]
paragraph 1 are not met.  Presumably the specification needs to be
updated so that an argument list containing a type-level pack expansion
is dependent.</P>

<BR><BR><HR><A NAME="502"></A><H4>502.
  
Dependency of nested enumerations and enumerators
</H4><B>Section: </B>14.6.2.1&#160; [temp.dep.type]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Mark Mitchell
 &#160;&#160;&#160;

 <B>Date: </B>05 Feb 2005<BR>


<P>[Voted into WP at August, 2010 meeting.]</P>

<P>The Standard is currently silent on the dependency status of
enumerations and enumerators that are members of class templates.
There are three questions that must be answered in this regard:</P>

<OL>

<LI><P><B>Are enumeration members of class templates dependent
types?</B></P>

<P>It seems clear that nested enumerations must be dependent.  For
example:</P>

<PRE>
    void f(int);

    template&lt;typename T&gt; struct S {
        enum E { e0 };
        void g() {
            f(e0);
        }
    };

    void f(S&lt;int&gt;::E);

    void x() {
        S&lt;int&gt; si;
        si-&gt;g();       // Should call f(S&lt;int&gt;::E)
    }
</PRE>

</LI>

<LI><P><B>Is <TT>sizeof</TT> applied to a nested enumeration a
value-dependent expression (14.6.2.3 [temp.dep.constexpr])?</B></P>

<P>There are three distinct cases that might have different answers
to this question:</P>

<UL>

<LI><PRE>
    template&lt;typename T&gt; struct S {
        enum E { e0 };
    };
</PRE>

<P>Here, the size of <TT>E</TT> is, in principle, known at the time
the template is defined.</P>

</LI>

<LI><PRE>
    template&lt;short I&gt; struct S {
        enum E { e0 = I };
    };
</PRE>

<P>In this case, the minimum size required for <TT>E</TT> cannot be
determined until instantiation, but it is clear that the underlying
type need be no larger than <TT>short</TT>.</P>

</LI>

<LI><PRE>
    template&lt;typename T&gt; struct S {
        enum E { e0 = T::e0; };
    }
</PRE>

<P>Here, nothing can be known about the size of <TT>E</TT> at the time
the template is defined.</P>

</LI>

</UL>

<P>14.6.2.3 [temp.dep.constexpr] paragraph 2 says that a
<TT>sizeof</TT> expression is value-dependent if the type of the
operand is type-dependent.  Unless enumerations are given special
treatment, all three of these examples will have value-dependent
sizes.  This could be surprising for the first case, at least, if not
the second as well.</P>

</LI>

<LI><P><B>Are nested enumerators value-dependent expressions?</B></P>

<P>Again the question of dependent initializers comes into play.  As an
example, consider:</P>

<PRE>
    template&lt;short I&gt; struct S {
        enum E { e0, e1 = I, e2 };
    };
</PRE>

<P>There seem to be three possible approaches as to whether the
enumerators of <TT>E</TT> are value-dependent:</P>

<OL type="A">

<LI><P>The enumerators of a nested enumeration are all
value-dependent, regardless of whether they have a value-dependent
initializer or not.  This is the current position of 14.6.2.3 [temp.dep.constexpr] paragraph 2, which says that an identifier is
value-dependent if it is a name declared with a dependent
type.</P></LI>

<LI><P>The enumerators of a nested enumeration are all value-dependent
if any of the enumeration's enumerators has a value-dependent
initializer.  In this approach, <TT>e0</TT> would be value-dependent,
even though it is clear that it has the value 0.</P></LI>

<LI><P>An enumerator of a nested enumeration is value-dependent only
if it has a value-dependent initializer (explict or implicit).  This
approach would make <TT>e1</TT> and <TT>e2</TT> value-dependent, but
not <TT>e0</TT>.</P></LI>

</OL>

<P>An example that bears on the third approach is the following:</P>

<PRE>
    template&lt;typename T&gt; struct S {
        enum E { N = UINT_MAX, O = T::O };
        int a[N + 2];
    };
</PRE>

<P>With the normal treatment of enumerations, the type of <TT>a</TT>
might be either <TT>int[UINT_MAX+2]</TT> or <TT>int[1]</TT>, depending
on whether the value of <TT>T::O</TT> was such that the underlying
type of <TT>E</TT> is <TT>unsigned int</TT> or <TT>long</TT>.
</P>

<P>One possibility for addressing this problem under the third
approach would be to treat a given enumerator as having the type of
its initializer in such cases, rather than the enumeration type.  This
would be similar to the way enumerators are treated within the
enumerator list, before the enumeration declaration is complete
(<sectioin_ref ref="7.2">7.2 [dcl.enum]</sectioin_ref> paragraph 5).  The argument against this
is that it makes arithmetic using enumerators behave differently when
the enumeration is a member of a class template and when it is not.</P>

</LI>

</OL>

<P><B>Notes from the April, 2005 meeting:</B></P>

<P>The CWG agreed on the following positions:</P>

<OL><LI><P>Nested enumerations are dependent types.</P></LI>

<LI><P>The result of the <TT>sizeof</TT> operator applied to a
nested enumeration is value-dependent unless there are no
dependent initializers in its definition; the first case above
is not dependent, while the second and third are dependent.</P>
</LI>

<LI><P>The approach described in 3.C above is correct.  This is
similar to the treatment of static const integral data members,
which are dependent only if their initializer is dependent.</P></LI>

</OL>

<P><B>Notes from the October, 2005 meeting:</B></P>

<P>There was no consensus among the CWG regarding question #3
(which enumerators should be considered value-dependent).  The
argument in favor of 3.C is principally that the values of enumerators
with non-dependent initializers are known at definition time, so there
is no need to treat them as dependent.</P>

<P>One objection to 3.C is that, according to the consensus of the
CWG, the enumeration type is dependent and thus even the known values
of the enumeration would have a dependent type, which could affect the
results when such enumerations are used in expressions.  A possible
response to this concern would be to treat non-dependent initializers
as having the type of the initializer rather than the enumeration
type, similar to the treatment of enumerators within
the <I>enumerator-list</I> (7.2 [dcl.enum] paragraph 5).
However, this approach would be inconsistent with the treatment of
other enumeration types.  It would also interfere with overload
resolution (e.g., the call in the example under question #1 above
would resolve to <TT>f(int)</TT> with this approach rather
than <TT>f(S&lt;int&gt;::E)</TT>).</P>

<P>Those in favor of option 3.A also suggested that it would be simpler
and require less drafting: if all the enumerators have the (dependent)
type of the enumeration, 14.6.2.3 [temp.dep.constexpr] paragraph 2
already says that a name with a dependent type is value-dependent, so
nothing further would need to be said.  Option 3.C would require
additional caveats to exempt some enumerators.</P>

<P>The proponents of 3.A also pointed out that there are many other
cases where a known value with a dependent type is treated as dependent:</P>

<PRE>
    static const T t = 0;
    ... A&lt;t&gt; ...
</PRE>

<P>or</P>

<PRE>
    template &lt;int I&gt; void f() {
        g(I-I);
    }
</PRE>

<P>With regard to current practice, g++ and MSVC++ implement 3.A, while
EDG implements 3.C.</P>

<P><B>Notes from the July, 2009 meeting:</B></P>

<P>The consensus of the CWG was that all the types and values are
dependent.</P>

<P><B>Proposed resolution (June, 2010):</B></P>

<P>Change 14.6.2.1 [temp.dep.type] paragraph 6 as
follows:</P>

<BLOCKQUOTE>

<P>A type is dependent if it is</P>

<UL><LI><P>...</P></LI>

<LI><P>a nested class <SPAN style="font-weight:bold;background-color:#A0FFA0">or enumeration</SPAN> that is a member
of the current instantiation,</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="590"></A><H4>590.
  
Nested classes and the &#8220;current instantiation&#8221;
</H4><B>Section: </B>14.6.2.1&#160; [temp.dep.type]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>James Widman
 &#160;&#160;&#160;

 <B>Date: </B>23 August 2006<BR>




<P>In 14.6.2.1 [temp.dep.type] paragraph 5 we have:</P>

<BLOCKQUOTE>

A name is a <I>member of an unknown specialization</I> if the name is a
<I>qualified-id</I> in which the <I>nested-name-specifier</I>
names a dependent type that is not the current instantiation.

</BLOCKQUOTE>

<P>So given:</P>

<PRE>
    template&lt;class T&gt; struct A {
        struct B {
            struct C {
                A&lt;T&gt;::B::C f();
            };
        };
    };
</PRE>

<P>it appears that the name <TT>A&lt;T&gt;::B::C</TT> should be
taken as a member of an unknown specialization, because the WP
refers to &#8220;the&#8221; current instantiation, implying that
there can be at most one at any given time.  At the declaration
of <TT>f()</TT>, the current instantiation is <TT>C</TT>,
so <TT>A&lt;T&gt;::B</TT> is not the current instantiation.</P>

<P>Would it be better to refer to &#8220;a known instantiation&#8221;
instead of &#8220;the current instantiation?&#8221;</P>

<P><U>Mike Miller</U>:</P>

<P>I agree that there is a problem here, but I don't think the
&#8220;current instantiation&#8221; terminology needs to be
replaced.  By way of background, paragraph 1 makes it clear that
<TT>A&lt;T&gt;::B</TT> &#8220;refers to&#8221; the current
instantiation:</P>

<BLOCKQUOTE>

<P>In the definition of a class template, a nested class of a
class template, a member of a class template, or a member of a
nested class of a class template, a name refers to the <I>current
instantiation</I> if it is</P>

<UL><LI><P>the injected-class-name (9 [class]) of
the class template or nested class,</P></LI>

<LI><P>in the definition of a primary class template, the name of
the class template followed by the template argument list of the
primary template (as described below) enclosed
in <TT>&lt;&gt;</TT>,</P></LI>

<LI><P>in the definition of a nested class of a class template,
the name of the nested class referenced as a member of the
current instantiation...</P></LI>

</UL>

</BLOCKQUOTE>

<P><TT>A&lt;T&gt;::B</TT> satisfies bullet 3.  Paragraph 4 says,</P>

<BLOCKQUOTE>

<P>A name is a member of the current instantiation if it is</P>

<UL><LI><P>An unqualified name that, when looked up, refers to a
member of a class template. [<I>Note:</I> this can only occur
when looking up a name in a scope enclosed by the definition of a
class template. &#8212;<I>end note</I>]</P></LI>

<LI><P>A <I>qualified-id</I> in which
the <I>nested-name-specifier</I> refers to the current
instantiation.</P></LI>

</UL>

</BLOCKQUOTE>

<P>So clearly by paragraphs 1 and 4, <TT>A&lt;T&gt;::B::C</TT> is
a member of the current instantiation.  The problem is in the
phrasing of paragraph 5, which incorrectly requires that the
<I>nested-name-specifier</I> &#8220;be&#8221; the current
instantiation rather than simply &#8220;referring to&#8221; the
current instantiation, which would be the correct complement to
paragraph 4.  Perhaps paragraph 5 could simply be rephrased as,
&#8220;...a dependent type and it is not a member of the current
instantiation.&#8221;</P>

<P>(Paragraph 1 may require a bit more wordsmithing to make it
truly recursive across multiple levels of nested classes; as it
stands, it's not clear whether the name of a nested class of a
nested class of a class template is covered or not.)</P>

<P><B>Additional note (April, 2011):</B></P>

<P>It appears that these concerns are addressed by the resolution
of <A HREF="
     cwg_defects.html#1043">issue 1043</A> in document N3283.</P>

<P><B>Proposed resolution (December, 2011):</B></P>

<P>This issue is resolved by the resolution of <A HREF="
     cwg_defects.html#1043">issue 1043</A>.</P>

<BR><BR><HR><A NAME="1043"></A><H4>1043.
  
Qualified name lookup in the current instantiation
</H4><B>Section: </B>14.6.2.1&#160; [temp.dep.type]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Doug Gregor
 &#160;&#160;&#160;

 <B>Date: </B>2010-03-05<BR>


<P>[Voted into the WP at the March, 2011 meeting as paper N3283.]</P>



<P>14.6.2.1 [temp.dep.type] paragraph 4 treats <I>unqualified-id</I>s
and <I>qualified-id</I>s in which the <I>nested-name-specifier</I> refers
to the current instantiation as equivalent.  However, the lookups
associated with these two <I>id-expression</I>s are different in the
presence of dependent base classes (14.6.2 [temp.dep]
paragraph 3): with an <I>unqualified-id</I>, a dependent base class
scope is never examined, while with a <I>qualified-id</I> it is. The
current wording does not specify how an example like the following is
to be handled:</P>

<PRE>
  template&lt;typename T&gt; struct B {};
  struct C { typedef int type; };

  template&lt;typename T&gt;
  struct A : B&lt;T&gt;, C {
    template&lt;typename U&gt; type a(); // #1
    template&lt;typename U&gt; typename A&lt;T&gt;::type a(); // #2: different from #1?
  };

  template&lt;typename T&gt; template&lt;typename U&gt; typename A&lt;T&gt;::type
    A&lt;T&gt;::a() { ... } // defines #1 or #2?
</PRE>

<P>There seem to be two possible strategies for the handling of
<TT>typename A&lt;T&gt;::type</TT>:</P>

<OL><LI><P>It is handled like the <I>unqualified-id</I> case,
looking only in non-dependent base classes and not being a
dependent type.</P></LI>

<LI><P>Since the current instantiation has dependent base classes,
it is handled as a dependent type.</P></LI>

</OL>

<P>EDG seems to be doing the former, g++ the latter.</P>

<P><B>Notes from the November, 2010 meeting:</B></P>

<P>The CWG agreed that if a name is found in a non-dependent base,
the type should be treated as non-dependent also.</P>

<P><B>Additional note (November, 2010):</B></P>

<P>The overall treatment of dependent base classes in handling a
<I>qualified-id</I> in which the <I>nested-name-specifier</I> names
the current instantiation or in a member access expression where the
object expression is <TT>*this</TT> is not very clear.  It would be
helpful if the resolution of this issue could clarify the overall
treatment while dealing with the mixed dependent/non-dependent case
given in the example.</P>

<BR><BR><HR><A NAME="1057"></A><H4>1057.
  
<TT>decltype</TT> and the current instantiation
</H4><B>Section: </B>14.6.2.1&#160; [temp.dep.type]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>2010-03-18<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>According to 14.6.2.1 [temp.dep.type] paragraph 3,</P>

<BLOCKQUOTE>

A template argument that is equivalent to a template parameter
(i.e., has the same constant value or the same type as the
template parameter) can be used in place of that template
parameter in a reference to the current instantiation.

</BLOCKQUOTE>

<P>This would presumably include something like</P>

<PRE>
    template&lt;typename T&gt; struct A {
        struct B { };
        A&lt;decltype(T())&gt;::B b;    // no typename
    };
</PRE>

<P>However, this example is rejected by current implementations.
Does this need to be clarified in the existing wording?</P>

<P><B>Notes from the November, 2010 meeting:</B></P>

<P>The example is not well-formed; if <TT>T</TT> is an rvalue reference
type, for example, <TT>decltype(T())</TT> is not equivalent to
<TT>T</TT>.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#1056">issue 1056</A>.</P>

<BR><BR><HR><A NAME="1160"></A><H4>1160.
  
Definitions of template members and the current instantiation
</H4><B>Section: </B>14.6.2.1&#160; [temp.dep.type]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>GB
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-03<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#GB43">N3092 comment
  GB&#160;43<BR></A>

<P>The current rules for determining whether a name refers to the current
instantiation, given in 14.6.2.1 [temp.dep.type] paragraph 1, do not
cover the case when a <I>template-id</I> matching a primary template or
partial specialization appears in the definition of a member of the
template.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change 14.6.2.1 [temp.dep.type] paragraph 1 as follows:</P>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">In the definition of a class template, a nested class
of a class template, a member of a class template, or a
member of a nested class of a class template, a</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">A</SPAN> name refers to the
<I>current instantiation</I> if it is

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">in the definition of a class template, a
nested class of a class template, a member of a class
template, or a member of a nested class of a class
template,</SPAN> the injected-class-name (9 [class]) of the class template or nested class,</P></LI>

<LI><P>in the definition of a primary class template <SPAN style="font-weight:bold;background-color:#A0FFA0">or
a member of a primary class template</SPAN>, the name of the
class template followed by the template argument list of the
primary template (as described below) enclosed in
<TT>&lt;&gt;</TT>,</P></LI>

<LI><P>in the definition of a nested class of a class
template, the name of the nested class referenced as a
member of the current instantiation, or</P></LI>

<LI><P>in the definition of a partial specialization <SPAN style="font-weight:bold;background-color:#A0FFA0">or
a member of a partial specialization</SPAN>, the name of the
class template followed by the template argument list of the
partial specialization enclosed in <TT>&lt;&gt;</TT>. If the
<I>n</I>th template parameter is a parameter pack, the
<I>n</I>th template argument is a pack expansion
(14.5.3 [temp.variadic]) whose pattern is the name of
the parameter pack.</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1047"></A><H4>1047.
  
When is <TT>typeid</TT> value-dependent?
</H4><B>Section: </B>14.6.2.3&#160; [temp.dep.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>2010-03-08<BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<P>The Standard should, but does not currently, say that <TT>typeid</TT>
is value-dependent if its expression or type is type-dependent.</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<P>Change 14.6.2.3 [temp.dep.constexpr] paragraph 2 as follows:</P>

<BLOCKQUOTE>

<P>...Expressions of the following form are value-dependent if the
<I>unary-expression</I> or <I>expression</I> is type-dependent or the
<I>type-id</I> is dependent:</P>

<UL><TT>sizeof</TT> <I>unary-expression</I><BR>

<TT>sizeof (</TT> <I>type-id</I> <TT>)</TT><BR>

<SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>typeid (</TT> <I>expression</I> <TT>)</TT></SPAN><BR>

<SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>typeid (</TT> <I>type-id</I> <TT>)</TT></SPAN><BR>

<TT>alignof (</TT> <I>type-id</I> <TT>)</TT><BR>

<TT>noexcept (</TT> <I>expression</I> <TT>)</TT></UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1074"></A><H4>1074.
  
Value-dependent <I>noexcept-expression</I>s
</H4><B>Section: </B>14.6.2.3&#160; [temp.dep.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-06-04<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>It is not clear why a <I>noexcept-expression</I> is value-dependent
if its operand is value-dependent.  It would seem that the value of the
expression depends only on the type of the operand, not its value.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Delete &#8220;<TT>noexcept(</TT> <I>expression</I> <TT>)</TT>&#8221;
from the list in 14.6.2.3 [temp.dep.constexpr] paragraph 3.</P>

<BR><BR><HR><A NAME="1088"></A><H4>1088.
  
Dependent non-type template arguments
</H4><B>Section: </B>14.6.2.3&#160; [temp.dep.constexpr]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-06-28<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>Given</P>

<PRE>
    template &lt;const char *N&gt; struct A { static const char *p; };
    template &lt;class T&gt;
       struct B { static const char c[1]; typedef A&lt;B&lt;T&gt;::c&gt; C; };
    template &lt;class T&gt;
       struct D { static const char c[1]; typedef A&lt;c&gt; C; };
</PRE>

<P>14.6.2.4 [temp.dep.temp] says that <TT>B&lt;T&gt;::c</TT> is
dependent because it is used as a non-integral non-type template
argument and it is a <I>qualified-id</I> with a
<I>nested-name-specifier</I> that names a dependent type.</P>

<P>There doesn't seem to be anything to say that <TT>c</TT> in the
definition of <TT>D&lt;T&gt;::C</TT> is dependent, which suggests that
<TT>D&lt;T&gt;::C</TT> is the same type for all <TT>T</TT>, which is
clearly false.</P>

<P>Instead of this special rule in 14.6.2.4 [temp.dep.temp],
14.6.2.3 [temp.dep.constexpr] should say that the address of a member
of a dependent type is value-dependent, regardless of whether the
address is written with a <I>qualified-id</I>.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<OL><LI><P>Add a new paragraph at the end of
14.6.2.3 [temp.dep.constexpr]:</P></LI>

<BLOCKQUOTE>

<SPAN style="font-weight:bold;background-color:#A0FFA0">An <I>id-expression</I> is value-dependent if it names a member
of an unknown specialization.</SPAN>

</BLOCKQUOTE>

<LI><P>Change 14.6.2.4 [temp.dep.temp] paragraphs 2-3 as follows:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">An integral</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">A</SPAN> non-type
<I>template-argument</I> is dependent if <SPAN style="font-weight:bold;background-color:#A0FFA0">its type is dependent
or</SPAN> the constant expression it specifies is value-dependent.</P>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">A non-integral</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Furthermore, a</SPAN> non-type
<I>template-argument</I> is dependent if <SPAN style="text-decoration:line-through;background-color:#FFA0A0">its type is dependent or it
has either of the following forms</SPAN></P>

<UL><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>qualified-id</I></SPAN></UL>
<UL><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>&amp;</TT> <I>qualified-id</I></SPAN></UL>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">and contains a <I>nested-name-specifier</I> which specifies a
<I>class-name</I> that names a dependent type</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">the
corresponding non-type <I>template-parameter</I> is of reference or
pointer type and the <I>template-argument</I> designates or points to
a member of the current instantiation or a member of a dependent
type</SPAN>.</P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="993"></A><H4>993.
  
Freedom to perform instantiation at the end of the translation unit
</H4><B>Section: </B>14.6.4.1&#160; [temp.point]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>6 March, 2009<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

<P>The intent is that it is a permissible implementation technique to
do template instantiation at the end of a translation unit rather than
at an actual point of instantiation.  This idea is not reflected in the
current rules, however.</P>

<P><B>Proposed resolution (January, 2011):</B></P>

<P>Change 14.6.4.1 [temp.point] paragraph 7 as follows:</P>

<BLOCKQUOTE>

A specialization for a function template, a member function template,
or of a member function or static data member of a class template may
have multiple points of instantiations within a translation unit<SPAN style="font-weight:bold;background-color:#A0FFA0">,
and in addition to the points of instantiation described above, for
any such specialization that has a point of instantiation within the
translation unit, the end of the translation unit is also considered a
point of instantiation</SPAN>.  A specialization for a class
template...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="546"></A><H4>546.
  
Explicit instantiation of class template members
</H4><B>Section: </B>14.7.2&#160; [temp.explicit]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Martin Sebor
 &#160;&#160;&#160;

 <B>Date: </B>29 October 2005<BR>


<P>[Voted into WP at August, 2010 meeting.]</P>

<P><A HREF="
     cwg_defects.html#470">Issue 470</A> specified the explicit
instantiation of members of explicitly-instantiated class templates.
In restricting the affected members to those &#8220;whose definition
is visible at the point of instantiation,&#8221; however, this
resolution introduced an incompatibility between explicitly
instantiating a member function or static data member and explicitly
instantiating the class template of which it is a member (14.7.2 [temp.explicit] paragraph 3 requires only that the class template
definition, not that of the member function or static data member, be
visible at the point of the explicit instantiation).  It would be
better to treat the member instantiations the same, regardless of
whether they are directly or indirectly explicitly instantiated.</P>

<P><B>Notes from the April, 2006 meeting:</B></P>

<P>In forwarding document J16/06-0057 = WG21 N1987 to be approved by
the full Committee, the CWG reaffirmed its position that explicitly
instantiating a class template only explicitly instantiates those of
its members that have been defined before the point of the explicit
instantiation.  The effect of the position advocated above would be to
require all non-exported member functions to be defined in the
translation unit in which the class template is explicitly
instantiated (cf paragraph 4), and we did not want to require that.
We did agree that the &#8220;visible&#8221; terminology should be
replaced by wording along the lines of &#8220;has been
defined.&#8221;</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 14.7.2 [temp.explicit] paragraph 8 as follows:</P>

<BLOCKQUOTE>

An explicit instantiation definition that names a class template
specialization explicitly instantiates the class template
specialization and is only an explicit instantiation definition
of members <SPAN style="text-decoration:line-through;background-color:#FFA0A0">whose definition is visible</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">that have
been defined</SPAN> at the point of instantiation.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1196"></A><H4>1196.
  
Definition required for explicit instantiation after explicit specialization?
</H4><B>Section: </B>14.7.2&#160; [temp.explicit]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>2010-09-08<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>According to 14.7.2 [temp.explicit] paragraph 4,</P>

<BLOCKQUOTE>

For a given set of template parameters, if an explicit instantiation
of a template appears after a declaration of an explicit
specialization for that template, the explicit instantiation has no
effect.

</BLOCKQUOTE>

<P>However, that does not appear to negate the requirements of paragraph
3 that a definition of the entity being instantiated must be in scope.
Consequently, the following would appear to be ill-formed, even though
there is no real need for the definition of <TT>C</TT>:</P>

<PRE>
    template&lt;typename T&gt; class C;
    template&lt;&gt; class C&lt;int&gt; { };
    template class C&lt;int&gt;;
</PRE>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change 14.7.2 [temp.explicit] paragraphs 3-4 as follows:</P>

<BLOCKQUOTE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">A declaration of a function template shall be in scope at the
point of the explicit instantiation of the function template. A
definition of the class or class template containing a member function
template shall be in scope at the point of the explicit instantiation
of the member function template. A definition of a class template or
class member template shall be in scope at the point of the explicit
instantiation of the class template or class member template.  A
definition of a class template shall be in scope at the point of an
explicit instantiation of a member function or a static data member of
the class template. A definition of a member class of a class template
shall be in scope at the point of an explicit instantiation of the
member class.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">A declaration of a function template, a
member function or static data member of a class template, or a member
function template of a class or class template shall precede an
explicit instantiation of that entity. A definition of a class
template, a member class of a class template, or a member class
template of a class or class template shall precede an explicit
instantiation of that entity, unless the explicit instantiation is
preceded by an explicit specialization of the entity with the same
template arguments.</SPAN> If the declaration of the explicit
instantiation names an implicitly-declared special member function
(Clause 12 [special]), the program is ill-formed.</P>

<P>For a given set of template <SPAN style="text-decoration:line-through;background-color:#FFA0A0">parameters</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">arguments</SPAN>, if an explicit instantiation of a template
appears after a declaration of an explicit specialization for that
template, the explicit instantiation has no effect.  Otherwise...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="531"></A><H4>531.
  
Defining members of explicit specializations
</H4><B>Section: </B>14.7.3&#160; [temp.expl.spec]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>1 October 2005<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>The Standard does not fully describe the syntax to be used when a
member of an explicitly-specialized member class or member class
template is defined in namespace scope.  14.7.3 [temp.expl.spec]
paragraph 4 says that the &#8220;explicit specialization syntax&#8221;
(presumably referring to &#8220;<TT>template&lt;&gt;</TT>&#8221;) is
not used in defining a member of an explicit specialization when a
class template is explicitly specialized as a class.  However, nothing
is said anywhere about how to define a member of a specialization
when:</P>

<OL><LI><P>the entity being specialized is a class (member of a
template class) rather than a class template.</P></LI>

<LI><P>the result of the specialization is a class template rather
than a class (cf 14.7.3 [temp.expl.spec] paragraph 18, which
describes this case as a &#8220;member template that...
remain[s] unspecialized&#8221;).</P></LI>
</OL>

<P>(See paper J16/05-0148 = WG21 N1888 for further details, including
a survey of existing implementation practice.)</P>

<P><B>Notes from the October, 2005 meeting:</B></P>

<P>The CWG felt that the best approach, balancing consistency with
implementation issues and existing practice, would be to require that
<TT>template&lt;&gt;</TT> be used when defining members of all
explicit specializations, including those currently covered by
14.7.3 [temp.expl.spec] paragraph 4.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 14.7.3 [temp.expl.spec] paragraph 5 as follows:</P>

<BLOCKQUOTE>

<P>...The definition of an explicitly specialized class is
unrelated to the definition of a generated specialization. That
is, its members need not have the same names, types, etc. as the
members of a generated specialization. Definitions of members of
an explicitly specialized class are defined <SPAN style="text-decoration:line-through;background-color:#FFA0A0">in the same
manner as members of normal classes, and not using the syntax for
explicit specialization</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">using the same
<TT>template&lt;&gt;</TT> prefix(es) as the explicitly
specialized class</SPAN>. [<I>Example:</I></P>

<PRE>
    template&lt;class T&gt; struct A {
      void f(T) { /* ... */ }
<SPAN style="font-weight:bold;background-color:#A0FFA0">      struct B { /* ... */ };
      template&lt;class U&gt; struct C { /* ... */ };</SPAN>
    };
    template&lt;&gt; struct A&lt;int&gt; {
      void f(int);
<SPAN style="font-weight:bold;background-color:#A0FFA0">      struct B;
      template&lt;class U&gt; struct C;</SPAN>
    };
    void h() {
      A&lt;int&gt; a;
      a.f(16); // A&lt;int&gt;::f <SPAN style="font-family:Times;font-style:italic">must be defined somewhere</SPAN>
    }
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">    //<SPAN style="font-family:Times;font-style:italic"> explicit specialization syntax not used for a member of</SPAN>
    //<SPAN style="font-family:Times;font-style:italic"> explicitly specialized class template specialization</SPAN></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">    //<SPAN style="font-family:Times;font-style:italic"> members of explicitly specialized classes are defined using</SPAN>
    //<SPAN style="font-family:Times;font-style:italic">the same syntax as the explicitly specialized class:</SPAN></SPAN>
    <SPAN style="font-weight:bold;background-color:#A0FFA0">template&lt;&gt; </SPAN>void A&lt;int&gt;::f(int) { /* ... */ }
<SPAN style="font-weight:bold;background-color:#A0FFA0">    template&lt;&gt; struct A&lt;int&gt;::B { /* ... */ };
    template&lt;&gt; template&lt;class T&gt; struct A&lt;int&gt;::C { /* ... */ };</SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<P><B>Note (June, 2010):</B></P>

<P>Because the survey of implementations on which the CWG relied in
reaching this resolution is quite old, a new survey of current
practice is needed.</P>

<BR><BR><HR><A NAME="605"></A><H4>605.
  
Linkage of explicit specializations
</H4><B>Section: </B>14.7.3&#160; [temp.expl.spec]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Steve Clamage
 &#160;&#160;&#160;

 <B>Date: </B>30 November 2006<BR>


<P>[Voted into WP at August, 2010 meeting.]</P>



<P>Given</P>

<PRE>
    template &lt;class T&gt; static T f(T   t) { ... }
    template &lt;&gt;             int f(int t) { ... }
</PRE>

<P>what is the linkage of <TT>f(int)</TT>?</P>

<P>Section 14 [temp] paragraph 4 says,</P>

<BLOCKQUOTE>

Entities generated from a template with internal linkage are
distinct from all entities generated in other translation units.

</BLOCKQUOTE>

<P>But is the explicit specialization &#8220;generated
from&#8221; the primary template?  Does it inherit the local
linkage?  If so, where do I find a reference saying so
explicitly?</P>

<P><U>James Widman</U>: Data points: EDG 3.8 inherits, GCC 4.0
does not.</P>

<P><U>Mike Miller</U>: There's a pretty strong presumption that
the linkage of an explicit specialization cannot be different
from that of its primary template, given that storage class
specifiers cannot appear in an explicit specialization
(7.1.1 [dcl.stc] paragraph 1).</P>

<P><B>Notes from the April, 2007 meeting:</B></P>

<P>The CWG agreed that the linkage of an explicit specialization
must be that of the template.  Gabriel dos Reis will investigate
the reason for the different behavior of g++.</P>

<P><B>Proposed resolution (March, 2010):</B></P>

<P>Change 14 [temp] paragraph 4 as follows:</P>

<BLOCKQUOTE>

...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Entities generated from</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Specializations
(explicit or implicit) of</SPAN> a template <SPAN style="text-decoration:line-through;background-color:#FFA0A0">with</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">that has</SPAN> internal linkage are distinct from all
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">entities generated</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">specializations</SPAN> in other
translation units...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="621"></A><H4>621.
  
Template argument deduction from function return types
</H4><B>Section: </B>14.7.3&#160; [temp.expl.spec]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Corden
 &#160;&#160;&#160;

 <B>Date: </B>16 February 2007<BR>


<P>[Voted into WP at August, 21010 meeting.]</P>



<P>It does not appear that the following example is well-formed,
although most compilers accept it:</P>

<PRE>
    template &lt;typename T&gt; T foo();
    template &lt;&gt; int foo();
</PRE>

<P>The reason is that 14.7.3 [temp.expl.spec] paragraph 11 only
allows trailing <I>template-argument</I>s to be omitted if they
&#8220;can be deduced from the function argument type,&#8221; and
there are no function arguments in this example.</P>

<P>14.7.3 [temp.expl.spec] should probably say &#8220;function
type&#8221; instead of &#8220;function argument type.&#8221;  Also,
a subsection should probably be added to 14.8.2 [temp.deduct]
to cover &#8220;Deducing template arguments from declarative
contexts&#8221; or some such.  It would be essentially the same as
14.8.2.2 [temp.deduct.funcaddr] except that the function type from
the declaration would be used as the type of <TT>P</TT>.</P>

<P><B>Proposed resolution (March, 2008):</B></P>

<OL>
<LI><P>Insert the following as a new subsection after
14.8.2.5 [temp.deduct.type]:</P></LI>

<BLOCKQUOTE>

<P><TABLE><TR>
<TD><SPAN style="font-weight:bold;background-color:#A0FFA0">14.9.2.6 Deducing template arguments in a declaration
that names a specialization of a function template</SPAN></TD>
<TD ALIGN="right"><SPAN style="font-weight:bold;background-color:#A0FFA0">[temp.deduct.funcdecl]</SPAN></TD>
</TR></TABLE></P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">Template arguments can be deduced from the function type
specified when declaring a specialization of a function
template. [<I>Note:</I> this can occur in the context of an
explicit specialization, an explicit instantiation, or a
friend declaration. &#8212;<I>end note</I>] The function
template's function type and the declared type are used as
the types of <TT>P</TT> and <TT>A</TT>, and the deduction is
done as described in 14.8.2.5 [temp.deduct.type].</SPAN></P>

</BLOCKQUOTE>

<LI><P>Change 14.7.3 [temp.expl.spec] paragraph 11 as
follows:</P></LI>

<BLOCKQUOTE>

A trailing <I>template-argument</I> can be left unspecified in the
<I>template-id</I> naming an explicit function template specialization
provided it can be deduced from the function <SPAN style="text-decoration:line-through;background-color:#FFA0A0">argument</SPAN> type
<SPAN style="font-weight:bold;background-color:#A0FFA0">(14.9.2.6 [temp.deduct.funcdecl])</SPAN>...

</BLOCKQUOTE>

</OL>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>The proposed resolution is probably more than is needed.
Instead of a complete new section, the material could become a
paragraph in 14.5.6 [temp.fct].</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Add the following paragraph at the end of 14.5.6 [temp.fct]:</P>

<BLOCKQUOTE>

<SPAN style="font-weight:bold;background-color:#A0FFA0">In a declaration that names a specialization of a function
template, template arguments can be deduced from the function
type.  [<I>Note:</I> this can occur in the context of an explicit
specialization, an explicit instantiation, or a friend
declaration. &#8212;<I>end note</I>] The function template's
function type and the declared type are used as the types of
<TT>P</TT> and <TT>A</TT> and the deduction is done as described
in 14.8.2.5 [temp.deduct.type].</SPAN>

</BLOCKQUOTE>

<P><B>Proposed resolution (March, 2010):</B></P>

<P>This issue is resolved by the resolution of <A HREF="
     cwg_defects.html#873">issue 873</A>.</P>

<BR><BR><HR><A NAME="941"></A><H4>941.
  
Explicit specialization of deleted function template
</H4><B>Section: </B>14.7.3&#160; [temp.expl.spec]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Spicer
 &#160;&#160;&#160;

 <B>Date: </B>14 July, 2009<BR>


<P>[Voted into WP at August, 21010 meeting.]</P>

<P>According to 14.7.3 [temp.expl.spec] paragraph 1, only non-deleted
function templates may be explicitly specialized.  There doesn't appear to
be a compelling need for this restriction, however, and it could be useful
to forbid use of implicitly-instantiated specializations while still
allowing use of explicitly-specialized versions.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change 14.7.3 [temp.expl.spec] paragraph 1 as follows:</P>

<BLOCKQUOTE>

<P>An explicit specialization of any of the following:</P>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-deleted</SPAN> function template</P></LI>

<LI><P>class template</P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-deleted</SPAN> member function of a class template</P></LI>

<LI><P>static data member of a class template</P></LI>

<LI><P>member class of a class template</P></LI>

<LI><P>member class template of a class or class template</P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-deleted</SPAN> member function template of a class or
class template</P></LI>

</UL>

<P>can be declared...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="575"></A><H4>575.
  
Criteria for deduction failure
</H4><B>Section: </B>14.8.2&#160; [temp.deduct]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>James Widman
 &#160;&#160;&#160;

 <B>Date: </B>19 April 2006<BR>


<P>[Voted into WP at August, 2010 meeting.]</P>



<P>The last two sentences of 14.8.2 [temp.deduct] paragraph 5
read:</P>

<BLOCKQUOTE>

When all template arguments have been deduced or obtained from default
template arguments, all uses of template parameters in non-deduced
contexts are replaced with the corresponding deduced or default
argument values. If the substitution results in an invalid type, as
described above, type deduction fails.

</BLOCKQUOTE>

<P>Shouldn't the substitution occur for all uses of the parameters, so
that any of them could result in deduction failure?</P>

<P><B>Proposed resolution (October, 2006):</B></P>

<P>Change 14.8.2 [temp.deduct] paragraph 5 as follows:</P>

<BLOCKQUOTE>

...When all template arguments have been deduced or obtained from
default template arguments, all uses of template parameters in
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-deduced contexts</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">the function type</SPAN> are replaced with
the corresponding deduced or default argument values. If the
substitution results in an invalid type, as described above, type
deduction fails.

</BLOCKQUOTE>

<P><B>Notes from the September, 2008 meeting:</B></P>

<P>This issue was returned to "drafting" status in order to
coordinate the wording with the concepts proposal.</P>

<P><B>Proposed resolution (March, 2010):</B></P>

<P>Change 14.8.2 [temp.deduct] paragraph 5 as follows:</P>

<BLOCKQUOTE>

When all template arguments have been deduced or obtained from
default template arguments, all uses of template parameters in
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-deduced contexts</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">the template parameter list
of the template and the function type</SPAN> are replaced with the
corresponding deduced or default argument values. If the
substitution results in an invalid type, as described above, type
deduction fails.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="709"></A><H4>709.
  
Enumeration names as <I>nested-name-specifier</I>s in deduction failure
</H4><B>Section: </B>14.8.2&#160; [temp.deduct]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Doug Gregor
 &#160;&#160;&#160;

 <B>Date: </B>23 Aug, 2008<BR>


<P>[Voted into WP at August, 21010 meeting.]</P>



<P>The current rules in 14.8.2 [temp.deduct] say that type
deduction fails as a result of attempting to use a type that is
not a class type in a qualified name.  However, it is now possible
to use enumeration names as <I>nested-name-specifier</I>s, so this
rule needs to be updated accordingly.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<P>Change the third bullet of the note in 14.8.2 [temp.deduct]
paragraph 8 as follows:</P>

<BLOCKQUOTE>

<P>[<I>Note:</I> Type deduction may fail for the following reasons:</P>

<UL><LI><P>...</P></LI>

<LI><P>Attempting to use a type that is not a class <SPAN style="font-weight:bold;background-color:#A0FFA0">or
enumeration</SPAN> type in a qualified
name. [<I>Example:</I>...</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1170"></A><H4>1170.
  
Access checking during template argument deduction
</H4><B>Section: </B>14.8.2&#160; [temp.deduct]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Adamczyk
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-03<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

<P>According to 14.8.2 [temp.deduct] paragraph 8,</P>

<BLOCKQUOTE>

Access checking is not done as part of the substitution
process.  Consequently, when deduction succeeds, an access
error could still result when the function is instantiated.

</BLOCKQUOTE>

<P>This mimics the way access checking is done in overload
resolution.  However, experience has shown that this exemption
of access errors from deduction failure significantly complicates
the Standard library, so this rule should be changed.</P>

<P><B>Proposed resolution (January, 2011):</B></P>

<P>Change 14.8.2 [temp.deduct] paragraph 8 as follows:</P>

<BLOCKQUOTE>

If a substitution results in an invalid type or expression, type
deduction fails. An invalid type or expression is one that would be
ill-formed if written using the substituted arguments.
<SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I></SPAN> Access checking is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">not</SPAN> done as
part of the substitution process.  <SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end note</I>]</SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">Consequently, when deduction succeeds, an access error could still
result when the function is instantiated.</SPAN>  Only invalid types...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1164"></A><H4>1164.
  
Partial ordering of <TT>f(T&amp;)</TT> and <TT>f(T&amp;&amp;)</TT>
</H4><B>Section: </B>14.8.2.1&#160; [temp.deduct.call]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-03<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US77">N3092 comment
  US&#160;77<BR></A>

<P>The following example is ambiguous:</P>

<PRE>
    template&lt;typename T&gt; int f(T&amp;);
    template&lt;typename T&gt; int f(T&amp;&amp;);
    int i;
    int j = f(i);
</PRE>

<P>Because of the special deduction rule for lvalues passed to
rvalue-reference parameters, deduction produces <TT>f(int&amp;)</TT>
for both templates, and they are indistinguishable.</P>

<P>Because <TT>f(T&amp;)</TT> accepts a strict subset of the things
that <TT>f(T&amp;&amp;)</TT> does, it should be considered more
specialized by the partial ordering rules.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change 14.8.2.4 [temp.deduct.partial] paragraph 9 as follows:</P>

<BLOCKQUOTE>

If, for a given type, deduction succeeds in both directions
(i.e., the types are identical after the transformations
above) <SPAN style="font-weight:bold;background-color:#A0FFA0">and both <TT>P</TT> and <TT>A</TT> were
reference types (before being replaced with the type
referred to above):</SPAN>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">If the type from the argument template was
an lvalue reference and the type from the parameter template
was not, the argument type is considered to be more
specialized than the other; otherwise,</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">and</SPAN> if the type from the argument template
is more cv-qualified than the type from the parameter
template (as described above)<SPAN style="font-weight:bold;background-color:#A0FFA0">, the argument</SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">that</SPAN> type is considered to be more specialized
than the other<SPAN style="text-decoration:line-through;background-color:#FFA0A0">.</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">; otherwise</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">If neither type is more cv-qualified than the
other then</SPAN> neither type is more specialized than the
other.</P></LI>

</UL>

</BLOCKQUOTE>

<P><I>[Editing note: this change transforms the running text at
the end of the paragraph into a bulleted list.]</I></P>

<BR><BR><HR><A NAME="1184"></A><H4>1184.
  
Argument conversions to nondeduced parameter types
</H4><B>Section: </B>14.8.2.1&#160; [temp.deduct.call]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Daniel Kr&#252;gler
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-29<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>It is not clear whether the following example is well-formed or not:</P>

<PRE>
    template&lt;class T&gt; struct identity { typedef T type; };

    template&lt;class T, class C&gt;
    void f(T C::*, typename identity&lt;T&gt;::type*){}

    struct X { void f() {}; };

    int main() { f(&amp;X::f, 0); }
</PRE>

<P>The null pointer conversion required for the second parameter of
<TT>f</TT> is not one of the ones permitted by
14.8.2.1 [temp.deduct.call] paragraph 4, but it's unclear whether
that list should apply to parameters with nondeduced types or not.
14.8.1 [temp.arg.explicit] paragraph 6 is explicit that</P>

<BLOCKQUOTE>

Implicit conversions (Clause 4 [conv]) will be performed
on a function argument to convert it to the type of the corresponding
function parameter if the parameter type contains no
<I>template-parameter</I>s that participate in template argument
deduction.

</BLOCKQUOTE>

<P>However, this statement appears in a section dealing with
explicitly-specified template arguments, so its applicability to
nondeduced contexts in general is not clear.</P>

<P>Implementations disagree on the handling of this example.</P>

<BR><BR><HR><A NAME="692"></A><H4>692.
  
Partial ordering of variadic class template partial specializations
</H4><B>Section: </B>14.8.2.5&#160; [temp.deduct.type]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Doug Gregor
 &#160;&#160;&#160;

 <B>Date: </B>16 April, 2008<BR>


<P>[Voted into the WP at the March, 2011 meeting as paper N3281.]</P>



<P>14.8.2.5 [temp.deduct.type] paragraph 22 describes how we
cope with partial ordering between two function templates that
differ because one has a function parameter pack while the other
has a normal function parameter.  However, this paragraph was
meant to apply to template parameter packs as well, e.g., to help
with partial ordering of class template partial specializations:</P>

<PRE>
   template &lt;class T1, class ...Z&gt; class S; // #1
   template &lt;class T1, class ...Z&gt; class S&lt;T1, const Z&amp;...&gt; {}; // #2
   template &lt;class T1, class T2&gt; class S&lt;T1, const T2&amp;&gt; {};; // #3
   S&lt;int, const int&amp;&gt; s; // both #2 and #3 match; #3 is more specialized
</PRE>

<P>(See also <A HREF="
     cwg_defects.html#818">issue 818</A>.)</P>

<P><B>Proposed resolution (March, 2009):</B></P>

<P>Change 14.8.2.5 [temp.deduct.type] paragraphs 9-10 as follows
(and add the example above to paragraph 9):</P>

<BLOCKQUOTE>

<P>If <TT>P</TT> has a form that contains &lt;<TT>T</TT>&gt; or
&lt;<TT>i</TT>&gt;, then each argument
<TT>P</TT><SUB><I>i</I></SUB> of the respective template argument
list of <TT>P</TT> is compared with the corresponding argument
<TT>A</TT><SUB><I>i</I></SUB> of the corresponding template
argument list of <TT>A</TT>. If the template argument list of
<TT>P</TT> contains a pack expansion that is not the last
template argument, the entire template argument list is a
non-deduced context. If <TT>P</TT><SUB><I>i</I></SUB> is a pack
expansion, then the pattern of <TT>P</TT><SUB><I>i</I></SUB> is
compared with each remaining argument in the template argument
list of <TT>A</TT>. Each comparison deduces template arguments
for subsequent positions in the template parameter packs expanded
by <TT>P</TT><SUB><I>i</I></SUB>. <SPAN style="font-weight:bold;background-color:#A0FFA0">During partial ordering
(14.8.2.4 [temp.deduct.partial]), if <TT>A</TT><SUB><I>i</I></SUB>
was originally a pack expansion and <TT>P</TT><SUB><I>i</I></SUB>
is not a pack expansion, or if <TT>P</TT> does not contain a
template argument corresponding to <TT>A</TT><SUB><I>i</I></SUB>,
argument deduction fails.</SPAN></P>

<P>Similarly, if <TT>P</TT> has a form that contains
<TT>(T)</TT>, then each parameter type
<TT>P</TT><SUB><I>i</I></SUB> of the respective
<I>parameter-type-list</I> of <TT>P</TT> is compared with the
corresponding parameter type <TT>A</TT><SUB><I>i</I></SUB> of the
corresponding <I>parameter-type-list</I> of <TT>A</TT>. If the
<I>parameter-declaration</I> corresponding to
<TT>P</TT><SUB><I>i</I></SUB> is a function parameter pack, then
the type of its <I>declarator-id</I> is compared with each
remaining parameter type in the <I>parameter-type-list</I> of
<TT>A</TT>. Each comparison deduces template arguments for
subsequent positions in the template parameter packs expanded by
the function parameter pack. <SPAN style="font-weight:bold;background-color:#A0FFA0">During partial ordering
(14.8.2.4 [temp.deduct.partial]), if <TT>A</TT><SUB><I>i</I></SUB>
was originally a function parameter pack and
<TT>P</TT><SUB><I>i</I></SUB> is not a function parameter
pack, or if <TT>P</TT> does not contain a function parameter type
corresponding to <TT>A</TT><SUB><I>i</I></SUB>, argument deduction
fails.</SPAN> [<I>Note:</I> A function parameter pack
can only occur at the end of a <I>parameter-declaration-list</I>
(8.3.5 [dcl.fct]). &#8212;<I>end note</I>]</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="873"></A><H4>873.
  
Deducing rvalue references in declarative contexts
</H4><B>Section: </B>14.8.2.5&#160; [temp.deduct.type]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>16 April, 2009<BR>


<P>[Voted into WP at August, 21010 meeting.]</P>

<P>14.8.2.1 [temp.deduct.call] paragraph 3 gives the deduction of
rvalue references special treatment in the context of a function call:</P>

<BLOCKQUOTE>

If <TT>P</TT> is of the form <TT>T&amp;&amp;</TT>, where <TT>T</TT> is
a template parameter, and the argument is an lvalue, the type
<TT>A&amp;</TT> is used in place of <TT>A</TT> for type deduction.

</BLOCKQUOTE>

<P>A similar provision is needed, but is not present, in declarative
contexts.  For example:</P>

<PRE>
    template&lt;typename T&gt; void f(T&amp;&amp;);
    template&lt;&gt; void f(int&amp;) { }    // #1
    template&lt;&gt; void f(int&amp;&amp;) { }   // #2
    void g(int i) {
        f(i);    // calls f&lt;int&amp;&gt;(int&amp;), i.e., #1
        f(0);    // calls f&lt;int&gt;(int&amp;&amp;), i.e., #2
    }
</PRE>

<P>There need to be rules that deduce the template arguments for the
specializations in the same way that the arguments are deduced in the
calls.</P>

<P><B>Proposed resolution (February, 2010):</B></P>

<OL><LI><P>Change 14.8.2.5 [temp.deduct.type] paragraph 10 as
follows:</P></LI>

<BLOCKQUOTE>

<P>Similarly, if <TT>P</TT> has a form that contains
<TT>(T)</TT>, then each parameter type
<TT>P</TT><SUB><I>i</I></SUB> of the respective
<I>parameter-type-list</I> of <TT>P</TT> is compared with the
corresponding parameter type <TT>A</TT><SUB><I>i</I></SUB> of the
corresponding <I>parameter-type-list</I> of <TT>A</TT>.  <SPAN style="font-weight:bold;background-color:#A0FFA0">If
<TT>P</TT> and <TT>A</TT> are function types that originated from
deduction when taking the address of a function template
(14.8.2.2 [temp.deduct.funcaddr]) or when deducing template
arguments from a function declaration ([temp.deduct.decl]) and
<TT>P</TT><SUB><I>i</I></SUB> and <TT>A</TT><SUB><I>i</I></SUB>
are parameters of the top-level <I>parameter-type-list</I> of
<TT>P</TT> and <TT>A</TT>, respectively, <TT>P</TT><SUB><I>i</I></SUB> 
is adjusted if it is an rvalue reference to
a cv-unqualified template parameter and
<TT>A</TT><SUB><I>i</I></SUB> is an lvalue reference, in which case
the type of <TT>P</TT><SUB><I>i</I></SUB> is
changed to be the template parameter type (i.e.,
<TT>T&amp;&amp;</TT> is changed to simply
<TT>T</TT>). [<I>Note:</I> As a result, when
<TT>P</TT><SUB><I>i</I></SUB> is <TT>T&amp;&amp;</TT> and
<TT>A</TT><SUB><I>i</I></SUB> is <TT>X&amp;</TT>, the adjusted
<TT>P</TT><SUB><I>i</I></SUB> will be <TT>T</TT>, causing
<TT>T</TT> to be deduced as <TT>X&amp;</TT>. &#8212;<I>end
note</I>] [<I>Example:</I></SPAN>
</P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  template&lt;typename T&gt; void f(T&amp;&amp;);
  template&lt;&gt; void f(int&amp;) { }      //<SPAN style="font-family:Times;font-style:italic"> #1</SPAN>
  template&lt;&gt; void f(int&amp;&amp;) { }     //<SPAN style="font-family:Times;font-style:italic"> #2</SPAN>
  void g(int i) {
    f(i);   //<SPAN style="font-family:Times;font-style:italic"> calls </SPAN>f&lt;int&amp;&gt;(int&amp;)<SPAN style="font-family:Times;font-style:italic">, i.e., #1</SPAN>
    f(0);   //<SPAN style="font-family:Times;font-style:italic"> calls </SPAN>f&lt;int&gt;(int&amp;&amp;)<SPAN style="font-family:Times;font-style:italic">, i.e., #2</SPAN>
  }</SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

<P>If the <I>parameter-declaration</I> corresponding to
<TT>P</TT><SUB><I>i</I></SUB> is a function parameter pack...</P>

</BLOCKQUOTE>

<LI><P>Add a new section under 14.8.2 [temp.deduct], either before
or after 14.8.2.5 [temp.deduct.type], as follows:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0"><B>14.8.2.x Deducing template arguments from a function declaration [temp.deduct.decl]</B></SPAN></P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">In a declaration whose <I>declarator-id</I> refers to a
specialization of a function template, template argument
deduction is performed to identify the specialization to which
the declaration refers. Specifically, this is done for explicit
instantiations (14.7.2 [temp.explicit]), explicit
specializations (14.7.3 [temp.expl.spec]), and certain friend
declarations (14.5.4 [temp.friend]). This is also done to
determine whether a function template specialization matches a
placement <TT>operator new</TT> (3.7.4.2 [basic.stc.dynamic.deallocation],
5.3.4 [expr.new]). In all these cases, <TT>P</TT> is the
type of the function template being considered as a potential
match and <TT>A</TT> is the function type from the
declaration. The deduction is done as described in 14.8.2.5 [temp.deduct.type].</SPAN></P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">If, for the set of function templates so considered, there is
either no match or more than one match after partial ordering has
been considered (14.5.6.2 [temp.func.order]), deduction fails
and the declaration is ill-formed.</SPAN></P>

</BLOCKQUOTE>

</OL>

<P>(Note that the resolution of <A HREF="
     cwg_defects.html#674">issue 674</A> depends on this resolution.)</P>

<BR><BR><HR><A NAME="1178"></A><H4>1178.
  
Deduction failure matching placement new
</H4><B>Section: </B>14.8.2.6&#160; [temp.deduct.decl]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-19<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<P>The new wording added by <A HREF="
     cwg_defects.html#873">issue 873</A> says,</P>

<BLOCKQUOTE>

...This is also done to determine whether a function template
specialization matches a placement <TT>operator new</TT> (3.7.4.2 [basic.stc.dynamic.deallocation], 5.3.4 [expr.new])... If, for the set of
function templates so considered, there is either no match or more
than one match after partial ordering has been considered
(14.5.6.2 [temp.func.order]), deduction fails and the declaration
is ill-formed.

</BLOCKQUOTE>

<P>The statement describing the consequence of deduction failure
(&#8220;the declaration is ill-formed&#8221;) does not apply to
the case when deduction is being performed for placement
<TT>operator delete</TT>, as there is no declaration involved.
It may not be necessary to describe what happens when deduction
fails in that case, but at least the wording should be tweaked to
limit the conclusion to declarative contexts.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change 14.8.2.6 [temp.deduct.decl] paragraphs 1-2 as follows:</P>

<BLOCKQUOTE>

<P>In a declaration whose <I>declarator-id</I> refers to a
specialization of a function template, template argument deduction is
performed to identify the specialization to which the declaration
refers. Specifically, this is done for explicit instantiations
(14.7.2 [temp.explicit]), explicit specializations (14.7.3 [temp.expl.spec]), and certain friend declarations (14.5.4 [temp.friend]).  This is also done to determine whether a
<SPAN style="font-weight:bold;background-color:#A0FFA0">deallocation</SPAN> function template specialization matches a
placement <TT>operator new</TT> (3.7.4.2 [basic.stc.dynamic.deallocation],
5.3.4 [expr.new]).  In all these cases, <TT>P</TT> is the
type of the function template being considered as a potential match
and <TT>A</TT> is <SPAN style="font-weight:bold;background-color:#A0FFA0">either</SPAN> the function type from the
declaration <SPAN style="font-weight:bold;background-color:#A0FFA0">or the type of the deallocation function that would
match the placement <TT>operator new</TT> as described in 5.3.4 [expr.new]</SPAN>. The deduction is done as described in
14.8.2.5 [temp.deduct.type].</P>

<P>If, for the set of function templates so considered, there is
either no match or more than one match after partial ordering has been
considered (14.5.6.2 [temp.func.order]), deduction fails and<SPAN style="font-weight:bold;background-color:#A0FFA0">,
in the declaration cases,</SPAN> the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">declaration</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">program</SPAN> is ill-formed.</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1165"></A><H4>1165.
  
Exceptions when destroying array elements
</H4><B>Section: </B>15.2&#160; [except.ctor]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-03<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US78">N3092 comment
  US&#160;78<BR></A>

<P>According to 15.2 [except.ctor] paragraph 2,</P>

<BLOCKQUOTE>

An object that is partially constructed or partially
destroyed will have destructors executed for all of its
fully constructed base classes and non-variant members, that
is, for subobjects for which the principal constructor
(12.6.2 [class.base.init]) has completed execution and
the destructor has not yet begun execution.

</BLOCKQUOTE>

<P>This wording leaves unclear whether the remaining
elements of an array will be destroyed if the destructor for
one of the elements exits via an exception: an array element
is a subobject (1.8 [intro.object] paragraph 2), but
it is not a base class or non-variant member.</P>

<P><B>Proposed resolution (September, 2010):</B></P>

<P>Change 15.2 [except.ctor] paragraph 2 as follows:</P>

<BLOCKQUOTE>

An object <SPAN style="text-decoration:line-through;background-color:#FFA0A0">that is partially constructed or partially
destroyed</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"> of any storage duration whose initialization or
destruction is terminated by an exception</SPAN> will have destructors
executed for all of its fully constructed <SPAN style="text-decoration:line-through;background-color:#FFA0A0">base classes and
non-variant members</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">subobjects (excluding the variant
members of a union-like class)</SPAN>, that is, for subobjects for
which the principal constructor (12.6.2 [class.base.init]) has
completed execution and the destructor has not yet begun execution.
Similarly, if the non-delegating constructor...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="971"></A><H4>971.
  
Incorrect treatment of <I>exception-declaration</I>s
</H4><B>Section: </B>15.3&#160; [except.handle]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>28 September, 2009<BR>


<P>The current wording of 15.3 [except.handle] paragraph 16 is:</P>

<BLOCKQUOTE>

The object declared in an <I>exception-declaration</I> or, if the
<I>exception-declaration</I> 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.

</BLOCKQUOTE>

<P>There are two problems with this.  First, it's not clear what it
means for the handler's &#8220;parameter&#8221; to be a temporary.
This possibility is briefly mentioned in 12.2 [class.temporary],
but the lifetime of such a temporary is not defined there; the
discussion of lifetime is restricted to those temporaries that arise
during the evaluation of an expression, and this is not such a case.</P>

<P>Second, this wording assumes that there will be an object to be
destroyed and thus ignores the possibility that the
<I>exception-declaration</I> declares a reference.</P>

<P><B>Proposed resolution (March, 2011):</B></P>

<P>This issue is resolved by the resolution of
<A HREF="
     cwg_defects.html#1166">issue 1166</A> in paper N3262.</P>

<BR><BR><HR><A NAME="1166"></A><H4>1166.
  
<I>exception-declaration</I>s that do not declare objects
</H4><B>Section: </B>15.3&#160; [except.handle]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>US
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-03<BR><BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#GB45">N3092 comment
  GB&#160;45<BR></A>

<P>According to 15.3 [except.handle] paragraph 16,</P>

<BLOCKQUOTE>

The object declared in an <I>exception-declaration</I> or, if the
<I>exception-declaration</I> 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.

</BLOCKQUOTE>

<P>This wording leaves unspecified how an <I>exception-declaration</I>
that is a reference should be treated.  For example, presumably a
reference to an abstract class type should be permitted, but that is
not specified.  The treatment of ellipsis is also not clearly
addressed.</P>

<BR><BR><HR><A NAME="1218"></A><H4>1218.
  
What is the &#8220;currently-handled exception&#8221; in a multi-threaded program?
</H4><B>Section: </B>15.3&#160; [except.handle]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>CA
 &#160;&#160;&#160;

 <B>Date: </B>2010-11-12<BR><BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#CA5">N3092 comment
  CA&#160;5<BR></A>

<P>15.3 [except.handle] paragraph 8 defines the &#8220;currently
handled exception&#8221; as</P>

<BLOCKQUOTE>

The exception with the most recently activated handler that is still active

</BLOCKQUOTE>

<P>This definition ignores the possibility that an exception might be
thrown and caught in another thread during the execution of a handler.
Since <TT>throw;</TT> rethrows the &#8220;currently handled
exception,&#8221; one might conclude that it would be the other
thread's exception that would be rethrown instead of the one that
activated that handler.</P>

<P><B>Proposed resolution (January, 2011):</B></P>

<OL><LI><P>Change 15 [except] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

Exception handling provides a way of transferring control and
information from a point in the execution of a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">program</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">thread</SPAN> to an exception handler associated with a point
previously passed by the execution...

</BLOCKQUOTE>

<LI><P>Change 15.1 [except.throw] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

...The implementation may then deallocate the memory for the exception
object; any such deallocation is done in an unspecified way. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I>
An exception thrown by a <I>throw-expression</I> does not propagate to other
threads unless caught, stored, and rethrown using appropriate library
functions; see 18.8.5 [propagation] and 30.6 [futures].
&#8212;<I>end note</I>]</SPAN>

</BLOCKQUOTE>

<LI><P>Change 15.3 [except.handle] paragraph 6 as follows:</P></LI>

If no match is found among the handlers for a try block, the search
for a matching handler continues in a dynamically surrounding try
block <SPAN style="font-weight:bold;background-color:#A0FFA0">of the same thread</SPAN>.

</OL>



<BR><BR><HR><A NAME="1073"></A><H4>1073.
  
Merging <I>dynamic-exception-specification</I>s and <I>noexcept-specification</I>s
</H4><B>Section: </B>15.4&#160; [except.spec]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-06-02<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>



<P>It is not clear how to handle compatible
<I>dynamic-exception-specification</I>s and
<I>noexcept-specification</I>s.  For example, given</P>

<PRE>
    void f() throw();
    void f() noexcept {
       throw 1;
    }
</PRE>

<P>should we call <TT>terminate()</TT> or <TT>unexpected()</TT>?  And
for</P>

<PRE>
    void g() throw (int);
    void g() noexcept (false) {
       throw 1.0;
    }
</PRE>

<P>should this call <TT>unexpected</TT> or propagate the exception?
Does the order of the declarations (and which is the definition)
matter?</P>

<P><U>Alisdair Meredith</U>:</P>

<P>And what about something like</P>

<PRE>
    struct A { ~A() throw() { } };
    struct B { ~B() noexcept { } };
    struct C: A, B { };
</PRE>

<P>What is the exception specification for <TT>C</TT>'s destructor?</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<OL><LI><P>Change 15.4 [except.spec] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

<P>Two <I>exception-specification</I>s are <I>compatible</I> if:</P>

<UL><LI><P>both are non-throwing (see below), regardless of their
form,</P></LI>

<LI><P>both have the form
<TT>noexcept(</TT><I>constant-expression</I><TT>)</TT> and the
<I>constant-expression</I>s are equivalent, <SPAN style="font-weight:bold;background-color:#A0FFA0">or</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">one <I>exception-specification</I> is a
<I>noexcept-specification</I> allowing all exceptions and the other is
of the form <TT>throw(</TT><I>type-id-list</I><TT>)</TT>,
or</SPAN></P></LI>

<LI><P>both are <I>dynamic-exception-specification</I>s that have the
same set of adjusted types.</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Add the following note to the end of 15.4 [except.spec]
paragraph 9:</P></LI>

<BLOCKQUOTE>

<P>Whenever an exception is thrown and the search...</P>

<P>&#8212;<I>end example</I>]</P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> A function can have multiple declarations with
different non-throwing <I>exception-specification</I>s; for this
purpose, the one on the function definition is used. &#8212;<I>end
note</I>]</SPAN></P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1167"></A><H4>1167.
  
<I>function-try-block</I>s for destructors
</H4><B>Section: </B>15.4&#160; [except.spec]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>GB
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-03<BR><BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#GB46">N3092 comment
  GB&#160;46<BR></A>

<P>It is not entirely clear that a <I>function-try-block</I>
on a destructor will catch exceptions from a base or member
destructor; whether such exceptions might be swallowed with
a simple <TT>return</TT> statement rather than being
rethrown; and whether such a clause might be entered
multiple times if multiple bases/members throw, or if that
is an automatic terminate call.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change 15 [except] paragraph 4 as follows:</P>

<BLOCKQUOTE>

...An exception thrown during the execution of the
initializer expressions in the <I>ctor-initializer</I> or
during the execution of the <I>compound-statement</I><SPAN style="font-weight:bold;background-color:#A0FFA0">,
or &#8212; in the case of a destructor &#8212; during the
destruction of a subobject,</SPAN> transfers control to a
handler in a <I>function-try-block</I> in the same way as an
exception thrown during the execution of a <I>try-block</I>
transfers control to other handlers. [<I>Example:</I>...

</BLOCKQUOTE>

<P><B>Additional note (October, 2010):</B></P>



<P>There is a related problem with this wording: it covers only
&#8220;the execution of the initializer expressions in the
<I>ctor-initializer</I>,&#8221; when it should also cover execution
of base and member constructors, regardless of whether they have
initializer expressions in the <I>ctor-initializer</I> or not.</P>

<P>The issue has been moved back to "review" status to allow
consideration of amending the proposed resolution to something
like</P>

<BLOCKQUOTE>

...during the execution of the <I>compound-statement</I> or, if the
function is a constructor or destructor, during the initialization
or destruction of the class's subobjects, transfers control...

</BLOCKQUOTE>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change 15 [except] paragraph 4 as follows:</P>

<BLOCKQUOTE>

A <I>function-try-block</I> associates a <I>handler-seq</I> with the
<I>ctor-initializer</I>, if present, and the
<I>compound-statement</I>.  An exception thrown during the execution
of the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">initializer expressions in the <I>ctor-initializer</I> or
during the execution of the</SPAN> <I>compound-statement</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">or,
for constructors and destructors, during the initialization or
destruction, respectively, of the class's subobjects,</SPAN> transfers
control to a handler in a <I>function-try-block</I> in the same way as
an exception thrown during the execution of a <I>try-block</I>
transfers control to other handlers.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1216"></A><H4>1216.
  
Exceptions &#8220;allowed&#8221; by a <I>noexcept-specification</I>
</H4><B>Section: </B>15.4&#160; [except.spec]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Jens Maurer
 &#160;&#160;&#160;

 <B>Date: </B>2010-11-02<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>According to 15.4 [except.spec] paragraph2 8 and 9,</P>

<BLOCKQUOTE>

<P>A function is said to <I>allow</I> an exception of type <TT>E</TT>
if its <I>dynamic-exception-specification</I> contains a type
<TT>T</TT> for which a handler of type <TT>T</TT> would be a match
(15.3 [except.handle]) for an exception of type <TT>E</TT>.</P>

<P>Whenever an exception is thrown and the search for a handler
(15.3 [except.handle]) encounters the outermost block of a
function with an <I>exception-specification</I> that does not allow
the exception, then,</P>

<UL><LI><P>if the <I>exception-specification</I> is a
<I>dynamic-exception-specification</I>, the function
<TT>std::unexpected()</TT> is called (15.5.2 [except.unexpected]),</P></LI>

<LI><P>otherwise, the function <TT>std::terminate()</TT> is called
(15.5.1 [except.terminate]).</P></LI>

</UL>

</BLOCKQUOTE>

<P>This does not define what it means for a <I>noexcept-specification</I>
to allow an exception.</P>

<P><B>Proposed resolution (November, 2010):</B></P>

<P>Change 15.4 [except.spec] paragraph 8 as follows:</P>

<BLOCKQUOTE>

A function is said to <I>allow</I> an exception of type <TT>E</TT> if
<SPAN style="font-weight:bold;background-color:#A0FFA0">the <I>constant-expression</I> in its
<I>noexcept-specification</I> evaluates to <TT>false</TT> or</SPAN> its
<I>dynamic-exception-specification</I> contains a type <TT>T</TT> for
which a handler of type <TT>T</TT> would be a match (15.3 [except.handle]) for an exception of type <TT>E</TT>.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1168"></A><H4>1168.
  
Additional reasons to call <TT>std::terminate</TT>
</H4><B>Section: </B>15.5.1&#160; [except.terminate]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>GB
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-03<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#GB47">N3092 comment
  GB&#160;47<BR></A>

<P>The list of reasons for which <TT>std::terminate</TT> is called
needs to be extended to cover several additional cases in
C++0x:</P>

<UL><LI><P>when function
<TT>std::nested_exception::rethrow_nested</TT> is called for
an object that stores a null exception pointer.</P></LI>

<LI><P>when execution of a function registered with
<TT>std::at_quick_exit</TT> exits using an exception.</P></LI>

<LI><P>when the destructor or a copy constructor of class
<TT>std::thread</TT> is called for the object that is
joinable.</P></LI>

</UL>

<P><B>Proposed resolution (August, 2010):</B></P>

<OL><LI><P>Change 15.5.1 [except.terminate] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<P>In <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the following</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">some</SPAN> situations
exception handling must be abandoned for less subtle error
handling techniques<SPAN style="text-decoration:line-through;background-color:#FFA0A0">:</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">. [<I>Note:</I> These
situations are:</SPAN></P>

<UL><LI><P>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 function that exits via an <SPAN style="text-decoration:line-through;background-color:#FFA0A0">uncaught</SPAN>
exception, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">[<I>Footnote:</I> For example, if the object
being thrown is of a class with a copy constructor,
std::terminate() will be called if that copy constructor
exits with an exception during a throw. &#8212;<I>end
footnote</I>]</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">or</SPAN></P></LI>

<LI><P>when the exception handling mechanism cannot find a
handler for a thrown exception (15.3 [except.handle]),
or</P></LI>

<LI><P>when the search for a handler (15.3 [except.handle]) encounters the outermost block of a function
with a <I>noexcept-specification</I> that does not allow the
exception (15.4 [except.spec]), or</P></LI>

<LI><P>when the destruction of an object during stack
unwinding (15.2) terminates by throwing an exception,
or</P></LI>

<LI><P>when initialization of a non-local variable with
static or thread storage duration (3.6.2 [basic.start.init]<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, 3.6.3 [basic.start.term]</SPAN>)
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">terminates by throwing</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">exits via</SPAN> an
exception, or</P></LI>

<LI><P>when destruction of an object with static or thread
storage duration exits <SPAN style="text-decoration:line-through;background-color:#FFA0A0">using</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">via</SPAN> an
exception (3.6.3 [basic.start.term]), or</P></LI>

<LI><P>when execution of a function registered with
<TT>std::atexit</TT> <SPAN style="font-weight:bold;background-color:#A0FFA0">or
<TT>std::at_quick_exit</TT></SPAN> exits <SPAN style="text-decoration:line-through;background-color:#FFA0A0">using</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">via</SPAN> an exception (18.5 [support.start.term]),
or</P></LI>

<LI><P>when a <I>throw-expression</I> with no operand
attempts to rethrow an exception and no exception is being
handled (15.1 [except.throw]), or</P></LI>

<LI><P>when <TT>std::unexpected</TT> throws an exception
which is not allowed by the previously violated
<I><SPAN style="font-weight:bold;background-color:#A0FFA0">dynamic-</SPAN>exception-specification</I>, and
<TT>std::bad_exception</TT> is not included in that
<I><SPAN style="font-weight:bold;background-color:#A0FFA0">dynamic-</SPAN>exception-specification</I>
(15.5.2 [except.unexpected]), or</P></LI>

<LI><P>when the implementation's default unexpected
exception handler is called (D.11.1 [unexpected.handler])<SPAN style="text-decoration:line-through;background-color:#FFA0A0">.</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">, or</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">when the function
<TT>std::nested_exception::rethrow_nested</TT> is called for
an object that has captured no exception (18.8.6 [except.nested]), or</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">when execution of the initial function of a thread
exits via an exception (30.3.1.2 [thread.thread.constr]),
or</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">when the destructor or the copy assignment operator
is invoked on a <TT>std::thread</TT> object that refers to a
joinable thread (30.3.1.3 [thread.thread.destr], 30.3.1.4 [thread.thread.assign]).</SPAN></P></LI>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end note</I>]</SPAN></P>

</BLOCKQUOTE>

<LI><P>Insert the following as a new paragraph following
15.1 [except.throw] paragraph 6:</P></LI>

<BLOCKQUOTE>

<P>An exception is considered caught...</P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">If the exception handling mechanism, after
completing evaluation of the expression to be thrown but
before the exception is caught, calls a function that exits
via an exception, <TT>std::terminate</TT> is called (15.5.1 [except.terminate]). [<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">    struct C {
      C() { }
      C(const C&amp;) { throw 0; }
    };

    int main() {
      try {
        throw C();   //<SPAN style="font-family:Times;font-style:italic"> calls </SPAN>std::terminate()
      } catch(C) { }
    }</SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

<LI><P>Change 15.2 [except.ctor] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

The process of calling destructors for automatic objects
constructed on the path from a try block to a
<I>throw-expression</I> is called &#8220;<I>stack
unwinding</I>.&#8221; <SPAN style="text-decoration:line-through;background-color:#FFA0A0">[<I>Note:</I></SPAN> If a
destructor called during stack unwinding exits with an
exception, <TT>std::terminate</TT> is called (15.5.1 [except.terminate]). <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I></SPAN> So destructors
should generally catch exceptions and not let them propagate
out of the destructor.  &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Change 3.6.2 [basic.start.init] paragraph 6 as follows:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">[<I>Note:</I></SPAN> If the initialization of a
non-local variable with static or thread storage duration
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">terminates by throwing</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">exits via</SPAN> an
exception, <TT>std::terminate</TT> is called (<SPAN style="text-decoration:line-through;background-color:#FFA0A0">see</SPAN>
15.5.1 [except.terminate]). <SPAN style="text-decoration:line-through;background-color:#FFA0A0">&#8212;<I>end note</I>]</SPAN>

</BLOCKQUOTE>

<LI><P>Change 3.6.3 [basic.start.term] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...<SPAN style="text-decoration:line-through;background-color:#FFA0A0">[<I>Note:</I></SPAN> If the destruction of <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a
non-local</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">an</SPAN> object with static or thread
storage duration <SPAN style="text-decoration:line-through;background-color:#FFA0A0">terminates by throwing</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">exits via</SPAN> an exception, <TT>std::terminate</TT>
is called (<SPAN style="text-decoration:line-through;background-color:#FFA0A0">see</SPAN> 15.5.1 [except.terminate]). <SPAN style="text-decoration:line-through;background-color:#FFA0A0">&#8212;<I>end note</I>]</SPAN>

</BLOCKQUOTE>

<LI><P>Change 18.5 [support.start.term] paragraph 8 bullet 1 as
follows:</P></LI>

<UL><LI><P>First, objects with thread storage duration...</P>

<P>If control leaves a registered function called by
<TT>exit</TT> because the function does not provide a
handler for a thrown exception, <TT>terminate()</TT> shall
be called <SPAN style="font-weight:bold;background-color:#A0FFA0">(15.5.1 [except.terminate])</SPAN>.</P>

</LI>

</UL>

</OL>

<BR><BR><HR><A NAME="1171"></A><H4>1171.
  
Partial stack unwinding with <TT>noexcept</TT> violation
</H4><B>Section: </B>15.5.1&#160; [except.terminate]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-04<BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<P>The current wording of 15.5.1 [except.terminate] paragraph 2
makes it sound as if stack unwinding in the case of a
<TT>noexcept</TT> violation is an all-or-nothing proposition.  It
would be useful to be able to partially unwind the stack, in
particular, not to call destructors for the function containing the
<I>noexcept-specification</I>.</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Change 15.5.1 [except.terminate] paragraph 2 as follows:</P>

<BLOCKQUOTE>

...In the situation where the search for a handler (15.3 [except.handle]) encounters the outermost block of a function with a
<I>noexcept-specification</I> that does not allow the exception
(15.4 [except.spec]), it is implementation-defined whether the
stack is unwound<SPAN style="font-weight:bold;background-color:#A0FFA0">, unwound partially, or not unwound at all</SPAN>
before <TT>std::terminate()</TT> is called. In all other situations,
the stack shall not be unwound...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="475"></A><H4>475.
  
When is <TT>std::uncaught_exception()</TT> true? (take 2)
</H4><B>Section: </B>15.5.3&#160; [except.uncaught]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>Martin Sebor
 &#160;&#160;&#160;

 <B>Date: </B>27 Sep 2004<BR>


<P>[Voted into WP at August, 2010 meeting.]</P>

<P> See also <A HREF="
     cwg_closed.html#37">issue 37</A>.</P>

<P>Given this piece of code and <TT>S</TT> having a user-defined
ctor, at precisely which point must
<TT>std::uncaught_exception()</TT> return <TT>true</TT> and where
<TT>false</TT>?</P>

<PRE>
    try { S s0; throw s0; } catch (S s2) { }
</PRE>

<P>My understanding of the semantics of the code is as
follows:</P>

<OL>

<LI>The throw expression creates a temporary for a copy of
<TT>s0</TT>, say <TT>s1</TT>, using the copy ctor of
<TT>S</TT>. In this invocation of the copy ctor
<TT>uncaught_exception()</TT> must return <TT>true</TT>.</LI>

<LI><TT>s0</TT> is destroyed during stack unwinding. In the
invocation of <TT>S</TT> dtor <TT>uncaught_exception()</TT> must
still return <TT>true</TT>.</LI>

<LI>The variable <TT>s2</TT> is initialized from <TT>s1</TT> by
invoking the copy ctor of <TT>S</TT>. In this invocation
<TT>uncaught_exception()</TT> must also return
<TT>true</TT>.</LI>

<LI><TT>s2</TT> and <TT>s1</TT> are destroyed. In the invocations
of <TT>S</TT> dtor <TT>uncaught_exception()</TT> must return
<TT>false</TT>.</LI>

</OL>

<P>Is my understanding correct?</P>

<P>15.1 [except.throw] paragraph 3 talks about &#8220;the
exception object&#8221; when describing the semantics of the
<I>throw-expression</I>:</P>

<BLOCKQUOTE>
a <I>throw-expression</I> initializes a temporary object, called
the <I>exception object</I>...  </BLOCKQUOTE>

<P>However, 15.5.1 [except.terminate] paragraph 1 talks about
&#8220;the expression to be thrown&#8221; when enumerating the
conditions under which <TT>terminate()</TT> is called:</P>

<BLOCKQUOTE>
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 user
function that exits via an uncaught exception... </BLOCKQUOTE>

<P>And, 15.5.3 [except.uncaught] paragraph 1 refers to
&#8220;the object to be thrown&#8221; in the description of
<TT>uncaught_exception()</TT>:</P>

<BLOCKQUOTE>
The function <TT>std::uncaught_exception()</TT> returns
<TT>true</TT> after completing evaluation of the object to be
thrown... </BLOCKQUOTE>

<P>Are all these objects one and the same? I believe the answer
is important in case the construction of the temporary exception
object throws another exception.</P>

<P>Suppose they are the same. Then <TT>uncaught_exception()</TT>
invoked from the copy ctor for <TT>s1</TT> (from the example
[above]) must return <TT>false</TT> and a new exception (e.g.,
<TT>bad_alloc</TT>) may be thrown and caught by a matching
handler (i.e., without calling <TT>terminate()</TT>).</P>

<P>But if they are not the same, then
<TT>uncaught_exception()</TT> invoked from the copy ctor for
<TT>s1</TT> must return <TT>true</TT> and throwing another
exception would end up calling <TT>terminate()</TT>. This would,
IMO, have pretty severe consequences on writing exception safe
exception classes.</P>

<P>As in the first case, different compilers behave differently,
with most compilers not calling <TT>terminate()</TT> when the
ctor for the temporary exception object throws. Unfortunately,
the two compilers that I trust the most do call
<TT>terminate()</TT>.</P>

<P>FWIW, my feeling is that it should be possible for the copy
ctor invoked to initialize the temporary exception object to
safely exit by throwing another exception, and that the new
exception should be allowed to be caught without calling
<TT>terminate</TT>.</P>

<P><U>Mike Miller</U>: The way I see this, a <I>throw-expression</I> has an 
<I>assignment-expression</I> as an operand.  This expression is
&#8220;the expression to be thrown.&#8221; Evaluation of this
expression yields an object; this object is &#8220;the object to
be thrown.&#8221; This object is then copied to the exception
object.</P>

<P><U>Martin Sebor</U>: Here's a survey of the return value from
<TT>uncaught_exception()</TT> in the various stages of exception
handling, implemented by current compilers:</P>

<TABLE FRAME="BOX" RULES="ALL">
<THEAD>
<TR>
<TH></TH>
<TH>expr</TH>
<TH>temp</TH>
<TH>unwind</TH>
<TH>handlr</TH>
<TH>2nd ex</TH>
</TR>
</THEAD>
<TBODY>
<TR>
<TD>HP aCC 6</TD>
<TD ALIGN="CENTER">0</TD>
<TD ALIGN="CENTER">0</TD>
<TD ALIGN="CENTER">1</TD>
<TD ALIGN="CENTER">0</TD>
<TD ALIGN="CENTER">OK</TD>
</TR>
<TR>
<TD>Compaq C++ 6.5</TD>
<TD ALIGN="CENTER">0</TD>
<TD ALIGN="CENTER">0</TD>
<TD ALIGN="CENTER">1</TD>
<TD ALIGN="CENTER">1</TD>
<TD ALIGN="CENTER">ABRT</TD>
</TR>
<TR>
<TD>EDG eccp 3.4</TD>
<TD ALIGN="CENTER">0</TD>
<TD ALIGN="CENTER">1</TD>
<TD ALIGN="CENTER">1</TD>
<TD ALIGN="CENTER">1</TD>
<TD ALIGN="CENTER">ABRT</TD>
</TR>
<TR>
<TD>g++ 3.4.2</TD>
<TD ALIGN="CENTER">0</TD>
<TD ALIGN="CENTER">0</TD>
<TD ALIGN="CENTER">1</TD>
<TD ALIGN="CENTER">0</TD>
<TD ALIGN="CENTER">OK</TD>
</TR>
<TR>
<TD>Intel C++ 7.0</TD>
<TD ALIGN="CENTER">0</TD>
<TD ALIGN="CENTER">0</TD>
<TD ALIGN="CENTER">1</TD>
<TD ALIGN="CENTER">0</TD>
<TD ALIGN="CENTER">OK</TD>
</TR>
<TR>
<TD>MIPSpro 7.4.1</TD>
<TD ALIGN="CENTER">0</TD>
<TD ALIGN="CENTER">0</TD>
<TD ALIGN="CENTER">1</TD>
<TD ALIGN="CENTER">1</TD>
<TD ALIGN="CENTER">ABRT</TD>
</TR>
<TR>
<TD>MSVC 7.0</TD>
<TD ALIGN="CENTER">0</TD>
<TD ALIGN="CENTER">0</TD>
<TD ALIGN="CENTER">1</TD>
<TD ALIGN="CENTER">0</TD>
<TD ALIGN="CENTER">OK</TD>
</TR>
<TR>
<TD>SunPro 5.5</TD>
<TD ALIGN="CENTER">1</TD>
<TD ALIGN="CENTER">1</TD>
<TD ALIGN="CENTER">1</TD>
<TD ALIGN="CENTER">0</TD>
<TD ALIGN="CENTER">OK</TD>
</TR>
<TR>
<TD>VisualAge 6.0</TD>
<TD ALIGN="CENTER">0</TD>
<TD ALIGN="CENTER">1</TD>
<TD ALIGN="CENTER">1</TD>
<TD ALIGN="CENTER">1</TD>
<TD ALIGN="CENTER">OK</TD>
</TR>
</TBODY>
</TABLE>

<P>In the table above:</P>

<UL>
<TABLE FRAME="VOID" RULES="NONE" CELLPADDING="10">
<TR>
<TD VALIGN="TOP">expr</TD>
<TD VALIGN="TOP">is the evaluation of the <I>assignment-expression</I> in the
<I>throw-expression</I></TD>
</TR>
<TR>
<TD VALIGN="TOP">temp</TD>
<TD VALIGN="TOP">is the invocation of the copy ctor for the unnamed temporary
exception object created by the runtime.</TD>
</TR>
<TR>
<TD VALIGN="TOP">unwind</TD>
<TD VALIGN="TOP">is stack unwinding.</TD>
</TR>
<TR>
<TD VALIGN="TOP">handlr</TD>
<TD VALIGN="TOP">is the invocation of the copy ctor in the
<I>exception-declaration</I> in the catch handler.</TD>
</TR>
<TR>
<TD VALIGN="TOP">2nd ex</TD>
<TD VALIGN="TOP">describes the behavior of the implementation when the
invocation of the copy ctor for the unnamed temporary exception
object [temp] throws another exception.</TD>
</TR>
</TABLE>
</UL>

<P><B>Proposed resolution (October, 2004):</B></P>

<OL>

<LI><P>Change 15.1 [except.throw] paragraph 3 as
follows:</P>

<BLOCKQUOTE>

A <I>throw-expression</I> initializes a temporary object, called the
<I>exception object</I>, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">by copying the <I>thrown
object</I> (i.e., the result of evaluating its
<I>assignment-expression</I> operand) to it. The</SPAN> type of
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">which</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">the exception object</SPAN> is determined by
removing any top-level <I>cv-qualifier</I>s from the static type
of the operand of <TT>throw</TT> and adjusting the type from
&#8220;array of <TT>T</TT>&#8221; or &#8220;function returning
<TT>T</TT>&#8221; to &#8220;pointer to <TT>T</TT>&#8221; or
&#8220;pointer to function returning <TT>T</TT>,&#8221;
respectively.  [<I>Note:</I> the temporary object created <SPAN style="text-decoration:line-through;background-color:#FFA0A0">for</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">by</SPAN> a <I>throw-expression</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">that</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">whose
operand</SPAN> is a string literal is never of type <TT>char*</TT>
or <TT>wchar_t*</TT>; that is, the special conversions for string
literals from the types &#8220;array of <TT>const
char</TT>&#8221; and &#8220;array of <TT>const
wchar_t</TT>&#8221; to the types &#8220;pointer to
<TT>char</TT>&#8221; and &#8220;pointer to
<TT>wchar_t</TT>,&#8221; respectively (4.2 [conv.array]), are never applied to <SPAN style="font-weight:bold;background-color:#A0FFA0">the operand of</SPAN> a
<I>throw-expression</I>. &#8212;<I>end note</I>] The temporary is
an lvalue and is used to initialize the variable named in the
matching handler (15.3 [except.handle]).  The type of the
<SPAN style="font-weight:bold;background-color:#A0FFA0">operand of a</SPAN> <I>throw-expression</I> shall not be an
incomplete type, or a pointer to an incomplete type other than
(possibly cv-qualified) <TT>void</TT>. [...]

</BLOCKQUOTE>

</LI>

<LI><P>Change the note in 15.3 [except.handle] paragraph 3
as follows:</P>

<BLOCKQUOTE>

[<I>Note:</I> a <I>throw-expression</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">operand that</SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">which</SPAN> is an integral constant expression of integer type
that evaluates to zero does not match a handler of pointer type;
that is, the null pointer constant conversions (4.10 [conv.ptr], 4.11 [conv.mem]) do not
apply. &#8212;<I>end note</I>]

</BLOCKQUOTE>

</LI>

<LI><P>Change 15.5.1 [except.terminate] paragraph 1 bullet 1
as follows:</P>

<BLOCKQUOTE>

when the exception handling mechanism, after completing
evaluation of the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">expression to be thrown</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">operand of
<TT>throw</TT></SPAN> but before the exception is caught
(15.1 [except.throw]), calls a user function that exits
via an uncaught exception,

</BLOCKQUOTE>

</LI>

<LI><P>Change 15.5.3 [except.uncaught] paragraph 1 as
follows:</P>

<BLOCKQUOTE>

The function <TT>std::uncaught_exception()</TT> returns
<TT>true</TT> after completing evaluation of the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">object to be
thrown</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">operand of <TT>throw</TT></SPAN> until completing the
initialization of the <I>exception-declaration</I> in the
matching handler (18.8.4 [uncaught]).

</BLOCKQUOTE>

</LI>

<LI><P>Change 18.8.4 [uncaught] paragraph 1 by adding
the indicated words:</P>

<BLOCKQUOTE>

<I>Returns:</I> <TT>true</TT> after completing evaluation of
<SPAN style="font-weight:bold;background-color:#A0FFA0">the operand of</SPAN> a <I>throw-expression</I> until either
completing initialization of the <I>exception-declaration</I> in
the matching handler or entering <TT>unexpected()</TT> due to the
throw; or after entering <TT>terminate()</TT> for any reason
other than an explicit call to <TT>terminate()</TT>.
[<I>Note:</I> This includes stack unwinding (15.2 [except.ctor]). &#8212;<I>end note</I>]

</BLOCKQUOTE>

</LI>

</OL>

<P><B>Notes from the April, 2005 meeting:</B></P>

<P>The CWG discussed this resolution both within the group and with
other interested parties.  Among the points that were made:</P>

<UL><LI><P>Martin Sebor  pointed to a
<A HREF="http://gcc.gnu.org/ml/libstdc++/2005-01/msg00033.html">posting</A>
in which he argues that writing copy constructors is more difficult if
an exception during the copy to the exception object will result in a
call to <TT>std::terminate()</TT>.</P>
</LI>

<LI><P>In response to a question about why the copy to the exception
object is different from the copy from the exception object to the
object in the <I>exception-declaration</I>, it was observed that the
writer of the handler can avoid the second copy (by using a reference
declaration), but the first copy is unavoidable.</P></LI>

<LI><P>John Spicer observed that not exiting via exception should be a
design constraint for copy constructors in exception objects,
regardless of whether <TT>std::terminate()</TT> is called or
not.</P></LI>

<LI><P>Adopting the position that <TT>uncaught_exception()</TT>
returns <TT>false</TT> during the copy to the exception object would
reduce the differences between the case where that copy is elided and
the case where it is performed.</P></LI>

<LI><P>Jason Merrill observed that making <TT>uncaught_exception()</TT>
return <TT>false</TT> during the copy to the exception object would
simplify the code generated by g++; as it currently stands, the
compiler must generate code to catch exceptions during that copy so
<TT>std::terminate()</TT> can be called.</P></LI>

<LI><P>Bjarne Stroustrup worried that allowing the copy constructor to
throw an exception during the copy to the exception object could
result in a serious and specific exception being silently transformed
into a more trivial and generic one (although the CWG later noted that
this risk already exists if something in the expression being thrown
throws an exception before the expression completes).</P></LI>

</UL>

<P>The CWG felt that more input from a wider audience was necessary
before a decision could be made on the appropriate resolution.
</P>

<P><B>Notes from the April, 2006 meeting:</B></P>

<P>The CWG agreed with the position that <TT>std::uncaught_exception()</TT>
should return <TT>false</TT> during the copy to the exception object
and that <TT>std::terminate()</TT> should not be called if that
constructor exits with an exception.  The issue was returned to
&#8220;drafting&#8221; status for rewording to reflect this position.</P>

<P><B>Additional notes (September, 2007):</B></P>

<P>Although this issue deals primarily with when
<TT>std::uncaught_exception()</TT> begins to return <TT>true</TT>, the
specification of when it begins to return <TT>false</TT> is also
problematic.  There are two parallel sections that define the meaning
of <TT>std::uncaught_exception()</TT> and each has a different
problem.  15.5.3 [except.uncaught] reads,</P>

<BLOCKQUOTE>

The function <TT>std::uncaught_exception()</TT> returns <TT>true</TT>
after completing evaluation of the object to be thrown until
completing the initialization of the <I>exception-declaration</I> in
the matching handler (18.8.4 [uncaught]).

</BLOCKQUOTE>

<P>The problem here is that whether an exception is considered
caught (the underlying condition tested by the function) is here
presented in terms of having initialized the <I>exception-declaration</I>,
while in other places it is specified by having an active handler for
the exception, e.g., 15.1 [except.throw] paragraph 6:</P>

<BLOCKQUOTE>

An exception is considered caught when a handler for that exception
becomes active (15.3 [except.handle]).

</BLOCKQUOTE>

<P>This distinction is important because of 15.3 [except.handle]
paragraph 3:</P>

<BLOCKQUOTE>

A handler is considered active when initialization is complete for the
formal parameter (if any) of the catch clause.  [<I>Note:</I> the
stack will have been unwound at that point. &#8212;<I>end note</I>]
Also, an implicit handler is considered active
when <TT>std::terminate()</TT> or <TT>std::unexpected()</TT> is
entered due to a throw.

</BLOCKQUOTE>

<P>Note that there is no <I>exception-declaration</I> to be
initialized for the <TT>std::terminate()</TT> and
<TT>std::unexpected()</TT> cases; nevertheless, according to
18.8.4 [uncaught], <TT>std::uncaught_exception()</TT>
is supposed to return <TT>false</TT> when one of those two functions
is entered.</P>

<P>The specification in 18.8.4 [uncaught] is not well
phrased, however, and is open to misinterpretation.  It reads,</P>

<BLOCKQUOTE>

<I>Returns:</I> <TT>true</TT> after completing evaluation of a
<I>throw-expression</I> until either completing initialization of the
<I>exception-declaration</I> in the matching handler or entering
<TT>unexpected()</TT> due to the throw; or after
entering <TT>terminate()</TT> for any reason other than an explicit
call to <TT>terminate()</TT>.

</BLOCKQUOTE>

<P>The problem here is lack of parallelism: does &#8220;after
entering <TT>terminate</TT>&#8221; refer to the condition for returning
<TT>true</TT> or <TT>false</TT>?  This would be better phrased along
the lines of</P>

<BLOCKQUOTE>

<I>Returns:</I> <TT>true</TT> after completing evaluation of a
<I>throw-expression</I> until a handler for the exception becomes
active (15.3 [except.handle]).

</BLOCKQUOTE>

<P><B>Proposed resolution (March, 2010):</B></P>

<OL><LI><P>Change 15.5.1 [except.terminate] paragraph 1 bullet 1 as
follows:</P></LI>

<BLOCKQUOTE>

<P>In the following situations exception handling must be
abandoned for less subtle error handling techniques:</P>

<UL><LI><P>when the exception handling mechanism, after
completing <SPAN style="text-decoration:line-through;background-color:#FFA0A0">evaluation of the expression to be thrown</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">the initialization of the exception object</SPAN> but before
the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">exception is caught</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">activation of a handler
for the exception</SPAN> (15.1 [except.throw]), calls a
function that exits via an uncaught exception, [<I>Footnote:</I>
For example, if the object being thrown is of a class with a copy
constructor, <TT>std::terminate()</TT> will be called if that
copy constructor exits with an exception during <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a
<TT>throw</TT></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">the initialization of the formal
parameter of a catch clause</SPAN>. &#8212;<I>end
footnote</I>]</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 15.5.3 [except.uncaught] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

The function <TT>std::uncaught_exception()</TT> returns
<TT>true</TT> after completing <SPAN style="text-decoration:line-through;background-color:#FFA0A0">evaluation of the object to
be thrown</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">the initialization of the exception object
(15.1 [except.throw])</SPAN> until completing the
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">initialization of the <I>exception-declaration</I> in the
matching handler</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">activation of a handler for the
exception</SPAN> (<SPAN style="font-weight:bold;background-color:#A0FFA0">15.3 [except.handle],
</SPAN>18.8.4 [uncaught])...

</BLOCKQUOTE>

<LI><P>Change 18.8.4 [uncaught] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<I>Returns:</I> <TT>true</TT> after <SPAN style="text-decoration:line-through;background-color:#FFA0A0">completing evaluation of a
<I>throw-expression</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">initializing an exception
object 15.1 [except.throw]</SPAN> until <SPAN style="text-decoration:line-through;background-color:#FFA0A0">either
completing initialization of the <I>exception-declaration</I> in
the matching handler or entering <TT>unexpected()</TT> due to the
throw; or after entering <TT>terminate()</TT> for any reason
other than an explicit call to <TT>terminate()</TT></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">a
handler for the exception (including <TT>unexpected()</TT> or
<TT>terminate()</TT>) is activated (15.3 [except.handle])</SPAN>.  [<I>Note:</I> This includes stack unwinding
(15.2 [except.ctor]). &#8212;<I>end note</I>]

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="1169"></A><H4>1169.
  
Missing feature macro for strict pointer safety
</H4><B>Section: </B>16.8&#160; [cpp.predefined]
 &#160;&#160;&#160;

 <B>Status: </B>FDIS
 &#160;&#160;&#160;

 <B>Submitter: </B>GB
 &#160;&#160;&#160;

 <B>Date: </B>2010-08-03<BR><BR>


<P>[Voted into the WP at the November, 2010 meeting.]</P>

<A href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#DE13">N3092 comment
  DE&#160;13<BR></A>

<P>The recommendations of document N2693 included a feature
macro to enable a program to determine whether the
implementation enforces strict pointer safety or not, but
this macro is not specified in 16.8 [cpp.predefined].</P>

<P><B>Proposed resolution (August, 2010):</B></P>

<P>Add the following to the end of 16.8 [cpp.predefined]
paragraph 2:</P>

<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>__STDCPP_STRICT_POINTER_SAFETY__</TT></SPAN>
<UL><SPAN style="font-weight:bold;background-color:#A0FFA0">Defined, and has the value integer constant 1, if
and only if the implementation has strict pointer safety
(3.7.4.3 [basic.stc.dynamic.safety]).</SPAN></UL></UL>

<BR><BR><BR><BR></BODY>
</HTML>
