Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
271 views
in Technique[技术] by (71.8m points)

c++ - Is taking uninitialized references of class members during construction legal?

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

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

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...