Question (proper) Variables initialization

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
10,002
Reaction score
4,418
Points
203
Location
Toulouse
A quick question. I get warnings from VS2022 that some of my variables are 'not initialized'. As you can below see I dealt with the various handles.

But I don't know what to do with the thruster groups. I reproduced what I saw in the samples, and declare them in the 'private' section of the header. I get that the problem is that they have no value assigned during a brief interval (between the header and clbkSetClassCaps). But I never saw such a thing in the samples. I am missing something ? Then of course, I have the thrusters (th_rcs) & groups (th_group) definitions in clbkSetClassCaps, and (th_group) has a maximum size of 4.

1763933438986.png

1763933239601.png
 
Just set the the all array elements to NULL, that should fix it. Otherwise, you can get some undefined behaviour in your module, similar to srf.

You can also do that in the statement following ":", its actually a comma separated list.

":VESSEL4(hVessel, flightModel), th_group({0}), th_rcs({0})"

 
Thanks, good to know. Seems a good practice.

And VS2022 is now happy :

1763934540357.png
 
Also, what is 'protected' here (Atlantis.h) ? What is the difference from 'public' and 'private' ?

1763938859785.png
 
These control the visibility of class and instance variables and methods:

"public:" : Every declaration following it is visible to code inside and outside the class.
"protected:" : Every declaration following it is only visible to this class or classes derived from it.
"private:" : Every declaration following it is only visible to this class. (default for class)
 
Thank you, crucial stuff!

So, if you have no child classes, you should not use 'protected', but 'private'.
 
So, if you have no child classes, you should not use 'protected', but 'private'.

You can not use it. Its not mandatory. Of course, without child classes, its like private.

But you can also plan to use it later for extending on your vessel class and thus, use protected for providing safe seams that an extended version of your vessel could build on, without changing the original.
 
Exactly, thats what an undefined initial state looks like. Much worse, if you have differential equations somewhere near them....
 
There's this other case I'm wondering about. Do I have to initialize these 'Animstate::Action' ? That's stuff taken from the Atlantis sample, and it works as it is. But I want to keep things clean, obviously.

1764091814082.png

In the .cpp you have :

1764091946330.png
 
AFAIR not, it has a default constructor that does that.
 
Just to elaborate on some things:
'private', 'public' & 'protected' only control the "visibility"/"accessability" of class members.
They do tell nothing about their initial values!
Initialization of members should be handled regardless of there visibility.

Example:
C++:
class Pet {
  public:
    Pet () {} // <= default constructor
    Pet (int numLegs) : m_NumberOfLegs(numLegs) { }
  private:
    int m_NumberOfLegs; // < No initialization here!
}
this would make it possible to create a Pet without any clearly defined number of legs:
C++:
void main () {
  Pet cat;
  // The instance 'cat' does not have a clearly defined number of legs! It can have any value!
  // This is undefined behavour!
}

To make this at least consistent you should (MUST) clearly define what is the default value of that member. Like:
C++:
class Pet {
  public:
    Pet () : m_NumberOfLegs(4) {} // <= default constructor assumes most pets have 4 legs ;)
    Pet (int numLegs) : m_NumberOfLegs(numLegs) { }
  private:
    int m_NumberOfLegs; // < No initialization here!
}
now you can have a "regular" cat without specifying...
C++:
void main () {
  Pet cat;
  // The instance 'cat' does have a clearly defined number of legs! 4! Nothing unexpected
  Pet tom(3);
  // The Pet instance 'tom' had an accident, thus we created it special; sad but accurate
}

For how exactly you specify the initial value, there are several ways:
  1. Member Initializer List
    Like I did in my example with the colon, the member name and the initial value in round-brackets
    C++:
    class Animal {
      public:
        Animal () :m_legs(4), m_tails(1), m_eyes(2) {}
        Animal (int numLegs) : m_legs(numLegs) {}
      private:
        int m_legs;
        int m_tails;
        int m_eyes;
    }
  2. Default member initializer
    If the values are constant expressions you could also just do this:
    C++:
    class Animal {
      public:
        Animal (int numLegs) : m_legs(numLegs) {}
      private:
        int m_legs = 4;
        int m_tails = 1;
        int m_eyes = 2;
    }
  3. By code in the constructor
    If your initial values might not be constant expressions you must do it "programmatically"
    C++:
    class Animal {
      public:
        Animal () {
          m_legs = rand();
          m_tails = rand();
          m_eyes = rand();
        }
        Animal (int numLegs) : m_legs(numLegs) {}
      private:
        int m_legs;
        int m_tails;
        int m_eyes;
    }
All syntax errors in my examples are expected ;)
 
Back
Top