Topic: Pointer To Member Syntax Rationale


Author: rjl@f111.iassf.easams.com.au (Rohan LENARD)
Date: 1995/07/14
Raw View
Further to my earlier post.

In article <3u1g0a$c66@f111.iassf.easams.com.au>,
Rohan LENARD <rjl@f111.iassf.easams.com.au> wrote:
>
>Hi folks,
>
>The grammar for an assignment-expression seems to preclude doing something
>like this -
>

Olaf Webber correctly pointed out this section of 8.3.3 which contradicts
the grammar (notice the example does exactly what the grammar precludes !!) -

: 8.3.3  Pointers to members                                  [dcl.mptr]
:
: 1 In a declaration T D where D has the form
:           ::opt nested-name-specifier * cv-qualifier-seqopt D1
:   and the nested-name-specifier names a class, and the type of the iden
:   tifier  in  the  declaration T D1 is "derived-declarator-type-list T,"
:   then the type of the identifier of D is  "derived-declarator-type-list
:   cv-qualifier-seq  pointer  to member of class nested-name-specifier of
:   type T."
:
: 2 [Example:
:           class X {
:           public:
:               void f(int);
:               int a;
:           };
:           class Y;
:
:           int X::* pmi = &X::a;
:           void (X::* pmf)(int) = &X::f;
:           double X::* pmd;
:           char Y::* pmc;
:   declares pmi, pmf, pmd and pmc to be a pointer to a  member  of  X  of
:   type int, a pointer to a member of X of type void(int), a pointer to a
:   member of X of type double and a pointer to a member of Y of type char
:   respectively.  The declaration of pmd is well-formed even though X has
:   no members of type double.  Similarly, the declaration of pmc is well-
:   formed  even  though Y is an incomplete type.  pmi and pmf can be used
:   like this:
:           X obj;
:           //...
:           obj.*pmi = 7;   // assign 7 to an integer
:                           // member of obj
:           (obj.*pmf)(7);  // call a function member of obj
:                           // with the argument 7
:    --end example]
:
: 3 A pointer to member shall not point to a  static  member  of  a  class
:   (_class.static_),  a  member with reference type, or "cv void." [Note:
:   There  is  no   "reference-to-member"   type   in   C++.    See   also
:   _expr.mptr.oper_ and _expr.unary_.  ]
:
:

So is this a fault in the standard.  Will someone fix it ?

Regards,
 Rohan
--
----------------------------------------------------------------------------
rjl@iassf.easams.com.au | All quotes can be attributed to my automated quote
Rohan Lenard            | writing tool.  Yours for just $19.95; and if you
+61-2-367-4555          | call now you'll get a free set of steak knives ...





Author: rjl@f111.iassf.easams.com.au (Rohan LENARD)
Date: 1995/07/13
Raw View
Hi folks,

The grammar for an assignment-expression seems to preclude doing something
like this -

struct T {
int a;
};

T AnObj;

main()
{
  int T::* pMem = &T::a;

  AnObj.*pMem = 10; // Error ?
  (AnObj.*pMem) = 10; // Ok
}


Can anyone explain the rationale, or is it just *too* difficult to put into
the grammar ?

Every compiler I've used allows the line marked // Error ?.  Do they all have
a defect in this regard ?  This seems really strange as the grammar hasn't
changed significantly since the ARM was released in this area.


Regards,
 Rohan
------------------------------------------------------------------------
(Attached is assignment-expression grammar).

          assignment-expression:
                  conditional-expression
                  unary-expression assignment-operator assignment-expression
                  throw-expression

          unary-expression:
                  postfix-expression
                  ++  unary-expression
                  --  unary-expression
                  unary-operator cast-expression
                  sizeof unary-expression
                  sizeof ( type-id )
                  new-expression
                  delete-expression

          postfix-expression:
                  primary-expression
                  postfix-expression [ expression ]
                  postfix-expression ( expression-listopt )
                  simple-type-specifier ( expression-listopt )
                  postfix-expression . templateopt id-expression
                  postfix-expression -> templateopt id-expression
                  postfix-expression ++
                  postfix-expression --
                  dynamic_cast < type-id > ( expression )
                  static_cast < type-id > ( expression )
                  reinterpret_cast < type-id > ( expression )
                  const_cast < type-id > ( expression )
                  typeid ( expression )
                  typeid ( type-id )

           primary-expression:
                  literal
                  this
                  :: identifier
                  :: operator-function-id
                  :: qualified-id
                  ( expression )
                  id-expression


--
----------------------------------------------------------------------------
rjl@iassf.easams.com.au | All quotes can be attributed to my automated quote
Rohan Lenard            | writing tool.  Yours for just $19.95; and if you
+61-2-367-4555          | call now you'll get a free set of steak knives ...