What is this feature

P

parag_paul

hi All,
I just saw some code that
looks like this


(void*) new (h) className ( arg1, arg2 );
all by itself. Is this an accepted syntax. I have never seen something
similar to this.
If yes, how does it work?
-Parag
 
V

Victor Bazarov

I just saw some code that
looks like this


(void*) new (h) className ( arg1, arg2 );
all by itself. Is this an accepted syntax. I have never seen something
similar to this.
If yes, how does it work?

Without knowing what 'h' is, it's hard to go into details, but

It calls

className::eek:perator new( size_t, decltype(h) )

, from which it receives a pointer to some memory in which it then
constructs an instance of 'className' using the constructor that
accepts the two arguments. Since the entire expression returns
a pointer to the newly created object, the code seems to discard it
(no assignment anywhere). The cast to 'void*' is extraneous, AFAICT.

Of course, questions of the nature "what does that code do" are
better addressed to those who wrote the code.

V
 
D

dp1978x

Without knowing what 'h' is, it's hard to go into details, but

It calls

className::eek:perator new( size_t, decltype(h) )

, from which it receives a pointer to some memory in which it then
constructs an instance of 'className' using the constructor that
accepts the two arguments. Since the entire expression returns
a pointer to the newly created object, the code seems to discard it
(no assignment anywhere). The cast to 'void*' is extraneous, AFAICT.

Of course, questions of the nature "what does that code do" are
better addressed to those who wrote the code.

In other words it constructs an object within an existing buffer "h"
instead of allocating a new one.

D.
 
V

Victor Bazarov

In other words it constructs an object within an existing buffer "h"
instead of allocating a new one.

*That* cannot be asserted without knowing what 'h' is. Yes, it uses
the syntax the placement new uses. But if 'h' is an integer or some
other type, all that can be concluded is that a special form of 'new'
is invoked, the one that takes an extra argument. Hell, if 'h' is
a macro, then who know what the expression can contain after the
preprocessor is done with it...

V
 
P

peter koch

In other words it constructs an object within an existing buffer "h"
instead of allocating a new one.

D
Maybe! We do not know what h is, so that is one possibility. Another
one is that the memory is allocated from some special arena.

/Peter
 
P

parag_paul

*That* cannot be asserted without knowing what 'h' is. Yes, it uses
the syntax the placement new uses. But if 'h' is an integer or some
other type, all that can be concluded is that a special form of 'new'
is invoked, the one that takes an extra argument. Hell, if 'h' is
a macro, then who know what the expression can contain after the
preprocessor is done with it...

V

Sorry to have been so brief earlier.
The 'h' in the discussion is actually
something like the following

className h ;

(void*) new (h) className ( arg1, arg2 );
 
D

dp1978x

Sorry to have been so brief earlier.
The 'h' in the discussion is actually
something like the following

className h ;

(void*) new (h) className ( arg1, arg2 );

Is the destructor called explicitely somewhere before "new"? If not
it's likely a bug.
 
V

Victor Bazarov

Is the destructor called explicitely somewhere before "new"? If not
it's likely a bug.

Again, you're rushing into some conclusions without any basis, or
at least it would seem so. The code does not have the address of
'h' in the 'new' expression. If it did, we could claim in-place
re-initialisation of sorts, like this:

className h;
new (&h) className(arg1, arg2);

which, of course, as you point out is not a good idea, the object
at the location '&h' is constructed twice (and will most likely
be destructed only once).

But it's not the case. Apparently, the OP can't get his ducks in
a row and post the complete piece of code from which something
could be concluded. Until then, my guess is as good as yours.

V
 
J

James Kanze

For reference, it's (miss-)called "placement new". Be careful,
though, as people (including the standard) use this expression
with two different meanings: either for any new expression with
this syntax, and the operator new function it calls, or for the
particular instance of this syntax where the argument (here, h)
is a void*, or can be converted into a void*.
Maybe! We do not know what h is, so that is one possibility.
Another one is that the memory is allocated from some special
arena.

Well, we do know what happens at one level. The compiler will
generate code to call "operator new( sizeof( className ), h )",
then call the constructor of className with the arguments arg1
and arg2 on the results. Beyond that:

-- there must be a declaration for the corresponding operator
new function somewhere in scope, either as a member function
of className or one of its bases, or in global scope,

-- if that function is declared with a throw() exception
specifier, the compiler will check for null before calling
the constructor, and

-- if the constructor exits via an exception, and there is a
corresponding placement delete in scope, it will be called
with the return value of the operator new function.

As for the question "is this an accepted syntax?", it's too
vague to answer. It's certainly acceptable to the compiler
(provided the corresponding operator new function has been
declared). For readers? It depends on the context: I would, in
fact, be very surprised not to find something similar in an
implementation of std::vector. In fact, in
std::allocator<>::construct(), in the standard vector, but
probably directly in the vector class in any pre-standard
implementations, which didn't use allocators. It was certainly
present in my pre-standard array classes. (Except that I didn't
bother with the cast to void*. Usually, in such cases, you're
ignoring the return value completely---some people insert a cast
to void (not void*) in such cases, to shut up various lint
tools.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top