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 ]