Re: Is it legal to directly call a constructor?
* James Kanze:
Note that you've just changed the meaning of "direct".
Depends on what meaning one assumes to begin with. For a constructor the call
via pointer meaning doesn't apply. So it must be something else. Having the call
deferred to the inside of some construct is something else. Ergo, that's it. :D
[snip]
And at the machine code level some funny stuff is used to
forward those arguments after setting up exception handling
(if a scheme is used where that is necessary, i.e. not address
look-up based handling) and after calling the relevant
allocation function, which forwarding constitutes an
indirection.
There's no forwarding that I can see.
Well that was perhaps Very Bad Phrasing. Instead of /is/ I should have written
/may be/, I'm sorry. The Holy Standard discusses this in ?5.3.4/21, where it
states that it's unspecified whether the allocation function is called before or
after evaluating the specified constructor arguments. If it's called after, then
you can't emulate the effect in C++ level code without argument forwarding.
As an example of emulation, consider
T* p = new T( e1, e2, e3 );
With the allocation function called before the argument evaluation, the compiler
can translate that to machine code equivalent to
T* p;
{
T* __p = (T*)::operator new( sizeof( T ) ); // Or T's allocator.
try
{
::new( __p ) T( e1, e2, e3 );
p = __p;
}
catch( ... )
{
::operator delete( __p ); // Or T's deallocator.
throw;
}
}
With a class-defined allocation function with extra arguments (a placement
allocation function) then on a constructor exception the corresponding placement
deallocation function needs to be called with the same arguments. Which with the
equivalence code above makes it necessary to hold on to those arguments until
sucessful construction has been accomplished. Then the question is, is it easier
or more efficient or whatever to hold on to (effectively forward) the allocation
function arguments, which means calling the allocation function before the
constructor argument evaluation as above, or to hold on to (effectively forward)
the constructor arguments, which means calling the allocation function after the
constructor argument evaluation? The implementation decides.
Anyway, I think of the choice of allocation after the constructor argument
evaluation, as an indirect call of the constructor -- it is similar to calling
f() by calling g() which calls f(), except that one needs C++0x to actually
express at the C++ level a g() that does what operator new does (hm, I'm not
sure whether it's possible even in C++0x for a placement allocation function!).
Cheers,
- Alf
--
Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
No ads, and there is some C++ stuff! :-) Just going there is good. Linking
to it is even better! Thanks in advance!