Name lookup in destructor call
_N4868_.6.5.6 [basic.lookup.classref]
Mark Mitchell

Created on 2001-05-19.00:00:00 last changed 168 months ago


Date: 2006-10-15.00:00:00

[Voted into WP at the October, 2006 meeting.]

Date: 2006-04-15.00:00:00

Proposed resolution (April, 2006):

  1. Remove the indicated text from _N4868_.6.5.6 [basic.lookup.classref] paragraph 2:

    If the id-expression in a class member access ( [expr.ref]) is an unqualified-id, and the type of the object expression is of a class type C (or of pointer to a class type C), the unqualified-id is looked up in the scope of class C...
  2. Change _N4868_.6.5.6 [basic.lookup.classref] paragraph 3 as indicated:

    If the unqualified-id is ~type-name, the type-name is looked up in the context of the entire postfix-expression. and If the type T of the object expression is of a class type C (or of pointer to a class type C), the type-name is also looked up in the context of the entire postfix-expression and in the scope of class C. The type-name shall refer to a class-name. If type-name 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 type-name is looked up in the scope of the complete postfix-expression. At least one of the lookups shall find a name that refers to (possibly cv-qualified) T. [Example:
        struct A { };
        struct B {
          struct A { };
          void f(::A* a);
        void B::f(::A* a) {
          a->~A();  // OK, lookup in *a finds the injected-class-name
    end example]

[Note: this change also resolves issue 414.]

Date: 2021-02-24.00:00:00

I believe this program is invalid:

    struct A {

    struct C {
      struct A {};
      void f ();

    void C::f () {
      ::A *a;
      a->~A ();
The problem is that _N4868_.6.5.6 [basic.lookup.classref] says that you have to look up A in both the context of the pointed-to-type (i.e., ::A), and in the context of the postfix-expression (i.e., the body of C::f), and that if the name is found in both places it must name the same type in both places.

The EDG front end does not issue an error about this program, though.

Am I reading the standardese incorrectly?

John Spicer: 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 -> operator). So I think that if either of the types found matches the one required, it should be sufficient. You can't say a->~::A(), which means you are forced to say a->::A::~A(), which disables the virtual mechanism. So you would have to do something like create a local typedef for the desired type.

See also issues 244, 399, and 466.

Date User Action Args
2008-10-05 00:00:00adminsetstatus: wp -> cd1
2007-05-06 00:00:00adminsetstatus: dr -> wp
2006-11-05 00:00:00adminsetmessages: + msg1428
2006-11-05 00:00:00adminsetstatus: ready -> dr
2006-04-22 00:00:00adminsetstatus: review -> ready
2005-05-01 00:00:00adminsetmessages: + msg1140
2005-05-01 00:00:00adminsetstatus: drafting -> review
2001-11-09 00:00:00adminsetstatus: open -> drafting
2001-05-19 00:00:00admincreate