Topic: delete a const *
Author: "James Russell Kuyper Jr." <kuyper@wizard.net>
Date: 19 Sep 2002 21:25:07 GMT Raw View
Allan W wrote:
....
> As for the main point of the OP's message, yes, you're supposed to be
> able to delete through a pointer to const, and it shouldn't matter if
> the pointee is a built-in or a class object. I'm pretty sure that
> MSVC6 gets this right -- MSVC5 is very old! -- but as I post this, I
> don't have one convenient to double-check. In the meantime, I'm sure
> that as a temporary workaround you could do this:
>
> const int * p = new int;
> delete (int*)p;
Please change that to:
delete const_cast<int*>(p);
---
[ 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 ]
Author: rmaddox@isicns.com (Randy Maddox)
Date: Wed, 18 Sep 2002 01:49:07 +0000 (UTC) Raw View
pasa@lib.hu ("Balog Pal") wrote in message news:<3d8633a1@andromeda.datanet.hu>...
> AFAIK we had a thread on this, and delete could be used with pointers to const.
> Now I tried to read it from the strandard and got lost.
Looks like a compiler bug to me. Subclause 5.3.5, paragraph 2,
explicitly states that ".. a pointer to a const type can be the
operand of a delete-expression; it is not necessary to cast away the
constness of the pointer expression before it is used as the operand
of the delete-expression". Seems pretty unambiguous. Perhaps a
compiler ugrade is in order?
Randy.
>
> Section 5.3.5 writes about delete and it just defines delete-expression in terms of cast expression, then I found cast expression being unary-expression and unary-expression has quite a list, including delete-expression running a full circle.
>
> The operand is required to be of pointer type, not mentioning cv-qualifiers make me guess those are ignored, so a const pointer is okey. [However I'd expect an explicit statement about that at least as the work will lose a cv qualifier silently.]
>
> What bought me here I just encountered in MSVC5:
>
> 1 const int * pI = new int;
> 2 delete pI;
> 3 const CDialog * pD = new CDialog;
> 4 delete pD;
>
> Line 2 gives
> error C2664: 'delete' : cannot convert parameter 1 from 'const int *' to 'void *'
> and line 4 compiles.
>
> The difference is that CDialog is descendant of CObject and CObject has its own set of operator new and operator delete.
>
> The error message suggests it tries to convert the pointer to void * -- likely to pass to operator delete(void *).
>
> Then it happens to succeed with CObject's one but not with the stock funtion. weird.
>
> Is this a plain compiler bug, or I'm missing something? And what would be the correct behavior then, compile both as I thought or reject both?
>
> Paul
>
> ---
> [ 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 ]
---
[ 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 ]
Author: musiphil@bawi.org (Sungbom Kim)
Date: Wed, 18 Sep 2002 04:28:33 +0000 (UTC) Raw View
"Alf P. Steinbach" wrote:
>
> On Mon, 16 Sep 2002 21:01:24 +0000 (UTC), pasa@lib.hu ("Balog Pal")
> wrote:
>
> >...
> >What bought me here I just encountered in MSVC5:
> >
> >1 const int * pI = new int;
> >2 delete pI;
> >3 const CDialog * pD = new CDialog;
> >4 delete pD;
> >
> >Line 2 gives
> > error C2664: 'delete' : cannot convert parameter 1 from 'const int *' to 'void *'
> >and line 4 compiles.
> >
> >The difference is that CDialog is descendant of CObject and CObject has its own set of operator new and operator delete.
>
> The compiler is correct.
No, it's not.
> Note that the pointer itself can be const (at least, I believe it
> can, haven't checked) but the object pointed to cannot. One reason
> is that delete calls the destructor, which certainly modifies the
> object, and might call non-const methods; doesn't matter that that
> object ceases to exist right after, constness must be preserved.
It is perfectly legal to apply delete to a pointer to a const object.
There was a long debate in this group whether it _should_ be so or not
<http://groups.google.com/groups?threadm=37008962.CA6238A2%40mcd.alcatel.be>
, but anyway the fact is that it _is_ legal now.
Destructors are not normal member functions, and they are not
restrained of their actions by constness. The same as in { const X x; }
or in { std::auto_ptr<const X> px; } constness of the objects does not
(and should not, I think) prevent them from being destroyed.
Modification is something done to an object while it exists,
and destruction is making it exist no more.
The distinction is clear, I think.
--
Sungbom Kim <musiphil@bawi.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Wed, 18 Sep 2002 16:16:13 +0000 (UTC) Raw View
In article <3D87DA27.6877B2D9@bawi.org>, Sungbom Kim <musiphil@bawi.org>
writes
>Modification is something done to an object while it exists,
>and destruction is making it exist no more.
>The distinction is clear, I think.
And technically the object has ceased to exist at the point at which the
dtor is entered.
--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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 ]
Author: Allan_W@my-dejanews.com (Allan W)
Date: Wed, 18 Sep 2002 19:01:56 +0000 (UTC) Raw View
kuyper@wizard.net ("James Russell Kuyper Jr.") wrote
> Balog Pal wrote:
> >
> > AFAIK we had a thread on this, and delete could be used with
> > pointers to const. Now I tried to read it from the strandard and
> > got lost.
> >
> > Section 5.3.5 writes about delete and it just defines
> > delete-expression in terms of cast expression, then I found cast
> > expression being unary-expression and unary-expression has quite
> > a list, including delete-expression running a full circle.
>
> The grammar doesn't cover everything. A delete expression is a
> unary-expression, and is therefore a cast-expression, which means that
> it can be parsed as the operand of another delete expression. However,
> "the operand shall have a pointer type, or a class type having a single
> conversion function (12.3.2) to a pointer type". Since "the result has
> type void.", one delete expression is never legal as the operand of
> another delete expression.
Right.
If you don't mind getting lynched in a code review, you could write
this:
delete (delete a),b
Here, (delete a) returns void, the comma operator returns b, and the
outer operator delete works on b.
As for the main point of the OP's message, yes, you're supposed to be
able to delete through a pointer to const, and it shouldn't matter if
the pointee is a built-in or a class object. I'm pretty sure that
MSVC6 gets this right -- MSVC5 is very old! -- but as I post this, I
don't have one convenient to double-check. In the meantime, I'm sure
that as a temporary workaround you could do this:
const int * p = new int;
delete (int*)p;
This should also work correctly on newer compilers, although you'll
want to remove it as soon as the need is gone -- casts are always
ugly, but doubly so in delete expressions.
---
[ 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 ]
Author: alf_p_steinbach@yahoo.no.invalid (Alf P. Steinbach)
Date: Wed, 18 Sep 2002 22:56:48 +0000 (UTC) Raw View
Boolean inversion at work.
Everything is exactly opposite of what I wrote.
'Nuff said.
With apologies,
- Alf
(Who has obviously used that particular compiler too long...)
On Tue, 17 Sep 2002 23:04:25 +0000 (UTC), alf_p_steinbach@yahoo.no.invalid (Alf P.
Steinbach) wrote:
>On Mon, 16 Sep 2002 21:01:24 +0000 (UTC), pasa@lib.hu ("Balog Pal")
>wrote:
>
>>...
>>What bought me here I just encountered in MSVC5:
>>
>>1 const int * pI = new int;
>>2 delete pI;
>>3 const CDialog * pD = new CDialog;
>>4 delete pD;
>>
>>Line 2 gives
>> error C2664: 'delete' : cannot convert parameter 1 from 'const int *' to 'void *'
>>and line 4 compiles.
>>
>>The difference is that CDialog is descendant of CObject and CObject has its own set of operator new and operator delete.
>
>The compiler is correct.
>
>Use a const_cast for the delete, if you must.
>
>Note that the pointer itself can be const (at least, I believe it
>can, haven't checked) but the object pointed to cannot. One reason
>is that delete calls the destructor, which certainly modifies the
>object, and might call non-const methods; doesn't matter that that
>object ceases to exist right after, constness must be preserved.
>
>Hth.,
>
>- Alf
>
>PS: I think you'll find the relevant section in the standard by
>looking at delete.
---
[ 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 ]
Author: pasa@lib.hu ("Balog Pal")
Date: Mon, 16 Sep 2002 21:01:24 +0000 (UTC) Raw View
AFAIK we had a thread on this, and delete could be used with pointers to const.
Now I tried to read it from the strandard and got lost.
Section 5.3.5 writes about delete and it just defines delete-expression in terms of cast expression, then I found cast expression being unary-expression and unary-expression has quite a list, including delete-expression running a full circle.
The operand is required to be of pointer type, not mentioning cv-qualifiers make me guess those are ignored, so a const pointer is okey. [However I'd expect an explicit statement about that at least as the work will lose a cv qualifier silently.]
What bought me here I just encountered in MSVC5:
1 const int * pI = new int;
2 delete pI;
3 const CDialog * pD = new CDialog;
4 delete pD;
Line 2 gives
error C2664: 'delete' : cannot convert parameter 1 from 'const int *' to 'void *'
and line 4 compiles.
The difference is that CDialog is descendant of CObject and CObject has its own set of operator new and operator delete.
The error message suggests it tries to convert the pointer to void * -- likely to pass to operator delete(void *).
Then it happens to succeed with CObject's one but not with the stock funtion. weird.
Is this a plain compiler bug, or I'm missing something? And what would be the correct behavior then, compile both as I thought or reject both?
Paul
---
[ 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 ]
Author: kuyper@wizard.net ("James Russell Kuyper Jr.")
Date: Tue, 17 Sep 2002 12:02:19 +0000 (UTC) Raw View
Balog Pal wrote:
>
> AFAIK we had a thread on this, and delete could be used with pointers to const.
> Now I tried to read it from the strandard and got lost.
>
> Section 5.3.5 writes about delete and it just defines delete-expression in terms of cast expression, then I found cast expression being unary-expression and unary-expression has quite a list, including delete-expression running a full circle.
The grammar doesn't cover everything. A delete expression is a
unary-expression, and is therefore a cast-expression, which means that
it can be parsed as the operand of another delete expression. However,
"the operand shall have a pointer type, or a class type having a single
conversion function (12.3.2) to a pointer type". Since "the result has
type void.", one delete expression is never legal as the operand of
another delete expression.
The fact that a pointer to a const type is legal, is derived mainly from
the negative fact that it never says that the pointer must point to a
non-const type. However, it's easy to miss something like that, so the
writers of the standard have helped us out by providing a note at the
end of that same paragraph: "_Note:_ a pointer to a const type can be
the operand of a _delete-expression_; it is not necessary to cast away
the constness (5.2.11) of the pointer expression before it is used as
the operand of the _delete-expression_."
---
[ 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 ]
Author: alf_p_steinbach@yahoo.no.invalid (Alf P. Steinbach)
Date: Tue, 17 Sep 2002 23:04:25 +0000 (UTC) Raw View
On Mon, 16 Sep 2002 21:01:24 +0000 (UTC), pasa@lib.hu ("Balog Pal")
wrote:
>...
>What bought me here I just encountered in MSVC5:
>
>1 const int * pI = new int;
>2 delete pI;
>3 const CDialog * pD = new CDialog;
>4 delete pD;
>
>Line 2 gives
> error C2664: 'delete' : cannot convert parameter 1 from 'const int *' to 'void *'
>and line 4 compiles.
>
>The difference is that CDialog is descendant of CObject and CObject has its own set of operator new and operator delete.
The compiler is correct.
Use a const_cast for the delete, if you must.
Note that the pointer itself can be const (at least, I believe it
can, haven't checked) but the object pointed to cannot. One reason
is that delete calls the destructor, which certainly modifies the
object, and might call non-const methods; doesn't matter that that
object ceases to exist right after, constness must be preserved.
Hth.,
- Alf
PS: I think you'll find the relevant section in the standard by
looking at delete.
---
[ 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 ]
Author: pasa@lib.hu ("Balog Pal")
Date: Tue, 17 Sep 2002 23:10:22 +0000 (UTC) Raw View
""Balog Pal"" <pasa@lib.hu> wrote in message news:3d8633a1@andromeda.datanet.hu...
> The operand is required to be of pointer type, not mentioning cv-qualifiers
> make me guess those are ignored, so a const pointer is okey.
> [However I'd expect an explicit statement about that at least as the
> work will lose a cv qualifier silently.]
BAH. As James pointed out the note is right where I was looking for it, I still managed to mislook. :-( Well.
> What bought me here I just encountered in MSVC5:
>
> 1 const int * pI = new int;
> 2 delete pI;
> 3 const CDialog * pD = new CDialog;
> 4 delete pD;
>
> Line 2 gives
> error C2664: 'delete' : cannot convert parameter 1 from 'const int *' to 'void *'
> and line 4 compiles.
>
> The difference is that CDialog is descendant of CObject and
> CObject has its own set of operator new and operator delete.
The bug appears even more subtle. It does not delend on presence of operator delete as I thought. It compiles with a class which has a dtor explicitly defined, and fails for stuff without dtor (one generated by the compiler).
Thanks everyone.
Paul
---
[ 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 ]