Home > Net >  this pointer cannot be aliased in a constructor:
this pointer cannot be aliased in a constructor:

Time:04-12

I am learning about inheritance in C . And i came across the following statement:

In other words, the this pointer cannot be aliased in a constructor:

extern struct D d;
struct D
{
    D(int a) : a(a), b(d.a) {} // b(a) or b(this->a) would be correct
    int a, b;
};
D d = D(1);   // because b(d.a) did not obtain a through this, d.b is now unspecified

The above example is from cppreference.

My first question is that it is written that "this cannot be aliased in a ctor" but then in the example above, they've written in the comment "b(this->a) would be correct". This seems to be a contradiction to me because when they said that this cannot be aliased in a ctor i understood that "this cannot be used in a ctor". But then why are they saying that writing b(this->a) would be correct if this cannot be used/aliased in a ctor. Isn't the initializer list considered "in a ctor"?


Now lets look at a custom example:

struct Name 
{
    private: 
        int x = 0;
  Name(int n )
  {
     this->x = 4;  //is the use of "this" well-defined here?
  }
};

My second question is that is the use of the expression this->x inside the converting constructor shown above well-defined? I mean since according the quote at the beginning of my question this can't be aliased in a ctor, so this shouldn't be valid.

CodePudding user response:

What is meant is that during the construction of a class object any access to the object's non-static data members should happen through a pointer/glvalue obtained directly or indirectly from this of the constructor. Otherwise the value read by such an access is unspecified.

So this->a is always fine, as is simply a which is implicitly the same as this->a.

It is also ok to copy the pointer this and access members through that, e.g.

auto p = this;
b = p->a;

or to store a reference to the object:

auto& r = *this;
b = r.a;

But in the example given at the beginning, d is the same object as this points to. In other words the name d and *this are aliases for the same object. It is not allowed to use this other alias d to access non-static data members of the class while it is under construction because d was not obtained from this. Or to be more precise, it is unspecified what value such an access will read. So b(d.a) may or may not initialize the b member to the same value as a.

See [class.cdtor]/2.

  • Related