Topic: Suggested Changes for delete operators.


Author: "rich_sposato" <rds@richsposato.com>
Date: Thu, 18 Aug 2005 08:37:23 CST
Raw View
Yongwei,

What you say makes sense if you consider *all* the new and delete
operators - except the usual forms - as placement new and delete
operators.  And the terminology of Section 5.3.4 does suggest that.

However, I define "placement new and delete" as shown in Section
18.4.1.3 [lib.new.delete.placement].  That section refers to certain
specific forms of new and delete as placement forms, and no others.
Indeed, the term "placement" is not used for any other new or delete
functions mentioned in all the other parts of Section 18.4.  (Although
somebody could claim that Section 18 is about the Standard Library and
not about the core of the language, I would say that's so.  But, it
does list many of the behaviors of each of the global new and delete
operators - including some behaviors not mentioned in sections 3.7.3.
5.3.4. 5.3.5 or 12.5.)

Apparently, there is some ambiguity in the standard as to whether the
word placement refers to certain specific signatures of new and delete,
or to any new and delete functions except the usual ones.

Cheers,

Rich Sposato

---
[ 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
Date: Thu, 18 Aug 2005 17:43:47 CST
Raw View
rich_sposato wrote:
> Yongwei,
>
> What you say makes sense if you consider *all* the new and delete
> operators - except the usual forms - as placement new and delete
> operators.  And the terminology of Section 5.3.4 does suggest that.
>
> However, I define "placement new and delete" as shown in Section
> 18.4.1.3 [lib.new.delete.placement].  That section refers to certain
> specific forms of new and delete as placement forms, and no others.


You don't get to define what "placement new and delete" means. That's
something for the standard to define, which it does in section 5.3.4.
What's defined in section 18.4.1.3 are specific placement new and
delete functions that are provided by the standard library, but those
aren't the only functions that qualify as placement allocation
functions.

---
[ 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: "Wu Yongwei" <wuyongwei@gmail.com>
Date: Fri, 19 Aug 2005 09:42:27 CST
Raw View
rich_sposato wrote:
> Yongwei,
>
> What you say makes sense if you consider *all* the new and delete
> operators - except the usual forms - as placement new and delete
> operators.  And the terminology of Section 5.3.4 does suggest that.
>
> However, I define "placement new and delete" as shown in Section
> 18.4.1.3 [lib.new.delete.placement].  That section refers to certain
> specific forms of new and delete as placement forms, and no others.
> Indeed, the term "placement" is not used for any other new or delete
> functions mentioned in all the other parts of Section 18.4.  (Although
> somebody could claim that Section 18 is about the Standard Library and
> not about the core of the language, I would say that's so.  But, it
> does list many of the behaviors of each of the global new and delete
> operators - including some behaviors not mentioned in sections 3.7.3.
> 5.3.4. 5.3.5 or 12.5.)
>
> Apparently, there is some ambiguity in the standard as to whether the
> word placement refers to certain specific signatures of new and delete,
> or to any new and delete functions except the usual ones.

I checked 18.4.1, and found the wording a little confusing, esp. that
the nothrow_t form is grouped under Single-object forms instead of
Placement forms.  Please notice it is only `a little', and I do not
think it constitute a defect of the standard.  And right under the
introduction of new(nothrow_t) in 18.4.1.1 the Standard writes:
`Effect: Same as above, except that it is called by a placement version
.'.

So the Standard is consistent in what constitute a placement form or
new-placement.

As to the issue that no `operator delete(void*, size_t, nothrow_t)' is
called in an exception of `new(nothrow) SomeObject', you have more
reasons to argue.  However, since exception is generally considered a
`rare' thing in execution (should not be in the normal
performance-sensitive execution path), the O(N) vs O(1) difference
might not be enough to persuade the committee.  And there are chances
for name collisions: consider the calls to placement deallocation
functions for an `operator new(size_t, const nothrow_t&)' and an
`operator new(size_t, size_t, const nothrow_t&)'.

Best regards,

Yongwei

---
[ 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: Sun, 14 Aug 2005 12:40:47 GMT
Raw View
===================================== MODERATOR'S COMMENT:

Please do not over-quote the orginal message.


===================================== END OF MODERATOR'S COMMENT

"rich_sposato" <rds@richsposato.com> a    crit dans le message de news:
1122704106.579938.165410@z14g2000cwz.googlegroups.com...
> Hi Everyone,
>
> During my work on Loki's Small-Object Allocator, I came across some
> issues in the C++ Standard with regards to the delete and delete []
> operators.  I am proposing 3 small refinements to the C++ Standard.  I
> would like to submit these suggested changes to the ISO C++ Committee,
> and before I do so, I would like your feedback.
>
>
> Here are one-sentence summaries of each proposed change:
>
> 1. A program may not delete an instance of an incomplete type.

I think that most modern compiler will give you a warning for that...

>
> 2. For delete [] operators with a size parameter, require the value to
> be identical to the size passed into the new [] operator.

Well, this one surprise me...

>
> 3. Deprecate the std::nothrow_t forms of the delete and delete []
> operators.
>

Well, I thing a compiler (user) might choose to get the memory in a
different way in such a case so both are required...

>
>
> This URL has more detailed descriptions of all 3 proposed changes:
> http://www.richsposato.com/Cpp_Standard.html
>
>
> If you need further clarification, please let me know.
>
>
> Thanks.
>
> Rich Sposato
>
> ---
> [ 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: "Wu Yongwei" <wuyongwei@gmail.com>
Date: Mon, 15 Aug 2005 01:26:23 CST
Raw View
rich_sposato wrote:
> 1. A program may not delete an instance of an incomplete type.
>
> 2. For delete [] operators with a size parameter, require the value to
> be identical to the size passed into the new [] operator.
>
> 3. Deprecate the std::nothrow_t forms of the delete and delete []
> operators.

Seriously none of them is justified.  You should check the Standard
more carefully.

1) 5.3.5/5: `If the object being deleted has incomplete class type at
the point of deletion and the complete class has a nontrivial
destructor or a deallocation function, the behavior is undefined.'

(It is already undefined behaviour.  And I believe there is a reason
why it is not ill-formed, possibly owing to compatibility with old
code.)

2) Someone else has pointed out that this is already required by the
Standard.

3) I pointed out earlier in the Loki-lib mailing list that nothrow_t is
only one kind of placement parameter of allocation/deallocation
functions.  You might have misunderstood something here.

Best regards,

Yongwei

---
[ 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: "rich_sposato" <rds@richsposato.com>
Date: Tue, 16 Aug 2005 00:12:14 CST
Raw View
Yongwei wrote:
> I pointed out earlier in the Loki-lib mailing list that nothrow_t is
> only one kind of placement parameter of allocation/deallocation
> functions.  You might have misunderstood something here.

I think you are confusing the nothrow_t versions of the new and delete
operators with the placement versions.  The nothrow_t versions of new
and delete are *not* the same as placement new and delete.  The
nothrow_t versions have different function signatures than the
placement versions of these operators.  The placement versions have an
extra void * parameter for the location of the allocated / deallocated
block - but don't have the nothrow_t parameter.  On the other hand, the
nothrow_t versions have the std::nothrow_t & parameter, but don't have
the additional void * placement parameter.


For clarification, the placement versions are:
void * operator new ( std::size_t size, void * ) throw ();
void * operator new [ ] ( std::size_t size, void * ) throw ();
void operator delete ( void * place, void * ) throw ();
void operator delete [ ] ( void * place, void * ) throw ();


And the nothrow versions are:
void * operator new ( std::size_t size, const std::nothrow_t & ) throw
();
void * operator new [] ( std::size_t size, const std::nothrow_t & )
throw ();
void operator delete ( void * place, const std::nothrow_t & nt )
throw();
void operator delete [] ( void * place, const std::nothrow_t & nt )
throw();

---
[ 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: "rich_sposato" <rds@richsposato.com>
Date: Tue, 16 Aug 2005 00:17:16 CST
Raw View
Philippe Mori wrote:

>> 3. Deprecate the std::nothrow_t forms of the delete and delete []
>> operators.

>Well, I thing a compiler (user) might choose to get the memory in a
>different way in such a case so both are required...

I thought that was the reason why, but it can easily be shown that
either the nothrow new or the usual new can be written as a call to the
other.  I can understand if somebody wants to use the nothrow new
operator, since that has different behavior than the usual new
operator.  But the nothrow_t delete operator does not seem to have any
different behavior than then usual delete operator.

As far as I can tell, the nothrow_t delete operator is only called in
one specific situation: when a program calls the nothrow_t new
operator, and a constructor throws an exception.



Anyhow, if the nothrow_t delete operators can't be deprecated, why not
allow them to have a similar property as the usual delete operators.
(Bear with me while I go over some related info for the usual delete
operators.)

Paragraph 3.7.3.2 / 2 says (emphasis mine) "If a class T has a member
deallocation function named operator delete with exactly one parameter,
then that function is a usual (non-placement) deallocation function.
If class T does _not_ declare such an operator delete, but does declare
a member deallocation function named operator delete with exactly two
parameters, the second of which has type std::size_t, then
_this_function_is_a_usual_deallocation_function_.  Similarly, if a
class T has a member deallocation function named operator delete [ ]
with exactly one parameter, then that function is a usual
(non-placement) deallocation function.  If class T does _not_ declare
such an operator delete [ ], but does declare a member deallocation
function named operator delete [ ] with exactly two parameters, the
second of which has type std::size_t, then
_this_function_is_a_usual_deallocation_function_."

In short,  the Standard allows delete operators with a size parameter
to *replace* delete operators without one.  Which is very useful for
people who have to write allocation functions, since the size parameter
can make it easier to check invariants, and efficiently find the
internal bookkeeping for the allocated block.

It seems that only the usual delete operators have the property that
they can be replaced with another delete operator with a size
parameter.

void operator delete ( void * place ) throw ();
Can be replaced by:
void operator delete ( void * place, std::size_t size ) throw ();
(And same with the delete [ ]  operator.)

I would like the Standard to allow a nothrow_t delete operator to have
the same property.  It would be really convenient to me if the compiler
would allow

void operator delete ( void * place, const std::nothrow_t & nt )
throw();
to be replaced by:
void operator delete (
    void * place, std::size_t size, const std::nothrow_t & nt ) throw
();


I find it odd that it allows the replacement for one operator, but not
another.  And if it did, I could change the next version of the Loki
deallocation function to work in constant time instead of linear time.

---
[ 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: "Wu Yongwei" <wuyongwei@gmail.com>
Date: Tue, 16 Aug 2005 08:26:10 CST
Raw View
rich_sposato wrote:
> Yongwei wrote:
> > I pointed out earlier in the Loki-lib mailing list that nothrow_t is
> > only one kind of placement parameter of allocation/deallocation
> > functions.  You might have misunderstood something here.
>
> I think you are confusing the nothrow_t versions of the new and delete
> operators with the placement versions.  The nothrow_t versions of new
> and delete are *not* the same as placement new and delete.  The
> nothrow_t versions have different function signatures than the
> placement versions of these operators.  The placement versions have an
> extra void * parameter for the location of the allocated / deallocated
> block - but don't have the nothrow_t parameter.  On the other hand, the
> nothrow_t versions have the std::nothrow_t & parameter, but don't have
> the additional void * placement parameter.

Check 5.3.4/1:

new-expression:
    ::{opt} new new-placement{opt} new-type-id new-initializer{opt}

new-placement:
    ( expression-list )

And 5.3.4/11:

`The new-placement syntax is used to supply additional arguments to an
allocation function. If used, overload resolution is performed on a
function call created by assembling an argument list consisting of the
amount of space requested (the first argument) and the expressions in
the new-placement
part of the new-expression (the second and succeeding arguments). The
first of these arguments has type size_t and the remaining arguments
have the corresponding types of the expressions in the new-placement.'

Please note that *any* additional argument passed to a new-expression
(new (...) type) makes a placement new, including, of course, `new
(std::nothrow) type'.  The placement parameter does not have to be
`void*'.

The following are some placement allocation functions I have used (just
examples; they cannot be exhaustive):

void* operator new(size_t size, const char* file, int line);
void* operator new(size_t size, const nothrow_t&);
void* operator new(size_t size, void* pointer);

The corresponding new-expressions will be like:

new(__FILE__, __LINE__) Object
new(nothrow) Object
new(buffer) Object

Best regards,

Yongwei

---
[ 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: "rich_sposato" <rds@richsposato.com>
Date: Sat, 30 Jul 2005 14:22:31 CST
Raw View
Hi Everyone,

During my work on Loki's Small-Object Allocator, I came across some
issues in the C++ Standard with regards to the delete and delete []
operators.  I am proposing 3 small refinements to the C++ Standard.  I
would like to submit these suggested changes to the ISO C++ Committee,
and before I do so, I would like your feedback.


Here are one-sentence summaries of each proposed change:

1. A program may not delete an instance of an incomplete type.

2. For delete [] operators with a size parameter, require the value to
be identical to the size passed into the new [] operator.

3. Deprecate the std::nothrow_t forms of the delete and delete []
operators.



This URL has more detailed descriptions of all 3 proposed changes:
http://www.richsposato.com/Cpp_Standard.html


If you need further clarification, please let me know.


Thanks.

Rich Sposato

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