mr_T
mr_T

Reputation: 2631

how to check whether a boolean is uninitialized in c++?

I want to create a caching for some (hard to calculate) boolean properties of an object. The structure I had in mind is the following:

   class Obj; 
   struct ObjProperties
   {
       bool property1;
       bool property2;
       // etc.
   };
   std::unordered_map<const Obj*, ObjectProperties> cache;

Now I want to have functions that go something like

bool hasProperty1()
{
    if /*(cache[property1] is uninitialized)*/
         cache[property1] = calculateProperty1();
    return cache[propery1];
}

Yet how could I check whether a boolean is uninitialized? Property1 can be either true or false, so I cannot initialize it to a value...

I see two ways to deal with this:

1) make the members of my struct bool* pointers. Then I could check for nullptr, but this makes my functions a bit more cumbersome as I have to new/delete all my boolean objects

2) make the members of my struct int. Then I could initialize them as -1 and assign 0 (false) or 1 (true). But this makes my code a bit less obvious. After all, these properties are boolean, and my cache struct contains in reality also some (real) ints and doubles.

What would be the best way to deal with this? or am I overlooking some very straightforward test to check whether a boolean is uninitialized?

Upvotes: 1

Views: 689

Answers (3)

Valeri Atamaniouk
Valeri Atamaniouk

Reputation: 5163

If you have just couple of properties:

class ObjProperties
{
  bool property1;
  bool property1_valid;
  bool property2;
  bool property2_valid;

  ObjProperties() : property1_valid(false), property2_valid(false)
  {}
}

You can implement a special property type:

struct BoolProperty
{
  bool value;
  bool valid;
  BoolProperty() : value(false), valid(false) {}
  BoolProperty(bool value) : value(value), valid(true) {}
  BoolProperty &operator=(const bool &arg)
  {
     value = arg;
     valid = true;
  }
  bool isValid() const { return valid; }
  ...
}
class ObjProperties
{
  BoolProperty property1;
  BoolProperty property2;
}

Or you can use some bit fields:

class ObjProperties
{
  bool property1;
  bool property2;
  int property1_valid:1;
  int property2_valid:1;
}

Upvotes: 1

user2249683
user2249683

Reputation:

You can not enforce initialization of built-in types, but you might use a wrapper instead (and if paranoid, query for that):

/// Initialize a type with zero.
template <typename T>
struct Zero
{
    T value;
    operator const T& () const { return value; }
    operator T& () { return value; }

    Zero()
    :   value(0)
    {}

    Zero(const T& initializer)
    :   value(initializer)
    {}
}; 

struct Some
{
    Zero<bool> property;
};

The above ensures zero (false) initialization, only. You may alter the template to support true (too), or choose names which reflect the false state (uppercase vs. no_uppercase)

Having C++11, I prefer:

struct Some
{
    bool property = false;
};

And have a non well defined behavior if the member is not initialized.

Upvotes: 1

Thomas Matthews
Thomas Matthews

Reputation: 57749

You can't immediately find out if a POD type is initialized or not. The memory that the compiler assigns the variable to will have a value; whether it's valid or not, is up to you.

One method to tell if variables are initialized or not is to use a bool variable.

Another preferred method is to always initialize them in the constructor of the struct, class or function.

Edit 1:
If you define a variable as static, it will be either initialized before main (as with global variables) or upon the first entry into the function.

In your case, I strongly recommend you create a constructor method that initializes the variables in the struct.

Upvotes: 0

Related Questions