Search code examples
c++multithreadingconstructormulticoresequence-points

Can assignment be done before constructor is called?


A comment to What's wrong with this fix for double checked locking? says:

The issue is that the variable may be assigned before the constructor is run (or completes), not before the object is allocated.

Let us consider code:

A *a;

void Test()
{
    a = new A;
}

To allow for more formal analysis, let us split the a = new A into several operations:

void *mem = malloc(sizeof(A)); // Allocation
new(mem) A; // Constructor
a = reinterpret_cast<A *>(mem); // Assignment

Is the comment quoted above true, and if it is, in what sense? Can Constructor be executed after the Assignment? If it can, what can be done against it when guaranteed order is needed because of MT safety?


Solution

  • The issue isn't so much when code executes, but more to do with write-ordering.

    Let's suppose:

    A()
    {
       member = 7;
    }
    

    Then later:

    singleton = new A()
    

    This results in code that does an allocation, a write to memory (member), and then a write to another memory location (singleton). Some CPU's can re-order writes such that the write to member will not be visible until after the write to singleton - in essence, code running on other CPU's in the system could have a view of memory where singleton is written to, but member is not.