Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it undefined behavior in the case of the private functions call in the initializer list?

Consider the following code:

struct Calc
{
   Calc(const Arg1 & arg1, const Arg2 & arg2, /* */ const ArgN & argn) :
      arg1(arg1), arg2(arg2), /* */ argn(argn), 
      coef1(get_coef1()), coef2(get_coef2()) 
   {
   }

   int Calc1();
   int Calc2();
   int Calc3();

private:
  const Arg1 & arg1;
  const Arg2 & arg2;
  // ...
  const ArgN & argn;

  const int coef1; // I want to use const because 
  const int coef2; //      no modification is needed.

  int get_coef1() const {
     // calc coef1 using arg1, arg2, ..., argn;
     // undefined behavior?     
  }
  int get_coef2() const {
     // calc coef2 using arg1, arg2, ..., argn and coef1;
     // undefined behavior?
  }

};

struct Calc is not completely defined when I call get_coef1 and get_coef2 Is this code valid? Can I get UB?

like image 201
Alexey Malistov Avatar asked Mar 22 '10 12:03

Alexey Malistov


2 Answers

12.6.2.8: Member functions (including virtual member functions, 10.3) can be called for an object under construction. Similarly, an object under construction can be the operand of the typeid operator (5.2.8) or of a dynamic_cast (5.2.7). However, if these operations are performed in a ctor-initializer (or in a function called directly or indirectly from a ctor-initializer) before all the mem-initializers for base classes have completed, the result of the operation is undefined.

So you can initialize your class members this way, but not base classes. And, as others pointed, you should be aware of members initialization order, if your function uses some of their values.

like image 172
Tadeusz Kopec for Ukraine Avatar answered Oct 27 '22 13:10

Tadeusz Kopec for Ukraine


Since the variables your calculation depend on are already initialized at the time of the call, it should not be undefined behavior. See this question for related information.

like image 40
Björn Pollex Avatar answered Oct 27 '22 14:10

Björn Pollex