user965369
user965369

Reputation: 5733

Is it stable to use arithmetic in a ctor's initialization list?

Is it stable to use something like this in a class's ctor initialization list during implicit assignment (no operators are overloaded):

class C{
   public:
      C(int _var): var(_var), i(var*var) 
        {} 
   private:
      int var;
      int i;
};

I'm getting some eratic results, why is this?

Upvotes: 7

Views: 815

Answers (3)

Christian Rau
Christian Rau

Reputation: 45948

Yes this is safe, but in this case you have to be careful. You are using var and not _var, so you have to be sure var is constructed before i. This is the case here, since the members are constructed in the order of their declaration (in this case var, i), which may be different from the order of their appearance in the initializer list.

So in this case it works. It would also work in this case:

C(int _var):  i(var*var), var(_var)

but not in this:

class C{
   public:
      C(int _var): var(_var), i(var*var) 
        {} 
   private:
      int i;
      int var;
};

But of course, to be always on the safe side, you could just use _var:

C(int _var):  var(_var), i(_var*_var)

Upvotes: 5

Steve Jessop
Steve Jessop

Reputation: 279245

That code has defined meaning, assuming the multiplication doesn't overflow.

Be aware that it relies critically on the fact that var is defined before i in the class (order in the initializer list is irrelevant, all that matters is the order the members themselves are defined). Otherwise i would be initialized using the unitialized data member var.

But if you're getting erratic behavior with exactly that code, then the bug lies elsewhere.

Upvotes: 5

Mordachai
Mordachai

Reputation: 9642

Yes.

You might want to get rid of the initialization order dependency, and write:

  C(int _var): var(_var), i(_var*_var) 

Basically, by making i depend on var, you must ensure that var is declared before i in the class.

Similarly, you can initialize something in C that is defined (and initialized) in a parent class, because the parent will be constructed before C.

Best practices dictate that you be aware of the above, and avoid situations that obfuscate any of that - maybe document i's dependence on var, so that the next programmer (maybe yourself) doesn't introduce an initialization order issue.

Upvotes: 8

Related Questions