<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>
    CWG Issue 1091</TITLE>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<STYLE TYPE="text/css">
  INS { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  .INS { text-decoration:none; background-color:#D0FFD0 }
  DEL { text-decoration:line-through; background-color:#FFA0A0 }
  .DEL { text-decoration:line-through; background-color: #FFD0D0 }
  @media (prefers-color-scheme: dark) {
    HTML { background-color:#202020; color:#f0f0f0; }
    A { color:#5bc0ff; }
    A:visited { color:#c6a8ff; }
    A:hover, a:focus { color:#afd7ff; }
    INS { background-color:#033a16; color:#aff5b4; }
    .INS { background-color: #033a16; }
    DEL { background-color:#67060c; color:#ffdcd7; }
    .DEL { background-color:#67060c; }
  }
  SPAN.cmnt { font-family:Times; font-style:italic }
</STYLE>
</HEAD>
<BODY>
<P><EM>This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21
  Core Issues List revision 118b.
  See http://www.open-std.org/jtc1/sc22/wg21/ for the official
  list.</EM></P>
<P>2025-09-28</P>
<HR>
<A NAME="1091"></A><H4>1091.
  
Inconsistent use of the term &#8220;object expression&#8221;
</H4>
<B>Section: </B>7.6.4&#160; [<A href="https://wg21.link/expr.mptr.oper">expr.mptr.oper</A>]
 &#160;&#160;&#160;

 <B>Status: </B>C++11
 &#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
7.6.1.5 [<A href="https://wg21.link/expr.ref#2">expr.ref</A>] 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
7.6.4 [<A href="https://wg21.link/expr.mptr.oper#4">expr.mptr.oper</A>] 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 _N4868_.6.5.6 [<A href="https://wg21.link/basic.lookup.classref">basic.lookup.classref</A>],
describing the lookup in a class member access expression.  The
first paragraph uses the term consistently with its use in
7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>], but paragraph 2 reads:</P>

<BLOCKQUOTE>

If the <I>id-expression</I> in a class member access
(7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>]) 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 7.6.1.3 [<A href="https://wg21.link/expr.call#1">expr.call</A>] paragraph 1:
</P>

<BLOCKQUOTE>

...the call is as a member of the object pointed to or
referred to by the object expression (7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>], 7.6.4 [<A href="https://wg21.link/expr.mptr.oper">expr.mptr.oper</A>])... its final
overrider (11.7.3 [<A href="https://wg21.link/class.virtual">class.virtual</A>]) 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 Clause 7 [<A href="https://wg21.link/expr#7">expr</A>] 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 7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>]; for example,
_N4567_.5.1.1 [<A href="https://wg21.link/expr.prim.general#10.1">expr.prim.general</A>] bullet 10.1
mentions</P>

<BLOCKQUOTE>

a class member access (7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>]) in which
the object-expression refers to the member's class

</BLOCKQUOTE>

<P>using the term defined in Clause 7 [<A href="https://wg21.link/expr#7">expr</A>] paragraph 7 but
linking it with 7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>].</P>

<P>These uses of &#8220;object expression&#8221; and
&#8220;object-expression&#8221; need to be made consistent,
especially the reference in 7.6.4 [<A href="https://wg21.link/expr.mptr.oper">expr.mptr.oper</A>] 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 _N4868_.6.5.6 [<A href="https://wg21.link/basic.lookup.classref#2">basic.lookup.classref</A>] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

...<DEL>If the type of the object expression is of pointer to scalar
type</DEL> <INS>For a pseudo-destructor call (_N4778_.7.6.1.4 [<A href="https://wg21.link/expr.pseudo">expr.pseudo</A>])</INS>, the <I>unqualified-id</I> is looked up in the
context of the complete <I>postfix-expression</I>.

</BLOCKQUOTE>

<LI><P>Delete Clause 7 [<A href="https://wg21.link/expr#7">expr</A>] paragraph 7</P></LI>

<BLOCKQUOTE>

<DEL>An expression designating an object is called an
object-expression.</DEL>

</BLOCKQUOTE>

<LI><P>Change _N4567_.5.1.1 [<A href="https://wg21.link/expr.prim.general#10">expr.prim.general</A>] 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 (7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>]) in which the <DEL>object-expression</DEL> <INS>object
expression</INS> 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 7.6.1.3 [<A href="https://wg21.link/expr.call#1">expr.call</A>] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...For a member function call, the postfix expression shall be an
implicit (11.4.3 [<A href="https://wg21.link/class.mfct.non.static">class.mfct.non.static</A>], 11.4.9 [<A href="https://wg21.link/class.static">class.static</A>]) or
explicit class member access (7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>]) whose
<I>id-expression</I> is a function member name, or a pointer-to-member
expression (7.6.4 [<A href="https://wg21.link/expr.mptr.oper">expr.mptr.oper</A>]) selecting a function member; the
call is as a member of the <INS>class</INS> object <DEL>pointed to
or</DEL> referred to by the object expression <DEL>(7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>], 7.6.4 [<A href="https://wg21.link/expr.mptr.oper">expr.mptr.oper</A>])</DEL>... [<I>Note:</I> the
dynamic type is the type of the object <DEL>pointed or</DEL> referred
to by the current value of the object expression. 11.9.5 [<A href="https://wg21.link/class.cdtor">class.cdtor</A>] describes the behavior of virtual function calls when the
<DEL>object-expression</DEL> <INS>object expression</INS> refers to an
object under construction or destruction. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Change 7.6.1.5 [<A href="https://wg21.link/expr.ref#2">expr.ref</A>] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

For the first option (dot) <DEL>the type of</DEL> the first expression <DEL>(the
<I>object expression</I>)</DEL> shall <DEL>be &#8220;class
object&#8221; (of a complete type)</DEL> <INS>have complete class
type</INS>. For the second option (arrow) <DEL>the type of</DEL> the
first expression <DEL>(the <I>pointer expression</I>)</DEL> shall
<DEL>be &#8220;pointer to class object&#8221; (of a complete
type)</DEL> <INS>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 7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>] will
address only the first option (dot) [<I>Footnote:</I> Note that
<TT>(*(E1))</TT> is an lvalue. &#8212;<I>end footnote</I>]</INS>.  In
<DEL>these cases</DEL> <INS>either case</INS>, the
<I>id-expression</I> shall name a member of the class or of one of its
base classes...

</BLOCKQUOTE>

<LI><P>Change 7.6.1.5 [<A href="https://wg21.link/expr.ref#3">expr.ref</A>] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

<DEL>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 7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>]
will address only the first option (dot)<SUP>66</SUP>.</DEL> Abbreviating
<I><DEL>object-expression</DEL><INS>postfix-expression</INS>.id-expression</I>
as <TT>E1.E2</TT>, <DEL>then the</DEL> <INS><TT>E1</TT> is called the
<I>object expression</I>.  The</INS> type and value category of
<DEL>this expression</DEL> <INS><TT>E1.E2</TT></INS> are determined as
follows...

</BLOCKQUOTE>

<LI><P>Change 7.6.4 [<A href="https://wg21.link/expr.mptr.oper#3">expr.mptr.oper</A>] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

...<DEL>The result is an object or a function of the
type specified by the second operand.</DEL> <INS>The expression
<TT>E1-&gt;*E2</TT> is converted into the equivalent form
<TT>(*(E1)).*E2.</TT></INS>

</BLOCKQUOTE>

<LI><P>Change 7.6.4 [<A href="https://wg21.link/expr.mptr.oper#4">expr.mptr.oper</A>] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

<DEL>The first operand</DEL> <INS>Abbreviating
<I>pm-expression</I><TT>.*</TT><I>cast-expression</I> as
<TT>E1.*E2</TT>, <TT>E1</TT></INS> is called the <I>object
expression</I>.  If the dynamic type of <DEL>the object
expression</DEL> <INS><TT>E1</TT></INS> does not contain the member to
which <DEL>the pointer</DEL> <INS><TT>E2</TT></INS> refers, the
behavior is undefined.

</BLOCKQUOTE>

<LI><P>Change 7.6.4 [<A href="https://wg21.link/expr.mptr.oper#6">expr.mptr.oper</A>] 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
<DEL><TT>-&gt;*</TT> expression or in a</DEL> <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 (7.2.1 [<A href="https://wg21.link/basic.lval">basic.lval</A>]) as its first
operand. The result of a <TT>.*</TT> expression whose second operand
is a pointer to a member function is a prvalue.  <DEL>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.</DEL> If the second
operand is the null pointer to member value (7.3.13 [<A href="https://wg21.link/conv.mem">conv.mem</A>]), the behavior is undefined.

</BLOCKQUOTE>

<LI><P>Change 11.4.9 [<A href="https://wg21.link/class.static#2">class.static</A>] 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 <DEL>object-expression</DEL>
<INS>object expression</INS> is evaluated...

</BLOCKQUOTE>

<LI><P>Change 11.9.5 [<A href="https://wg21.link/class.cdtor#4">class.cdtor</A>] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

...If the virtual function call uses an explicit class member access
(5.2.5) and the <DEL>object-expression</DEL> <INS>object
expression</INS> refers to the object under construction...

</BLOCKQUOTE>

<LI><P>Change 13.3 [<A href="https://wg21.link/temp.names#4">temp.names</A>] 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
<DEL>or pointer</DEL> expression of the <I>postfix-expression</I> or...

</BLOCKQUOTE>

</OL>

<P><I>[Note: although the current text of _N4868_.6.5.6 [<A href="https://wg21.link/basic.lookup.classref#7">basic.lookup.classref</A>] paragraph 7
mentions the phrase &#8220;pointer expression,&#8221;
that wording will be replaced by <A HREF="1111.html">issue 1111</A>
or <A HREF="1220.html">issue 1220</A> and is thus not addressed
here.]</I></P>

<BR><BR>
</BODY>
</HTML>
