Topic: Why void* as return type of new?


Author: Gennaro Prota <gennaro_prota@yahoo.com>
Date: Wed, 22 May 2002 20:10:08 GMT
Raw View
On Sat, 18 May 2002 19:35:12 GMT, Francis Glassborow
<francis.glassborow@ntlworld.com> wrote:

[...]
>
>>OtherType * p = (OtherType*) MyClass::operator new (20);
>
>DO NOT even dream of writing that statement.

Of course you're right (and quite convincing I'd say :) )
Anyhow, John's example reminds me one thing that I've always found
disturbing with replacing operator new functions: making them
accessible for new expressions makes them accessible for a direct call
too  (i.e. you can't impose that they can be called, from
non-members/friend, only when evaluating operator new). The case is
different from that of other operators (except delete), because in
those cases the call has the same effect of using the operator.

Note: I can do something like:

   class A {
       void* operator new (std::size_t n) { /*...*/ }
   public:
       static A* construct_new () {
           A* p = new A();
           return p;
       }
   };

but that's not the same thing and anyhow it is not a so wonderful
approach when A has many constructors.


Is there something I'm missing? Was this considered by the commitee?

Genny.

---
[ 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: whatiscpp@yahoo.com (John the newbie)
Date: Fri, 17 May 2002 23:03:34 GMT
Raw View
"AT" writes:

> What Ron said in previous post is true. I just would like slightly expand
> the point.
>
> When you write
>
> CMyClass a = new CMyClass;
>
> you will call new operator (don't confuse it with operator new).
> New call then operator new. And operator new is void* operator new(size_t).
> This is exaclty the thing you are trying to overload in you class and in
> order for new operator to use your overload it should be as it is known to
> new operator.

Yes, the distinction between a new-expression and a function named
"operator new" is clear to me. That's not my point.

>
> Since the new operator is pretty universal thing it is just ask operator new
> to allocate raw memory (in bytes) and then call constructor on this memory.
> Since you don't know what you going allocate next time is not reasonable to
> have operator new to return anything but void.


Here's where I don't agree. What you say is true for the global
operator new functions. But when it comes to class members like in

struct MyClass {
  void * operator new (std::size_t);
};

what's the rationale for having a void*? Yes, there's still the case
in which you make a direct call of the operator function to allocate
objects that are not of type A, like

MyClass::operator new (20);

but is seems to me that this is by far the least common case, and
anyhow, as long as the operator functions returns something that is
properly aligned etc. etc, you could always do a cast like

OtherType * p = (OtherType*) MyClass::operator new (20);

which currently you need anyway for an explicit call (and even to
assign the result to an A*).


The only answer I find plausible here is that it's a choice _as well
reasonable_ as:

A* operator new (std::size_t);

---
[ 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 <francis.glassborow@ntlworld.com>
Date: Sat, 18 May 2002 19:35:12 GMT
Raw View
In article <102a8848.0205171459.459ac210@posting.google.com>, John the
newbie <whatiscpp@yahoo.com> writes
>Here's where I don't agree. What you say is true for the global
>operator new functions. But when it comes to class members like in
>
>struct MyClass {
>  void * operator new (std::size_t);
>};
>
>what's the rationale for having a void*? Yes, there's still the case
>in which you make a direct call of the operator function to allocate
>objects that are not of type A, like
>
>MyClass::operator new (20);
>
>but is seems to me that this is by far the least common case, and
>anyhow, as long as the operator functions returns something that is
>properly aligned etc. etc, you could always do a cast like
>
But allocation functions whether global or at class scope (note that
they cannot be at namespace scope) simply provide raw (untyped) memory,
normally for use by a new expression. That expression expects to handle
raw (untyped) memory which it then uses to form an object.

>OtherType * p = (OtherType*) MyClass::operator new (20);

DO NOT even dream of writing that statement. There is no OtherType
object (or even a MyClass) object to point to. And that is exactly why
the return value from operator new must NOT be of any type other than
void* .


>
>which currently you need anyway for an explicit call (and even to
>assign the result to an A*).
>
>
>The only answer I find plausible here is that it's a choice _as well
>reasonable_ as:
>
>A* operator new (std::size_t);

I consider that to be an entirely unreasonable choice because it
implicitly lies, the returned 'address' is NOT that of an A.


--
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: "Mike Schilling" <mscottschilling@hotmail.com>
Date: Sun, 19 May 2002 23:19:18 GMT
Raw View
"John the newbie" <whatiscpp@yahoo.com> wrote in message
news:102a8848.0205171459.459ac210@posting.google.com...
> "AT" writes:
>
> > What Ron said in previous post is true. I just would like slightly
expand
> > the point.
> >
> > When you write
> >
> > CMyClass a = new CMyClass;
> >
> > you will call new operator (don't confuse it with operator new).
> > New call then operator new. And operator new is void* operator
new(size_t).
> > This is exaclty the thing you are trying to overload in you class and in
> > order for new operator to use your overload it should be as it is known
to
> > new operator.
>
> Yes, the distinction between a new-expression and a function named
> "operator new" is clear to me.

I don't think it is.

There are two steps to constructing a new object:

1.  Find memory in which to construct the object.
2. Run a constructor on this memory.

Step 1 can be done in one of three ways:

    1. For an automatic object, the memory is allocated in space specific to
the block in which the object s defined.  Informally,
    it's allocated on the stack.

    2. For a static object, the memory is allocated as part of program
initiailization.

    3. For a dynamic object, the memory is allocated by calling the
appropriate operator new.

That is, calling operator new is not a necessary part of constructing an
object.  It occurs only for dynamic objects, and is the moral equivalent of
adjusting the stack pointer.

Step 2 runs in the memory allocated by one of the methods in step 1.  Untl
Step 2 runs, this memory is not an object, it's simply snough memory in
which to construct an object.

    void *buffer = A::operator new(sizeof(A));

runs only step 1.  No A has been constructed in the space.  Casting buffer
to A* and using it as an A* is a recipe for disaster.  Calling a virtual
method on it is almost certainly an instant crash.

    A *a = new A();

runs both steps 1 and 2 and *does* create an A.

    {
        A a;
    }

also runs both steps 1 and 2 and *does* create an A, but does not call
operator new.

---
[ 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: jpotter@falcon.lhup.edu (John Potter)
Date: Mon, 20 May 2002 17:21:17 GMT
Raw View
On Fri, 17 May 2002 23:03:34 GMT, whatiscpp@yahoo.com (John the newbie)
wrote:

> Yes, the distinction between a new-expression and a function named
> "operator new" is clear to me. That's not my point.

I don't think it is clear to you.

> Here's where I don't agree. What you say is true for the global
> operator new functions. But when it comes to class members like in

> struct MyClass {
>   void * operator new (std::size_t);
> };

That is a static member function.  It has no this pointer because there
is no object.  Operator new is a raw memory allocation function whether
it is global or a class static member.

Operator new allocates a properly sized and aligned bucket of bits.
Constructor creates object in that bucket of bits.
New expression calls the two functions in the correct order.

Destructor turns object into bucket of bits.
Operator delete reclaimes the bucket of bits.
Delete expression calls the two functions in the correct order.

John

---
[ 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: whatiscpp@yahoo.com (John the newbie)
Date: Mon, 13 May 2002 18:12:22 GMT
Raw View
Hi everybody,

can someone explain why the standard requires user-declared operator
new to have a void* return type even when it is member of a class?

E.g.:

class MyClass {
public:
    void* operator new (std::size_t);
};

Why not  MyClass* operator new (std::size_t); ?


Moreover shouldn't
   MyClass * p = new MyClass();
give an error because of conversion from void* to MyClass*?


Thanks for the help!

---
[ 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 Natalie <ron@sensor.com>
Date: Mon, 13 May 2002 19:28:20 GMT
Raw View

John the newbie wrote:

> can someone explain why the standard requires user-declared operator
> new to have a void* return type even when it is member of a class?
>
Because it doesn't return an item of the class, it returns memory
on which such a class can be instantiated.

---
[ 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: "AT" <coveraaten@imation.com>
Date: Tue, 14 May 2002 17:51:42 GMT
Raw View
What Ron said in previous post is true. I just would like slightly expand
the point.

When you write

CMyClass a = new CMyClass;

you will call new operator (don't confuse it with operator new).
New call then operator new. And operator new is void* operator new(size_t).
This is exaclty the thing you are trying to overload in you class and in
order for new operator to use your overload it should be as it is known to
new operator.

Since the new operator is pretty universal thing it is just ask operator new
to allocate raw memory (in bytes) and then call constructor on this memory.
Since you don't know what you going allocate next time is not reasonable to
have operator new to return anything but void.

Arkady

--
_________________
Remove "cover" when reply.
"John the newbie" <whatiscpp@yahoo.com> wrote in message
news:102a8848.0205131005.54deff29@posting.google.com...
> Hi everybody,
>
> can someone explain why the standard requires user-declared operator
> new to have a void* return type even when it is member of a class?
>
> E.g.:
>
> class MyClass {
> public:
>     void* operator new (std::size_t);
> };
>
> Why not  MyClass* operator new (std::size_t); ?
>
>
> Moreover shouldn't
>    MyClass * p = new MyClass();
> give an error because of conversion from void* to MyClass*?
>
>
> Thanks for the help!
>
> ---
> [ 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                       ]