首页 > 解决方案 > Is accessing accessing a child attribute in the parent constructor UB when using CTRP?

问题描述

I made a wandbox that captures my issue: https://wandbox.org/permlink/qAX6SL43BvERo32Z

Basically, as the tittle suggests. I am using CRTP, and my base / parent class constructor calls a child method using the standard way in CTRP.

BUT that child method uses it's own child classes's attributes, which if are of certain type, such as std::string, appear to cause runtime issues (Such as bad alloc on MSVC, and 'what(): basic_string::_M_create' / empty string on GCC).

Long story short, is this UB? If so exactly why?

Bonus points for anyone who can give suggestions for how to tackle this problem. Should / can I add an "Init" "virtual" CTRP method that the parent class calls to initialize the child variables? Should I just generally avoid CTRP calling child methods in the constructor?

标签: c++stringstructcrtpbad-alloc

解决方案


Is accessing accessing a child attribute in the parent constructor UB

Yes, in general.

... when using CTRP?

And yes, in particular.

If so exactly why?

Because the behaviour of accessing an object outside its lifetime is undefined. The lifetime of the derived object and its members has not yet begun by the time the base-sub object is being constructed.

Conclusion: CRTP bases must not do the CRTP magic (i.e. you musn't do static_cast<Derived*>(this) or similar) in their constructors nor destructors (and be careful of calling member functions, as those must also not do the same).

Bonus points for anyone who can give suggestions for how to tackle this problem. Should / can I add an "Init" "virtual" CTRP method that the parent class calls to initialize the child variables?

The derived class constructor should initialize its own variables whether you use CRTP or not. The constructor should do nothing extra beyond initializing the state of the object. It shouldn't "do fruit things".


推荐阅读