a
is a global object with static storage duration so it's going to be initialised in some pre-allocated storage sometime before the body of main get executed. Assuming that a call to Test isn't the result of some static object construction weirdness, a
will be full constructed by the time Test is called.
a = new A;
This slightly unusual assignment isn't going to be (only) a standard copy assignment operation as you are assigning a pointer to A
to a, not an object or reference. Whether it actually compiles and what exactly it calls depends on whether A
has an assignment operator that takes a pointer to A
, or something implicitly convertable from a pointer to A
or whether A
has an non-explicit constructor that takes a pointer to A
(or a pointer to a base class of A
).
Post edit, your code does something rather different!
Conceptually, it does something more like this:
A *tmpa;
void *mem = ::operator new( sizeof(A) ); // ( or possibly A::operator new )
try
{
tmpa = new (mem) A; // placement new = default constructor call
}
catch (...)
{
::operator delete( mem );
throw;
}
a = tmpa; // pointer assignment won't throw.
The peril with writing something out like this is that your implicitly adding a lot of sequence points that just aren't there in the original, and in addition the compiler is allowed to generate code that doesn't look like this so long as it behaves 'as if' it were written by this as far as the executing program could determine. This 'as if' rule only applies to the executing thread as the (current) language says nothing about interaction with other threads works.
For this you need to use the specific behaviour guarantees (if any) proided by your implementation.