Topic: Defect Report: postfixexpression->scalar_type_dtor() inconsistent (13.5.6 [over.ref])


Author: "Markus Mauhart" <markus.mauhart@nospamm.chello.at>
Date: 08 Jun 03 18:00:27 GMT
Raw View
 [Moderator's note: this defect report has been
 forwarded to the C++ committee. -moderator.]

Lets start with the proposed solution.
In 13.5.6 [over.ref], replace line ...

  postfix-expression -   > id-expression

.... with the lines ...

  postfix-expression    -> template_opt id-expression
  postfix-expression    -> pseudo-destructor-name

(This then is a copy of the two lines in 5.2 [expr.post]
covering "->dtor")
Alternatively remove the sentence "It implements class member
access using -> \n postfix-expression -> id-expression".


-----------------------------------------
Reasons:

Currently stdc++ is inconsistent when handling expressions of
the form "postfixexpression->scalar_type_dtor()":
If "postfixexpression" is a pointer to the scalar type, it is OK,
but if "postfixexpression" referres to any smart pointer class
(e.g. iterator or allocator::pointer) with class specific
CLASS::operator->() returning pointer to the scalar type, then
it is ill-formed; so while c++98 does allow CLASS::operator->()
returning pointer to scalar type, c++98 prohibits any '->'-expression
involving this overloaded operator function.

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:
  c++pl2.r.5.2 -> 5.2 [expr.post]
  c++pl2.r.5.2.4 -> 5.2.4 [expr.pseudo] + 5.2.5 [expr.ref]
  c++pl2.r.13.4 -> 13.3.1.2 [over.match.oper]
  c++pl2.r.13.4.6 -> 13.5.6 [over.ref]
For the single line of c++pl2.r.5.2 covering "->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->()
returning pointer to scalar type has been removed.
Only the single line of c++pl2.r.13.4.6 (<-> c++pl2.r.5.2's
single line) has not gotten its 2nd line when converted
into 13.5.6 [over.ref].

Additionally GCC32 does is right (but against 13.5.6 [over.ref]).

AFAICS this would not break old code except compilers like VC7x
and Comeau4301.

It does not add new functionality, cause any expression
class_type->scalar_type_dtor() even today can be substituted
through (*class_type).scalar_type_dtor().

Without this fix, template functions like some_allocator<T>::destroy(p)
must use "(*p).~T()" or "(*p).T::~T()" when calling the destructor,
otherwise the simpler versions "p->~T()" or "p->T::~T()" could be used.


-----------------------------------------
Sample code, compiled with GCC32, VC7[1] and Comeau4301:

struct A {};//any class

template <class T>
struct PTR
    {
    T& operator*  () const;
    T* operator-> () const;
    };

template <class T>
void f ()
    {
        {
        T*  p               ;
        p = new T           ;
        (*p).T::~T()        ;//OK
        p = new T           ;
        (*p).~T()           ;//OK
        p = new T           ;
        p->T::~T()          ;//OK
        p = new T           ;
        p->~T()             ;//OK
        }

        {
        PTR<T> p = PTR<T>() ;
        (*p).T::~T()        ;//OK
        (*p).~T()           ;//OK
        p.operator->()      ;//OK !!!
        p->T::~T()          ;//GCC32: OK; VC7x,Com4301: OK for A; ERROR w/ int
        p->~T()             ;//GCC32: OK; VC7x,Com4301: OK for A; ERROR w/ int
        }
    }

void test ()
    {
    f <A>  ();
    f <int>();
    }
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]