By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,483 Members | 1,614 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,483 IT Pros & Developers. It's quick & easy.

using placement new to forward ctor calls

P: n/a
Hi,

I'm in discussion with a lib vendor who uses placement new
to forward construction to another ctor, like this:
MyClass( ... ) {
new (this) MyClass( ... );
}
I asked them to use a private init() function instead, but
they claim:
you might be correct that using placement new to forward
construction is not well defined in the general case. In
our case however it is, as the class only contains one
pimpl-pointer (no members that have a constructor
and no vtable). In this case it's perfectly valid to use
the construct we're using.


Please supply me with ammonition to make them reconsider
(or tell me they're right :/).

Thanks,
Marc

Jul 23 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
* Marc Mutz:

I'm in discussion with a lib vendor who uses placement new
to forward construction to another ctor, like this:
MyClass( ... ) {
new (this) MyClass( ... );
}
I asked them to use a private init() function instead, but
they claim:
you might be correct that using placement new to forward
construction is not well defined in the general case. In
our case however it is, as the class only contains one
pimpl-pointer (no members that have a constructor
and no vtable). In this case it's perfectly valid to use
the construct we're using.


Please supply me with ammonition to make them reconsider
(or tell me they're right :/).


"Right" or "wrong" is not really relevant wrt. a platform-specific library.
Either it works, or not. The technical problem is whether it works with all
relevant compilers (it may, or it may not), and with future versions of
those compilers (it may not). The problem for a client is that the
construct above is _unnecessary_ UB, and bodes not well for the quality of
the rest of the library implementation. It indicates that they're "clever"
technicians, not engineers; an engineer wouldn't do a thing like that.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 23 '05 #2

P: n/a
Marc Mutz wrote:
Hi,

I'm in discussion with a lib vendor who uses placement new
to forward construction to another ctor, like this:
MyClass( ... ) {
new (this) MyClass( ... );
}
I asked them to use a private init() function instead, but
they claim:
you might be correct that using placement new to forward
construction is not well defined in the general case. In
our case however it is, as the class only contains one
pimpl-pointer (no members that have a constructor
and no vtable). In this case it's perfectly valid to use
the construct we're using.


Please supply me with ammonition to make them reconsider
(or tell me they're right :/).


1) It's not easy to understand, it's not clear what this code is trying
to achieve
2) It's not common practice
3) It's brittle, it may break on another system/compiler/version.
4) It may be wrong (is this really a MyClass?)
5) It may be less "efficient" than calling an init() function
6) It is illegal
7) The fact that they admit "using placement new to forward
construction is not well defined in the general case" is quite scary.

And 8) change the library.
Jonathan

Jul 23 '05 #3

P: n/a
The only thing I have to add to the superior answers you have received
so far is that I am not accustomed to being born twice in spite of
dying once. And it's UB,thus you can expect demons, aliens, formatted
drives and absense of errors.

Jul 23 '05 #4

P: n/a
leonardo77 wrote:
And it's UB,thus you can expect demons, aliens, formatted
drives and absense of errors.


Where in the standard is that requirement? <g> In fact, I expect that it
does exactly what it was described as doing. With suitable knowledge of
the target platform and of the compiler and with appropriate testing
there's no need to fear code whose behavior isn't defined by the
language definition.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jul 23 '05 #5

P: n/a
Marc Mutz wrote:
I'm in discussion with a lib vendor who uses placement new
to forward construction to another ctor, like this:
MyClass( ... ) {
new (this) MyClass( ... );
}
Please supply me with ammonition to make them reconsider
(or tell me they're right :/).


It's uncool. It looks as if they dont know what they are doing.

------
"The fact that the program works has no relevance."
Bartosz Milewski

Jul 23 '05 #6

P: n/a
Me
Marc Mutz wrote:
I'm in discussion with a lib vendor who uses placement new
to forward construction to another ctor, like this:
MyClass( ... ) {
new (this) MyClass( ... );
}
I asked them to use a private init() function instead, but
they claim:
you might be correct that using placement new to forward
construction is not well defined in the general case. In
our case however it is, as the class only contains one
pimpl-pointer (no members that have a constructor
and no vtable). In this case it's perfectly valid to use
the construct we're using.


Please supply me with ammonition to make them reconsider
(or tell me they're right :/).


This is already in shaky grounds because the lifetime of a non-POD
before construction completes and before destruction begins is really
hard to reason about and there are lots of restrictions on what is well
defined and what isn't (see 3.8 and the sections it references for more
details). But if we ignore that and pick a simpler reason why this code
is illegal:

3.8/1 "The lifetime of an object of type T begins when ... if T is a
class type and the constructor invoked to create the object is
non-trivial (12.1), the constructor call has completed."

MyClass::MyClass(...)
{
new ((void*)this) MyClass(...); //1
} //2

So what happens here is that they are using placement new to create a
new object at the location pointed to by this //1. This creates a new
MyClass object, that's fine (totally ignoring the issues I talked about
above). The problem occurs when the MyClass ctor returns //2, the
constructor call has completed, which means *two* MyClass objects are
created at the same memory location, which is illegal since MyClass is
not a POD struct. Since there is no way to forward ctor calls in the
current standard, the only legal thing to do is call an init()
function.

Jul 23 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.