Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

Coming from this question, I am going a step further:

C* c = static_cast<C*>(malloc(sizeof(C)));

As stated in the referenced question, accessing *c (its members) is undefined behaviour before a constructor is called. But, the pointer itself is valid, of course.

Now within the constructor, the members are available already and I should be able to take the address off.

Putting this together, I conclude that the following is legal:

class Y;
class X
{
    Y& y;
public:
    X(Y& y) : y(y) { } // non-trivial constructor!
};
class Y
{
    X& x;
public:
    Y(X& x) : x(x) { }
};
class Z
{
    X x;
    Y y;
public:
    Z() : x(y), y(x) { } 
};

as long as the constructor of X does not use the uninitialized reference to Y other than storing it somewhere.

Is this correct or have I overseen some important point (and thus producing UB again)? If I missed something, would it make a difference if I used pointers instead of references?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
278 views
Welcome To Ask or Share your Answers For Others

1 Answer

This is legitimate. To justify this, see the following from the standard, [basic.life]:

  1. Before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any pointer that refers to the storage location where the object will be or was located may be used but only in limited ways. For an object under construction or destruction, see 12.7. Otherwise, such a pointer refers to allocated storage (3.7.4.2), and using the pointer as if the pointer were of type void*, is well-defined. ...

...

  1. Similarly, before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any glvalue that refers to the original object may be used but only in limited ways. For an object under construction or destruction, see 12.7. Otherwise, such a glvalue refers to allocated storage (3.7.4.2), and using the properties of the glvalue that do not depend on its value is well-defined.

...

Merely taking a reference falls under the 'limited use' (for objects whose lifetime has not yet begun) criteria set out above.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...