2

Recently I learnt that:

During construction of an object, if the value of the object or any of its subobjects is accessed through a glvalue that is not obtained, directly or indirectly, from the constructor's this pointer, the value of the object or subobject thus obtained is unspecified.

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

I also learnt here that:

in the example above, d and *this are aliases for the same object.

So my question is that is there a reason for why when d and *this are aliases for the same object, then we're not allowed to use d but allowed to use this? What problem does using d instead of this raise? And how does using this resolves that problem?

Jason
  • 36,170
  • 5
  • 26
  • 60
  • this is just what is specified. This doesn't necessarily mean that it couldn't be specifed differently. If you do not follow the rules then the issue is that the compilers assumption that `this` is not aliased does not hold anymore. Are you asking what problems may arise in your code if you do alias `this` or are you asking for the issues that may arise in compiler implementation when the specification would be different? – 463035818_is_not_an_ai Apr 11 '22 at 10:35
  • @463035818_is_not_a_number I am asking what issues will we face if the standard did not provided this restriction. I mean there must be a reason for why the standard says the we should not use `d` and instead use `this`. What is the possible reasoning behind introducing this rule. – Jason Apr 11 '22 at 10:38
  • related: https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule – 463035818_is_not_an_ai Apr 11 '22 at 10:40
  • @463035818_is_not_a_number and why is it specified that way? – user253751 Apr 11 '22 at 13:00
  • thats explained in the linked Q&A. Assuming two pointers do not refer to the same object opens up opportunities for optimizations. I am not 100% sure, but I guess this case is similar to aliasing in general – 463035818_is_not_an_ai Apr 11 '22 at 13:23

1 Answers1

0

During the construction of objects of automatic or dynamic storage duration, accessing the object other than via this (or other pointers or references escaped from this) requires odd code like using a variable in its own initializer or tricks with new. Getting access to a subobject is even harder, since it has to happen after the constructor has begun execution ([class.cdtor]/1), and the lifetime of the overall object doesn’t begin until the constructor finishes.

It is therefore considered useful for alias analysis (though not type-based) to assume that no such access has occurred. Disallowing the usage of static or thread-local names for the object (which are not so unusual) when they do exist allows all cases to be optimized equivalently. If those objects do need to be treated specially, this may be compared to their addresses to detect them.

Davis Herring
  • 36,443
  • 4
  • 48
  • 76
  • Ok, i am processing your answer given here. Meanwhile you might be intereseted in [GCC/Clang/MSVC Bug while expanding template parameter pack in the same parameter clause for function templates](https://stackoverflow.com/questions/71893166/gcc-clang-vs-msvc-bug-while-expanding-template-parameter-pack-in-the-same-para). In the above linked question, my understanding is that the function template examples given at the end of my question are invalid and thus gcc & clang seem to have a bug in accepting those samples. But i would like to know for sure what is correct according to the standard. – Jason May 26 '22 at 15:46
  • _During the construction of objects of automatic or dynamic storage duration, it’s impossible to access the object except via `this`_ I won't be so sure. How about objects created in arrays of `unsigned char`? Yes, you can't launder a pointer to such an array element into point to the object being constructed, since it is not within lifetime yet, but you can launder into a pointer to some already alive member subobject. – Language Lawyer May 26 '22 at 16:59
  • _During the construction of objects of automatic or dynamic storage duration, it’s impossible to access the object except via `this`_ Or, just an array of two objects. The first object saves its `this` pointer into a global variable, the second one obtains a pointer to itself incrementing the saved value. – Language Lawyer May 26 '22 at 17:03
  • _During the construction of objects of automatic or dynamic storage duration, it’s impossible to access the object except via `this`_ Meh, just `Klass k(&k);` for some `Klass::Klass(Klass* self_not_obtained_from_this)` – Language Lawyer May 26 '22 at 17:15
  • @LanguageLawyer: True: you can even manage `new T()` by implementing your own `operator new`. I’ll weaken the statement and try to add some (fuzzy) rationale. – Davis Herring May 27 '22 at 13:45