Topic: Delete (void *)p;


Author: llewelly.at@xmission.dot.com
Date: Wed, 24 Sep 2003 15:22:23 +0000 (UTC)
Raw View
wolof@freemail.hu ("WW") writes:

> Hello,
>
> In the standard 5.3.5 there seem to be some (lot for my taste) compile time
> detectable errors which are simply deemed to be undefine behavior.  One of
> those, which is IMHO very easy to detect, is delete-ing a void pointer.
>
> I wonder why wasn't it defined as ill-formed?  It can be detected compile
> time and if one reads the text it is clear that it will always be undefined
> behavior.
>
> IMHO removing undefined behavior from the standard by making it defined
> helps all of us.  Especially if it is as simple as this case.  Why do I say
> that?  Because currently (up to my understanding) this is A OK and will
> compile, but go bananas runtime:
>
> delete std::cout;

It is not quite as simple as that. Deleting a pointer to NULL has
    well-defined behavior; no effect. So if cout.fail() is true,
    this is well-defined. :-)


Now the question becomes, is there any use, real or imagined, for
    passing a NULL void* to delete? Does the cost of breaking such
    uses outweigh the cost of undefined behavior when deleting any
    non-null void* ? I doubt it.

>
> I know this is silly, but when it happens it will happen in a much more
> subtle way, with a typo of some sort or in complex code by mistake.  And
> that mistake compilers could identify.
>
> Could someone tell me what was the rationale to make that void * case only a
> non-normative comment (saying that it is always undefined) and not making it
> ill-formed?  I also wonder why isn't there a DR on this issue...

I see no normative or non-normative text which implies passing a pointer
    to void to delete is always undefined. I *do* see footnote 73,
    which says:

#   This implies an object cannot be deleted using a pointer of type
#   void* because there are no objects of type void.

    which is very close to what you were thinking, except for NULL
    pointers and the rules given for deleting them in 5.3.5/2 .

---
[ 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: wolof@freemail.hu ("WW")
Date: Thu, 25 Sep 2003 02:18:29 +0000 (UTC)
Raw View
llewelly.at@xmission.dot.com wrote:
[SNIP]
>> delete std::cout;
>
> It is not quite as simple as that. Deleting a pointer to NULL has
>     well-defined behavior; no effect. So if cout.fail() is true,
>     this is well-defined. :-)

Not as I understand the standard.  The standard talks about the pointers
static type and it states (as an explanation or reinforcement) in a footnote
that deleting void is always illegal (u/b).

> Now the question becomes, is there any use, real or imagined, for
>     passing a NULL void* to delete? Does the cost of breaking such
>     uses outweigh the cost of undefined behavior when deleting any
>     non-null void* ? I doubt it.

I don't think it is legal today.

>> I know this is silly, but when it happens it will happen in a much
>> more subtle way, with a typo of some sort or in complex code by
>> mistake.  And that mistake compilers could identify.
>>
>> Could someone tell me what was the rationale to make that void *
>> case only a non-normative comment (saying that it is always
>> undefined) and not making it ill-formed?  I also wonder why isn't
>> there a DR on this issue...
>
> I see no normative or non-normative text which implies passing a
>     pointer to void to delete is always undefined. I *do* see
>     footnote 73, which says:
>
> #   This implies an object cannot be deleted using a pointer of type
> #   void* because there are no objects of type void.
>
>     which is very close to what you were thinking, except for NULL
>     pointers and the rules given for deleting them in 5.3.5/2 .

Yeah.  But as I understand it there are two alternatives.  Not three.  Not
any kinda pointer and it is NULL.  So there are two cases.  In either case
if the pointer is NULL nothing happens.  Then it defines what pointer types
can used with each of the two alternatives.  The void * is not there.  And
as it seems the desingers of g++ agree with me, since they give a warning if
you try to delete void *.

--
WW aka Attila


---
[ 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: Thu, 25 Sep 2003 02:19:05 +0000 (UTC)
Raw View
<llewelly.at@xmission.dot.com> wrote in message
news:86oexb60eb.fsf@mushroom.brsssget...

> #   This implies an object cannot be deleted using a pointer of type
> #   void* because there are no objects of type void.
>
>     which is very close to what you were thinking, except for NULL
>     pointers and the rules given for deleting them in 5.3.5/2 .

Hm, that is really interesting. Which of the rules take precedence here? I
thougt delete (void*) 0; would be UB and not a defined no-op.   Could
someone explain?

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: brangdon@cix.co.uk (Dave Harris)
Date: Fri, 26 Sep 2003 02:59:22 +0000 (UTC)
Raw View
wolof@freemail.hu ("WW") wrote (abridged):
> > Now the question becomes, is there any use, real or imagined,
> >     for passing a NULL void* to delete? Does the cost of
> >     breaking such uses outweigh the cost of undefined behavior
> >     when deleting any non-null void* ? I doubt it.
>
> I don't think it is legal today.

If it's undefined behaviour, then an implementation is allowed to
define a behaviour for it. For example, it could free memory
without calling destructors.

If it requires a diagnostic, then in practice it can't be given that
meaning, or any other. At least not if we want programs to compile
diagnostic-free.

-- Dave Harris, Nottingham, UK

---
[ 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: rogero@howzatt.demon.co.uk ("Roger Orr")
Date: Fri, 26 Sep 2003 17:29:53 +0000 (UTC)
Raw View
<llewelly.at@xmission.dot.com> wrote in message
news:86oexb60eb.fsf@mushroom.brsssget...
> wolof@freemail.hu ("WW") writes:
>
> > Hello,
> >
> > In the standard 5.3.5 there seem to be some (lot for my taste) compile
time
> > detectable errors which are simply deemed to be undefine behavior.  One
of
> > those, which is IMHO very easy to detect, is delete-ing a void pointer.
> >
> > I wonder why wasn't it defined as ill-formed?  It can be detected
compile
> > time and if one reads the text it is clear that it will always be
undefined
> > behavior.
> >
> > IMHO removing undefined behavior from the standard by making it defined
> > helps all of us.  Especially if it is as simple as this case.  Why do I
say
> > that?  Because currently (up to my understanding) this is A OK and will
> > compile, but go bananas runtime:
> >
> > delete std::cout;
>
> It is not quite as simple as that. Deleting a pointer to NULL has
>     well-defined behavior; no effect. So if cout.fail() is true,
>     this is well-defined. :-)

True, but it is rather fragile code.

>
> Now the question becomes, is there any use, real or imagined, for
>     passing a NULL void* to delete?

I think the actual question is: are there any uses for code passing a void*
to delete where the pointer is _always_ going to be null at runtime.

> Does the cost of breaking such
>     uses outweigh the cost of undefined behavior when deleting any
>     non-null void* ? I doubt it.

My problem is not with breaking this sort of use, but where people have used
'delete pVoid'.
I've seen quite a lot of code where people are allocating memory to
different sorts of POD data like this:-

char * pChar = new char[ n ];
int *pInt = new int[ m ];

and then freeing the memory by calling a method like:-

void tidy( void *buffer )
{
    delete buffer;
}

I know this code is bad and not guaranteed to be portable - mismatched new[]
and delete is dangerous in general.
However this code _does_ work in practice on at least one very common
implementation.

If delete of a void* was made illegal code like this would fail to compile.
You might think this would be a good thing :-) but people always seem
unhappy when code stops compiling.

Roger Orr
--
MVP in C++ at www.brainbench.com


---
[ 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: wolof@freemail.hu ("WW")
Date: Fri, 26 Sep 2003 17:34:51 +0000 (UTC)
Raw View
Dave Harris wrote:
> wolof@freemail.hu ("WW") wrote (abridged):
>>> Now the question becomes, is there any use, real or imagined,
>>>     for passing a NULL void* to delete? Does the cost of
>>>     breaking such uses outweigh the cost of undefined behavior
>>>     when deleting any non-null void* ? I doubt it.
>>
>> I don't think it is legal today.
>
> If it's undefined behaviour, then an implementation is allowed to
> define a behaviour for it. For example, it could free memory
> without calling destructors.
>
> If it requires a diagnostic, then in practice it can't be given that
> meaning, or any other. At least not if we want programs to compile
> diagnostic-free.

I still think it is a big mistake.  Using void * to make a pseudo
operator-bool makes all classes to be delete-able.  Including smart
pointers.  I think the price to pay for this undefined behavior is too high.
And I think that if an implementation wants to define delete with no
destructors it can just as easily use char *.

--
WW aka Attila


---
[ 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: wolof@freemail.hu ("WW")
Date: Sat, 27 Sep 2003 01:19:04 +0000 (UTC)
Raw View
"Roger Orr" wrote:
[SNIP]
> I know this code is bad and not guaranteed to be portable -
> mismatched new[] and delete is dangerous in general.
> However this code _does_ work in practice on at least one very common
> implementation.
>
> If delete of a void* was made illegal code like this would fail to
> compile. You might think this would be a good thing :-) but people
> always seem unhappy when code stops compiling.

That kind of code deserves to be broken.

--
WW aka Attila


---
[ 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: brangdon@cix.co.uk (Dave Harris)
Date: Mon, 29 Sep 2003 05:07:56 +0000 (UTC)
Raw View
wolof@freemail.hu ("WW") wrote (abridged):
> I still think it is a big mistake.  Using void * to make a pseudo
> operator-bool makes all classes to be delete-able.  Including smart
> pointers.

Don't do that, then. Use some other type of pointer, eg
pointer-to-member.


> And I think that if an implementation wants to define delete with
> no destructors it can just as easily use char *.

Void * has some useful properties which char * lacks.

What we really need is some kind of "byte *" type, convertible like
void * but supporting pointer arithmetic. Then delete would make
more sense.

-- Dave Harris, Nottingham, UK

---
[ 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: dheld@codelogicconsulting.com ("David B. Held")
Date: Mon, 29 Sep 2003 05:12:52 +0000 (UTC)
Raw View
""WW"" <wolof@freemail.hu> wrote in message
news:bl0c4d$gl$1@phys-news1.kolumbus.fi...
> [...]
> I still think it is a big mistake.  Using void * to make a pseudo
> operator-bool makes all classes to be delete-able.  Including
> smart pointers.
> [...]

That's why the preferred idiom doesn't use void*.  There are plenty
of convertible-to-bool types that are not deletable (like any pointer-
to-member[-function] type) or convertible to int.

Dave


---
[ 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: ron@sensor.com ("Ron Natalie")
Date: Mon, 29 Sep 2003 05:15:29 +0000 (UTC)
Raw View
""WW"" <wolof@freemail.hu> wrote in message news:bl1tfv$io2$1@phys-news1.kolumbus.fi...

> > If delete of a void* was made illegal code like this would fail to
> > compile. You might think this would be a good thing :-) but people
> > always seem unhappy when code stops compiling.
>
> That kind of code deserves to be broken.

One thing you might also do as a QOI issue is have the "operator void*" return some
other pointer than the internal one of the auto_ptr.   For example:

struct _InternalHowler {
    ~_InternalHowler() {
        instance = new _internalHowler; // restore singleton.
        ShootProgrammerInTheKneeCap();

    }
    static _InternalHowler* instance;
};

_InternalHowler* _InternalHowler::instance = new _InternalHowler;

auto_ptr::operator void*() {
    if(get()) return _InternalHowler::instance;
    else return 0;
}

That way, at least deleting an auto_ptr wouldn't hose the class.


---
[ 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: philippe_mori@hotmail.com ("Philippe Mori")
Date: Mon, 29 Sep 2003 17:03:14 +0000 (UTC)
Raw View
>
> I still think it is a big mistake.  Using void * to make a pseudo
> operator-bool makes all classes to be delete-able.  Including smart
> pointers.  I think the price to pay for this undefined behavior is too
high.
> And I think that if an implementation wants to define delete with no
> destructors it can just as easily use char *.
>
> --
> WW aka Attila
>
>

Well if alomst anytime a class define a conversion to a pointer
it is unsafe to delete it... but this is not work that deleting any
other pointers we should not (and in C++ there are a lot of
them...) so this would make the language just a bit safer in an
area where there are tons of possible errors without counting
double delete, delete[] vs delete and deleting sub-object or
object on the stack...

In one case, it is usefull that the compiler give a warning, it
is when deleting an incomplet type... This is an error that
can easily occurs in we do not include the proper file
and we do not otherwise need the definition...

In some case like template, one should add a static_cast
to ensure the type is known:

static_cast<T *>(p);
delete p;


The best recommendation is to uses a safe automatic
pointer class and almost never uses 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: tony.xt.oliver@ericsson.com (Tony Oliver)
Date: Thu, 2 Oct 2003 22:14:01 +0000 (UTC)
Raw View
rogero@howzatt.demon.co.uk ("Roger Orr") wrote in message news:<bkt9cv$gar$1$8302bc10@news.demon.co.uk>...
> I've seen quite a lot of code where people are allocating memory to
> different sorts of POD data like this:-
>
> char * pChar = new char[ n ];
> int *pInt = new int[ m ];
>
> and then freeing the memory by calling a method like:-
>
> void tidy( void *buffer )
> {
>     delete buffer;
> }
>
> I know this code is bad and not guaranteed to be portable - mismatched new[]
> and delete is dangerous in general.
> However this code _does_ work in practice on at least one very common
> implementation.
>
> If delete of a void* was made illegal code like this would fail to compile.
> You might think this would be a good thing :-) but people always seem
> unhappy when code stops compiling.

I also think it would be a Good Thing :-)

What's more, it could easily be "fixed" using a template function:

    template<typename ValueT>
    inline
    void tidy (ValueT* buffer)
    {
        delete[] buffer;
    }

Assuming the original tidy() function to have been declared in one
header and implemented in one source file, you could satisfy all
tidy() client code by replacing its header-file declaration with the
template-function definition given above, and deleting the old
implementation in its source file.  Two quick code changes and all
should compile again.

For what it's worth, I believe that delete (void*) has no reasonable
semantic meaning and should be disallowed by the language.  The
side-discussion about deleting null pointers should be clarified by
(a) explicitly disallowing delete (void*) and (b) saying something to
the effect that the delete operation, when applied to a
pointer-TO-NON-VOID whose value is zero, behaves as a no-op.

TonyO.

---
[ 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: wolof@freemail.hu ("WW")
Date: Tue, 23 Sep 2003 05:38:45 +0000 (UTC)
Raw View
Hello,

In the standard 5.3.5 there seem to be some (lot for my taste) compile time
detectable errors which are simply deemed to be undefine behavior.  One of
those, which is IMHO very easy to detect, is delete-ing a void pointer.

I wonder why wasn't it defined as ill-formed?  It can be detected compile
time and if one reads the text it is clear that it will always be undefined
behavior.

IMHO removing undefined behavior from the standard by making it defined
helps all of us.  Especially if it is as simple as this case.  Why do I say
that?  Because currently (up to my understanding) this is A OK and will
compile, but go bananas runtime:

delete std::cout;

I know this is silly, but when it happens it will happen in a much more
subtle way, with a typo of some sort or in complex code by mistake.  And
that mistake compilers could identify.

Could someone tell me what was the rationale to make that void * case only a
non-normative comment (saying that it is always undefined) and not making it
ill-formed?  I also wonder why isn't there a DR on this issue...

--
WW aka Attila


---
[ 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                       ]