Can you do better than returning a bool?

It’s very common to write functions that do something or check something and then return “ok” or “failed”.

When writing such functions one’s instinct is often to return a bool value. Let’s think of some hardware that monitors a digital input coming from a switch which is active when a valve is open.

We might declare the function as follows:

bool ValveLimitSwitchIsActive(void);

This is a sensible choice, the digital input can only be either active or inactive (any other condition must be a hardware failure) and our function matches this physical reality.

But what about if we want to check if the valve is open? We could declare a function as follows:

bool ValveIsOpen(void);

Great! we can now start to write code that works with the valve, using this function as required. All looks good? Perhaps not. Perhaps we have an operation on our plant which demands that the valve is definitely energised (could be safety critical) as well as being fully open. Perhaps we also want to monitor how long it takes for the valve to actually open. We could generate more functions:

bool ValveIsFullyOpenAndEnergised(void);
bool ValveIsEnergised(void);

but it all gets a bit messy….

How about

enum class TValveState {FullyClosed, Closing, Opening, FullyOpen};
// Opening == energised but not yet reached fully open limit switch

TValveState GetValveState(void);

This is good because all the valve checking is in one place. If the design of the valve interface changes we only have to modify this one function.

This still has good clear legibility at when the function is called; no one can be confused by:

if (GetValveState(void) == FullyClosed) { // do something here }

Because of this form of calling, the same technique is also very useful when dealing with functions that are harder to name in such a way that a bool return value makes sense. Consider a database update. We could have a function

bool UpdateDatabase(…); // returns true if update was successful

We call this using:

if (UpdateDatabase(…)) { // do something here – task }

This works, but if you come back to this code do you know if the task is executed if the update was successful, or if it was unsuccessful? The only way to be sure is to back to the body of the function UpdateDatabase – very bad from a programming maintenance perspective.

A simple improvement would be to write

bool UpdateDatabaseWasSuccessful(…)

but now you have a function name that suggests a status check on the database, it rather hides the fact that an action is actually carried out.

Much better is to use:

enum class TDatabaseUpdateResult {UpdatedOk, FailedToUpdate};

TDatabaseUpdateResult UpdateDatabase(…);

Now the call is fairly concise and very clear:

if (UpdateDatabase(…) == UpdatedOk) { // do something here – task }

Again, if we later decide to return more error information (perhaps different reasons why the update failed) we can simply add extra enum names.

We could even change the enum to a full blown class and return this, if we needed to.

It’s a good technique: use it!