Search code examples
c++initializationcrtp

C++ CRTP initialization


i ran into a segfault running the following program

#include <iostream>
#include <vector>

template <typename Derived>
struct CRTPBase {
  CRTPBase() {
    func();
  }
  void func() {
    static_cast<Derived*>(this)->_func();
  }
};
struct CRTPChild : CRTPBase<CRTPChild>{
  using CRTPBase<CRTPChild>::CRTPBase;
  void _func(){
    vec.resize(10);
    vec[0] = 2;
  }
  std::vector<int> vec;
};
int main()
{
    CRTPChild obj;
    std::cout << obj.vec[0] << std::endl;
}

When i replace vec with a member of type int it doesn't segfault anymore. Why?


Solution

  • Your code has undefined behavior. The problem comes from the order of the initialization; for the derived class CRTPChild, the constructor of the base class CRTPBase<CRTPChild> is invoked firstly, after that the data member vec of CRTPChild get initialized. When _func is invoked (from the constructor of the base class) vec is not initialized at all.

    2) Then, direct base classes are initialized in left-to-right order as they appear in this class's base-specifier list

    3) Then, non-static data members are initialized in order of declaration in the class definition.

    Changing the type to int it's still UB. UB means anything is possible, it might lead to segfault or might not.