Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>3.8/1 says:</p> <blockquote> <p><strong>The lifetime of an object of type T begins when</strong>: — storage with the proper alignment and size for type T is obtained, and — if T is a class type with a non-trivial constructor (12.1), <strong>the constructor call has completed</strong>.</p> </blockquote> <p>3.8/5 says:</p> <blockquote> <p><strong>Before the lifetime of an object has started but after the storage which the object will occupy has been allocated</strong> or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, <strong>any pointer that refers to the storage location where the object will be or was located may be used but only in limited ways</strong>. Such a pointer refers to allocated storage (3.7.3.2), and using the pointer as if the pointer were of type void*, is well-defined. <strong>Such a pointer may be dereferenced but the resulting lvalue may only be used in limited ways, as described below.</strong></p> </blockquote> <p>"Below" is 3.8/6:</p> <blockquote> <p>Such an lvalue refers to allocated storage (3.7.3.2), and using the properties of the lvalue which do not depend on its value is well-defined.</p> </blockquote> <p>...and then a list of things you can't do. Binding to a reference to the same, derived type is not among them.</p> <p>I can't find anything elsewhere that might make your code invalid. Notably, despite the following phrase in 8.3.2/4:</p> <blockquote> <p>A reference shall be initialized to refer to a valid object or function.</p> </blockquote> <p>there doesn't seem to be any definition of "valid object" to speak of.</p> <p>So, after much to-ing and fro-ing, <strong>I must conclude that it is legal</strong>.</p> <hr> <p><em>Of course, that's not to say that it's in any way a good idea!</em> <strong>It still looks like a bad design.</strong></p> <p>For example, if you later change your base constructor and any of the following become relevant (again from 3.8/6):</p> <ul> <li>the lvalue is used to access a non-static data member or call a non-static member function of the object</li> <li>the lvalue is implicitly converted (4.10) to a reference to a base class type</li> <li>the lvalue is used as the operand of a <code>static_cast</code> (5.2.9) (except when the conversion is ultimately to <code>char&amp;</code> or <code>unsigned char&amp;</code></li> <li>the lvalue is used as the operand of a <code>dynamic_cast</code> (5.2.7) or as the operand of <code>typeid</code>.</li> </ul> <p>...then your program will be undefined, and the compiler may emit no diagnostic for this!</p> <hr> <p><strong>Random other observations</strong></p> <p>I notice a couple of other <em>interesting</em> things whilst compiling this answer, and this is as good a place as any to share them.</p> <p>First, 9.3.2 appears to leave the type of <code>this</code> in a <em>ctor-initializer</em> accidentally unspecified. Bizarre!</p> <p>Second, the criteria set on a pointer by 3.8/5 (not the same list that I quoted from 3.8/6) include:</p> <blockquote> <p>If the object will be or was of a non-POD class type, the program has undefined behavior if [..] the pointer is implicitly converted (4.10) to a pointer to a base class type.</p> </blockquote> <p>I believe that this renders the following innocuous-looking code undefined:</p> <pre><code>struct A { A(A* ptr) {} }; struct B : A { B() : A(this) {} }; int main() { B b; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload