Is it legal to directly call a constructor?

A

Alf P. Steinbach

* James Kanze:
* James Kanze:
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.

Your assuming the conclusion. A constructor is a function, of
sorts. For a function, a "direct" call means that it doesn't go
through a pointer to a function (usually). In that sense,
constructors can only be called directly. But other meanings of
"direct" can be considered.
Having the call deferred to the inside of some construct is
something else. Ergo, that's it. :D

Or given that () is the function call operator, at the syntax
levbel, using the function call operator is direct, anything
else is indirect (although I'd use explicit/implied here). Of
course, this definition leads to a lot of fun, because () aren't
only function call operators; they can occur in a lot of other
contexts as well.

IMHO, from a syntax point of view, the only reasonable meaning
for a direct call is one that corresponds to what is described
in §5.2.2---that's what the standard identifies as a function
call. In that sense, you can't call the constructor (or the
destructor) explicitly. Except that the standard also speaks of
a "pseudo destructor call" in §5.2.4. (Does the pseudo mean
that it isn't really a call?) The standard also speaks of
"calling the constructor" in several other places---do these
mean that there is something called a "constructor call"
(different from a "function call"), or is the standard just
referring to indirect calls. (There's no doubt that
constructors do get called.)

It's all really word games, and you can argue just about any
point you like, by defining or using the words in special ways.
[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.

Nonsense. Its basically the same case as:

T::constructor( ::eek:perator new( sizeof( T ) ),
arg1,
arg2... ) ;

In practice, under the hood, the allocator is just an
additional, hidden argument to the constructor. I wouldn't call
that "forwarding".

But I'm not sure what you mean by forwarding. That's why I ask.
To me, forwarding would mean that the constructor was somehow
called from the allocator function, or that there was some
special hidden function which called both of them. But that's
not the case, and I'm pretty sure you know that. (The wording in
the standard is there to allow implementations like that in
CFront, where the call to the allocator was actually in the
constructor---if the hidden constructor argument with the
address was null, the constructor called the allocator
function.)
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*)::eek:perator new( sizeof( T ) ); // Or T's allocator.
try
{
::new( __p ) T( e1, e2, e3 );
p = __p;
}
catch( ... )
{
::eek:perator 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.

I don't get where "effectively holding on to the constructor
arguments" implies forwarding. The compiler generates machine
code, not C++. And the machine code for a function call is
basically: allocate memory for the arguments if necessary,
construct the arguments, then call the function. Those are
three distinct operations, and there's no problem slipping a
call to the allocator anywhere in the middle. And of course,
the presense of a try/catch block doesn't change anything, but
normally, a try/catch block does not generate any inline code.

(Note too that the CFront strategy still works with the required
exception handling. Just that the try/catch block is in the
constructor, not in the calling code.)
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!).

It's the placement allocation which causes problems for the
CFront model. Placement allocation probably must be done
outside of the constructor. (I can think of an implementation
technique with it in the constructor, but it is heavy and much
more complicated.)

I don't understand what you're writing.


Cheers,

- Alf
 

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

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,269
Latest member
vinaykumar_nevatia23

Latest Threads

Top