libzypp: Code Pitfalls - Frequently made mistakes

libzypp 17.38.5

Code Pitfalls - Frequently made mistakes

# Comparing TriBool values

Comparing two TriBool values is not as easy as it might look like, because the `TriBool::operator==` and `TriBool::operator!=` return a TriBool.

For example is (indeterminate==indeterminate) not `true`, but `indeterminate`. That's why the following snippet does not do what the author expected:

// buggy option class
struct Option
{
public:
Option()
: _value( indeterminate )
{}
bool get() const
{ return ( _value == indeterminate ) ? true : bool(_value); }
void set( bool new_r )
{ _value = new_r; }
private:
tribool _value;
};
bool
zypp::Option::get
const value_type & get() const
Get the value.
Definition ZConfig.cc:389
zypp::Option::set
void set(value_type newval_r)
Set a new value.
Definition ZConfig.cc:397
zypp::Option::Option
Option(value_type initial_r)
No default ctor, explicit initialisation!
Definition ZConfig.cc:381

You find that `get()` returns `false` as long as the option is unset, and not `true` as the code suggests. That's because (_value==indeterminate) returns `indeterminate`.

Note
  Always use `indeterminate(_value)` to test whether a TriBools value is `indeterminate:`

bool get() const
{ return indeterminate( _value ) ? true : bool(_value); }
tribool _value;
...
if ( indeterminate( _value ) )
{ ... } // indeterminate
else if ( _value )
{ ... } // true
else
{ ... } // false