Topic: Question about address-of-member syntax


Author: "Chris Uppal" <chris.uppal@ait.REMOVE-THIS.co.uk>
Date: 1997/12/09
Raw View
Given:

struct Class
{
   void method(int i) { }

   void other()
   {
      typedef void (Class::*MPTR)(int);

      MPTR mptr1 = &Class::method; // 1
      MPTR mptr2 = Class::method; // 2 -- can we drop the '&' ?
      MPTR mptr3 = &method;  // 3 -- can we rely on scope ?
      MPTR mptr4 = method;  // 4 -- can we do both ?
  }
};

Which of the four syntax's for taking the address of
Class::method(int) are legal ?

The (draft) standard *seems* to be saying that only version 4 is OK,
but logic and consistency (poor guides I know) seem to require that
the others should also be OK in context.  All the examples in the
draft use the fully qualified syntax, but then the member they take
the address of is never in scope, and there's only one example of
taking the address of a method.

FWIW: I came across this as a difference between MSVC4.2 and Borland
5 -- MS allows everything except (3), Borland will only allow (1).
What's a little more interesting than just a difference between
vendors, is that in each of the cases where either compiler "fails"
it does so with a message that suggests it is actually falling over
somewhere in the type checker rather than just refusing illegal code.

 -- chris
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Pete Becker <petebecker@acm.org>
Date: 1997/12/10
Raw View
Chris Uppal wrote:
>
> Given:
>
> struct Class
> {
>    void method(int i) { }
>
>    void other()
>    {
>       typedef void (Class::*MPTR)(int);
>
>       MPTR mptr1 = &Class::method;      // 1
>       MPTR mptr2 = Class::method;       // 2 -- can we drop the '&' ?
No, this is illegal.

>       MPTR mptr3 = &method;             // 3 -- can we rely on scope ?
No, this is illegal.

>       MPTR mptr4 = method;              // 4 -- can we do both ?
No, this is illegal.

>   }
> };
>
> Which of the four syntax's for taking the address of
> Class::method(int) are legal ?
>
> The (draft) standard *seems* to be saying that only version 4 is OK,
No, only version 1 is OK.

>
> FWIW: I came across this as a difference between MSVC4.2 and Borland
> 5 -- MS allows everything except (3), Borland will only allow (1).

Yes, MS is very sloppy here, always has been.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: bill@gibbons.org (Bill Gibbons)
Date: 1997/12/10
Raw View
In article <01bd03dc$b3b4c920$4494dfc2@cuppal-pc>, "Chris Uppal"
<chris.uppal@ait.REMOVE-THIS.co.uk> wrote:

> Given:
>
> struct Class
> {
>    void method(int i) { }
>
>    void other()
>    {
>       typedef void (Class::*MPTR)(int);
>
>       MPTR mptr1 = &Class::method;      // 1
>       MPTR mptr2 = Class::method;       // 2 -- can we drop the '&' ?
>       MPTR mptr3 = &method;             // 3 -- can we rely on scope ?
>       MPTR mptr4 = method;              // 4 -- can we do both ?
>   }
> };
>
> Which of the four syntax's for taking the address of
> Class::method(int) are legal ?
>
> The (draft) standard *seems* to be saying that only version 4 is OK,
> but logic and consistency (poor guides I know) seem to require that
> the others should also be OK in context.  All the examples in the
> draft use the fully qualified syntax, but then the member they take
> the address of is never in scope, and there's only one example of
> taking the address of a method.
>
> FWIW: I came across this as a difference between MSVC4.2 and Borland
> 5 -- MS allows everything except (3), Borland will only allow (1).
> What's a little more interesting than just a difference between
> vendors, is that in each of the cases where either compiler "fails"
> it does so with a message that suggests it is actually falling over
> somewhere in the type checker rather than just refusing illegal code.

The committee made an explicit decision on this issue and the draft
is now very clear (only #1 is valid).  From 5.3.1 paragraph 3:

  A pointer to member is only formed when an explicit & is used and its
  operand is a qualified-id not enclosed in parentheses.

This was strongly implied in the ARM but was not as explicit as it is
in the draft.

Some compilers accept incorrect forms; in particular, Microsoft not only
accepts incorrect forms but uses them in MFC, even though they are not
needed there.  (I've done the excercise of modifying MFC to use correct
pointers to members; it isn't that hard.)


Note that compilers which accept simpler forms have to be inconsistent
about pointers to data members:

    struct A {
        void f();
        int x;
        void g();
    };

    void A::g() {
        &f;  // ill-formed, but could be treated as PM as an extension
        &x;  // must be the same as "&this->x", NOT pointer to member
    }

This is one reason the draft requires the more elaborate form.


Also note that a pointer to a static member is an ordinary pointer,
so the validity of "&f" depends on whether "f" is a static member.
When "f" is an overload set, this depends on the context:

    struct A {
        void f(int);
        static void f(long);
        void g();
    };

    void A::g() {
        void (A::*pf1)(int) = &f;  // ill-formed
        void (*pf2)(long)   = &f;  // well-formed
    }

This situation would be vanishingly rare in practice, but the draft does
cover it.


-- Bill Gibbons
   bill@gibbons.org
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]