Let's just put away the logic of the program for a moment. I'm just
wondering whether this syntax is legal in standard C++ or not. This
compiles OK in VC and GCC, but fails in Comeau. I'm not able to find
a direct answer to this in the standard. Can anyone help to explain
whether it is syntactically legal? Thank you very much.
The above is not valid syntax in standard C++.
But regarding your question which you inconveniently put only in the subject
line, "Is it legal to directly call a constructor", yes of course it is
(regarding a constructor of a most derived class the only indirect way is via
the 'new' operator), and that's what you do every time you call a constructor.
Given your example, what you probably meant was to ask, "Does C++ support
calling a constructor on existing storage?", and the answer to that is also yes.
> This
> compiles OK in VC and GCC, but fails in Comeau.
It shouldn't compile with any compiler.
For g++, have you remembered to specify -pedantic and -std=c++98?
For VC, which version?
> I'm not able to find
> a direct answer to this in the standard. Can anyone help to explain
> whether it is syntactically legal? Thank you very much.
The C++ syntax for calling a constructor on existing storage is the basic
placement new, like, for emulating what you're trying to do above,
#include <new>
...
this->A::~A(); // Must first be destroyed.
::new( this ) A(); // Resurrect.
This is extremely dangerous when you don't know what you're doing, which you
don't when you're enquiring about the syntax. It's even extremely dangerous when
you do think you know what you're doing, or perhaps especially then! There's
very seldom any reason to do it; if or when you feel that that the above could
be a solution to something, ask about solutions to the something (they will
exist, and they will not include the above).
Cheers & hth.,
- 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!
Or by having an instance of that class as a default-constructed member.
Sorry.
Didn't think of that when just typing away...
> > This
> > compiles OK in VC and GCC, but fails in Comeau.
>
> It shouldn't compile with any compiler.
>
> For g++, have you remembered to specify -pedantic and -std=c++98?
I have to apologize that the code in the original post doesn't compile
in g++. It's my mistake. However, the following code compiles in g++
and vc.
class A {};
int main()
{
A::A();
}
Is this syntactically legal in standard C++? I only know that "A()"
is the syntax used to create a temporary object of A.
And even more, the following code compiles in g++ (but not in vc).
#include <typeinfo>
class A {};
int main()
{
typeid(A::A);
}
What does this mean?
PS: By saying g++, actually I'm using mingw through dev-c++ on
windows.
>
> For VC, which version?
The code in the original post compiles in VC2008SP1.
Yes, AFAIK (regarding the qualification with A::, but check the standard if it
matters). It constructs a temporary of type A.
> I only know that "A()"
> is the syntax used to create a temporary object of A.
Yes.
> And even more, the following code compiles in g++ (but not in vc).
> #include <typeinfo>
> class A {};
> int main()
> {
> typeid(A::A);
> }
> What does this mean?
typeid is a built-in operator.
C++ allows any expression that produces a value, void, or a reference, to be
used as a statement; this includes writing e.g.
42;
You should up the compiler's warning level to get some diagnostic.
Check your documentation (textbook, C++ standard, whatever) regarding typeid.
> PS: By saying g++, actually I'm using mingw through dev-c++ on
> windows.
>> For VC, which version?
> The code in the original post compiles in VC2008SP1.
It really shouldn't.
But have you checked the compiler's documentation about non-conformance issues?
It might be (and probably is) a VC-specific language extension, for backwards
compatibility with pre-standard code.
I think that 'A::A' is the same as 'A' outside of 'A', so when you write
A::A();
it's the same as to write
A();
if you're not inside the 'A' class itself (not inside of one of its
member functions). Try writing
A::A::A::A::A::A::A::A::A();
and see what happens. :-)
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
> > And even more, the following code compiles in g++ (but not in vc).
> > #include <typeinfo>
> > class A {};
> > int main()
> > {
> > typeid(A::A);
> > }
> > What does this mean?
>
> typeid is a built-in operator.
typeid should take an expression or a type as its operand, but I don't
know what kind of expression or type A::A represents.
Every class has a name of itself injected into its scope. So, 'A::'
resolves to the scope of the class A, and the name 'A' in that scope
refers to the class itself, recursively. 'A::A::A::A::A::A ...' is the
same as 'A', but only outside of the class itself, IIRC.
Maybe I got it backwards and it's only allowed inside the class scope...
You can't directly call a constructor in C++. The closest you can do is
use placement new to construct an object in a buffer you provide:
#include <memory>
struct A { };
int main()
{
char* mem = new char [sizeof (A)];
A* a = new (mem) A;
// ...
a->~A();
delete [] mem;
}
(if A's constructor throws an exception in the example, it'll leak the
storage pointed to by mem).
On the contrary, that's the farthest from a direct constructor call. The
placement new has to work very indirectly because it has to set up an exception
handler, plus in the general case it has to call the class' allocation function,
before invoking the constructor with the specified arguments, which it has held
on to until now. In contrast, an ordinary direct constructor call is a direct
call, which you can readily verify by inspecting the machine code (unless you
have a really perverse C++ implementation).
> > class A {
> > void f() { this->A::A(); }
> > };
> > Let's just put away the logic of the program for a moment.
> > I'm just wondering whether this syntax is legal in standard
> > C++ or not.
> The above is not valid syntax in standard C++.
> But regarding your question which you inconveniently put only
> in the subject line, "Is it legal to directly call a
> constructor", yes of course it is (regarding a constructor of
> a most derived class the only indirect way is via the 'new'
> operator), and that's what you do every time you call a
> constructor.
It really hinges on what you mean by "direct". There is no
syntax in C++ which "calls a constructor"; every *syntax* which
results in a constructor call also allocates memory. Formally,
at least---placement new can be used to make the memory
allocation a no-op, of course. (But using placement new isn't
really what I'd call "direct". On the other hand, naming a base
class in a initialization list sure looks like a direct call to
the constructor to me.)
Anyway, his example made it more or less clear: he wants to call
the constructor like you'd call any other member function.
Which doesn't work, of course. Logically, since to call any
other member function (including the destructor), you need an
object, and the only way to get an object is to call the
constructor.
[...]
> The C++ syntax for calling a constructor on existing storage is the basic
> placement new, like, for emulating what you're trying to do above,
>
> #include <new>
>
> ...
>
> this->A::~A(); // Must first be destroyed.
Technically, only if it has a non-trivial destructor. (Also,
this->A::~A() is probably not a good idea, since the qualified
id prevents virtual function resolution. Although just about
anywhere virtual function resolution would make a difference,
explicit destruction will probably cause other problems as
well.)
> ::new( this ) A(); // Resurrect.
> This is extremely dangerous when you don't know what you're
> doing, which you don't when you're enquiring about the syntax.
> It's even extremely dangerous when you do think you know what
> you're doing, or perhaps especially then! There's very seldom
> any reason to do it; if or when you feel that that the above
> could be a solution to something, ask about solutions to the
> something (they will exist, and they will not include the
> above).
Even if you know perfectly what you're doing, it's dangerous,
because the person who ends up maintaining your code may not
realize you're doing it, and make some modification which breaks
it (e.g. by adding something to A::A() which might throw).
--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Just the opposite of "indirect". :-)
E.g. that could be debated for the case of a virtual call of an ordinary member
routine, is it direct or indirect? At the source code level it's direct. At the
machine code level it's indirect. Just flinging about the word "direct" would
not be sufficient for that case. One would need to be more specific.
But happily, for a constructor there's no such difference between the source
code level and the machine code level.
For a direct constructor call there are possible extra actions (memory
initializer list argument evaluation, invocations of base and member
constructors) but these actions are part of the called constructor. It's not
like there is some way to call the constructor without getting them, as you can
call a virtual routine non-virtually (machine code direct) or virtually (machine
code indirect). The direct -- implicit or explicit -- constructor call ends
up as a direct machine code call, plain and simple.
For an indirect call, operator new (placement or not!), there's indirection both
at the source code level and the machine code level. At the source code level
constructor arguments are handed to an operator, which will do the calling,
indirect. 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 is no
> syntax in C++ which "calls a constructor"; every *syntax* which
> results in a constructor call also allocates memory. Formally,
> at least---placement new can be used to make the memory
> allocation a no-op, of course. (But using placement new isn't
> really what I'd call "direct". On the other hand, naming a base
> class in a initialization list sure looks like a direct call to
> the constructor to me.)
Yes. It is a shame that the syntax of C++ differentiates many cases that really
should have been abstracted (e.g., no common "command" syntactic element, so
semicolons are present in a lot of places to /emulate/ that missing element!),
and fails to differentiate cases that really constitute distinct semantical
categories. I guess that this divide, the lack of a mostly one-to-one mapping
between syntax and semantics, leads to endless confusion for the newbies...
> Anyway, his example made it more or less clear: he wants to call
> the constructor like you'd call any other member function.
> Which doesn't work, of course. Logically, since to call any
> other member function (including the destructor), you need an
> object, and the only way to get an object is to call the
> constructor.
Uh, from a pedantic point of view, no. You don't need an object to call a static
member function. And, still pedantically, it depends on the meaning of the word
"call": for a source code level call that is only evaluated at compile time you
don't need an object; indeed there is no object at compile time. ;-)
> [...]
>> The C++ syntax for calling a constructor on existing storage is the basic
>> placement new, like, for emulating what you're trying to do above,
>>
>> #include <new>
>>
>> ...
>>
>> this->A::~A(); // Must first be destroyed.
>
> Technically, only if it has a non-trivial destructor. (Also,
> this->A::~A() is probably not a good idea, since the qualified
> id prevents virtual function resolution.
In this case qualified destructor call is IMHO the only reasonable idea, the
least ungood. For it's UB to resurrect the object as an object of different type
if it's accessed as the original type. And so one does, in practice, need to
know the exact most derived type, and that should be expressed in the code.
> Although just about
> anywhere virtual function resolution would make a difference,
> explicit destruction will probably cause other problems as
> well.)
>
>> ::new( this ) A(); // Resurrect.
>
>> This is extremely dangerous when you don't know what you're
>> doing, which you don't when you're enquiring about the syntax.
>> It's even extremely dangerous when you do think you know what
>> you're doing, or perhaps especially then! There's very seldom
>> any reason to do it; if or when you feel that that the above
>> could be a solution to something, ask about solutions to the
>> something (they will exist, and they will not include the
>> above).
>
> Even if you know perfectly what you're doing, it's dangerous,
> because the person who ends up maintaining your code may not
> realize you're doing it, and make some modification which breaks
> it (e.g. by adding something to A::A() which might throw).
Yeah. :-)
Cheers,
> A::A();
> A();
Not always. Consider:
struct A { A() ; } ;
A() { /* ... */ } // illegal...
A::A() { /* ... */ } // defines the constructor.
I think that the standard is actually somewhat ambiguous here,
at least when the class name is immediately followed by an
opening parentheses. According to the standard, "Constructors
do not have names. A special declarator syntax using an optional
sequence of function-specifiers (7.1.2) followed by the
constructor¿s class name followed by a parameter list is used to
declare or define the constructor." (Of course, if I read this
literally, it means that the both of the declarations above are
legal to define the constructor.)
> if you're not inside the 'A' class itself (not inside of one
> of its member functions). Try writing
> A::A::A::A::A::A::A::A::A();
> and see what happens. :-)
Whether you're inside the class or not doesn't matter. The only
question is whether the final A (the one followed by the ()) is
an instance of the "special declarator syntax[...]used to
declare or define the constructor".
> > goodbye...@gmail.com wrote:
> >> class A {
> >> void f() { this->A::A(); }
> >> };
> >> Let's just put away the logic of the program for a moment.
> >> I'm just wondering whether this syntax is legal in standard
> >> C++ or not. This compiles OK in VC and GCC, but fails in
> >> Comeau. I'm not able to find a direct answer to this in
> >> the standard. Can anyone help to explain whether it is
> >> syntactically legal? Thank you very much.
> > You can't directly call a constructor in C++. The closest
> > you can do is use placement new to construct an object in a
> > buffer you provide:
> On the contrary, that's the farthest from a direct constructor
> call. The placement new has to work very indirectly because it
> has to set up an exception handler, plus in the general case
> it has to call the class' allocation function, before invoking
> the constructor with the specified arguments, which it has
> held on to until now. In contrast, an ordinary direct
> constructor call is a direct call, which you can readily
> verify by inspecting the machine code (unless you have a
> really perverse C++ implementation).
What's your definition of "direct" in this context? In other
words, what makes a constructor call a "direct constructor
call", as opposed to an indirect constructor call? (In one very
real sense, all constructor calls are direct. Since you can't
take the address of the constructor, there's no way to get a
pointer to it in order to call it indirectly. But I suppose
neither you nor the original poster meant "direct" in that way,
although it would seem to me the most obvious meaning.)
<quote origin="elsethread">
Just the opposite of "indirect". :-)
E.g. that could be debated for the case of a virtual call of an ordinary member
routine, is it direct or indirect? At the source code level it's direct. At the
machine code level it's indirect. Just flinging about the word "direct" would
not be sufficient for that case. One would need to be more specific.
But happily, for a constructor there's no such difference between the source
code level and the machine code level.
For a direct constructor call there are possible extra actions (memory
initializer list argument evaluation, invocations of base and member
constructors) but these actions are part of the called constructor. It's not
like there is some way to call the constructor without getting them, as you can
call a virtual routine non-virtually (machine code direct) or virtually (machine
code indirect). The direct -- implicit or explicit -- constructor call ends
up as a direct machine code call, plain and simple.
For an indirect call, operator new (placement or not!), there's indirection both
at the source code level and the machine code level. At the source code level
constructor arguments are handed to an operator, which will do the calling,
indirect. 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.
</quote>
Cheers,
> >>> class A {
> >>> void f() { this->A::A(); }
> >>> };
> >>> Let's just put away the logic of the program for a moment.
> >>> I'm just wondering whether this syntax is legal in
> >>> standard C++ or not.
> >> The above is not valid syntax in standard C++.
> >> But regarding your question which you inconveniently put
> >> only in the subject line, "Is it legal to directly call a
> >> constructor", yes of course it is (regarding a constructor
> >> of a most derived class the only indirect way is via the
> >> 'new' operator), and that's what you do every time you call
> >> a constructor.
> > It really hinges on what you mean by "direct".
> Just the opposite of "indirect". :-)
Which is? :-)
I raise the question because in C, when one spoke of an indirect
function call, it almost always meant a call through a pointer
to function. If we accept this definition, then there's no way
of calling a constructor indirectly (since you can't take its
address).
> E.g. that could be debated for the case of a virtual call of
> an ordinary member routine, is it direct or indirect?
Exactly. If I have an explicit pointer to function, which I
dereference, the call is indirect. If I call a global function
or a non-virtual member function directly, it's direct. But
what about a virtual function?
> At the source code level it's direct. At the machine code
> level it's indirect. Just flinging about the word "direct"
> would not be sufficient for that case. One would need to be
> more specific.
> But happily, for a constructor there's no such difference
> between the source code level and the machine code level.
> For a direct constructor call there are possible extra actions
> (memory initializer list argument evaluation, invocations of
> base and member constructors) but these actions are part of
> the called constructor. It's not like there is some way to
> call the constructor without getting them, as you can call a
> virtual routine non-virtually (machine code direct) or
> virtually (machine code indirect). The direct -- implicit or
> explicit -- constructor call ends up as a direct machine
> code call, plain and simple.
> For an indirect call, operator new (placement or not!),
> there's indirection both at the source code level and the
> machine code level.
Note that you've just changed the meaning of "direct". Even
when I use operator new, there's no "indirection" (through a
pointer) when calling the constructor, so in that sense, it is
direct. Syntactically, however, I've not written a "function
call expression" or a "constructor call expression" (which
doesn't exist in C++), so according to some definition, it is
indirect. It's still not as indirect as the call to g(),
however, when I call a function f(), in another translation
unit, which calls g(). The "new expression" is defined to do
two things (basically): call an allocator function, then call a
constructor. So it's direct in the sense that I've "directly"
(in the expression itself) requested that the constructor be
called.
> At the source code level constructor arguments are handed to
> an operator, which will do the calling, indirect.
I'm not sure I understand that. The "operator", here, is a
syntax construct. That construct does require that the compiler
generate a call to the constructor.
> 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.
> > There is no syntax in C++ which "calls a constructor";
> > every *syntax* which results in a constructor call also
> > allocates memory. Formally, at least---placement new can
> > be used to make the memory allocation a no-op, of course.
> > (But using placement new isn't really what I'd call
> > "direct". On the other hand, naming a base class in a
> > initialization list sure looks like a direct call to the
> > constructor to me.)
> Yes. It is a shame that the syntax of C++ differentiates many
> cases that really should have been abstracted (e.g., no common
> "command" syntactic element, so semicolons are present in a
> lot of places to /emulate/ that missing element!), and fails
> to differentiate cases that really constitute distinct
> semantical categories. I guess that this divide, the lack of a
> mostly one-to-one mapping between syntax and semantics, leads
> to endless confusion for the newbies...
Not just for the newbies:-).
> > Anyway, his example made it more or less clear: he wants to
> > call the constructor like you'd call any other member
> > function. Which doesn't work, of course. Logically, since
> > to call any other member function (including the
> > destructor), you need an object, and the only way to get an
> > object is to call the constructor.
> Uh, from a pedantic point of view, no. You don't need an
> object to call a static member function.
Good point. Is a constructor a static member function? No,
since it has a this pointer. Is it a non-static member
function? No, since you don't need an object to call it. Is it
a member function? Yes, because the standard says so (and I
don't know what else you would call it).
The standard is more than confusing about this.
> And, still pedantically, it depends on the meaning of the word
> "call": for a source code level call that is only evaluated at
> compile time you don't need an object; indeed there is no
> object at compile time. ;-)
:-).
> > [...]
> >> The C++ syntax for calling a constructor on existing
> >> storage is the basic placement new, like, for emulating
> >> what you're trying to do above,
> >> #include <new>
> >> ...
> >> this->A::~A(); // Must first be destroyed.
> > Technically, only if it has a non-trivial destructor.
> > (Also, this->A::~A() is probably not a good idea, since the
> > qualified id prevents virtual function resolution.
> In this case qualified destructor call is IMHO the only
> reasonable idea, the least ungood. For it's UB to resurrect
> the object as an object of different type if it's accessed as
> the original type. And so one does, in practice, need to know
> the exact most derived type, and that should be expressed in
> the code.
Which is more black? In this case, I don't think either are
acceptable:-). One thing is sure, calling A::~A() if the
dynamic type of the object is not A will result in undefined
behavior, regardless of the context. For the rest, I can't
think of a case off hand where it would make sense to explicitly
call the destructor where the dynamic type of the object wasn't
the same as the static type; the only times I've used explicit
destructor calls is in my pre-standard implementation of ArrayOf
and ListOf, and like the standard std::vector and std::list (and
C style arrays), they used copy semantics, and didn't allow
derived objects in the container.
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!).
> 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( ::operator 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.)
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.