How to handle invalid input in a function that returns a bool?

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What are the best practices for handling invalid input in functions that return a bool?  In functions that return an int, I can return an enum error code, but with a function that returns a bool that's obviously not going to work.  Here's an example to further illustrate my question.

 

typedef enum Error_Codes {
    INVALID_PROTOCOL = -120
} Error_codes;

typedef enum Protocol_Type {
    UNKNOWN,
    ANOTHER_PROTOCOL,
    NEC
} Protocol_Type;

int calculate_stuff(Protocol_Type protocol) {
    if(protocol == NEC) {
        //do stuff
    } else if (protocol == UNKNOWN) {
        //do different stuff
    } else {
        return INVALID_PROTOCOL;
    }
}

bool transmits_msb_first(Protocol_Type protocol) {
    if(protocol == NEC) {
        return true;
    } else if (protocol == ANOTHER_PROTOCOL) {
        return false
    } else {
        //this will only happen if invalid input is sent to the function
        //how can I let the caller of this function know something went wrong?
    }
}

How do you guys handle these sorts of scenarios?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
//how can I let the caller of this function know something went wrong?

 

If you want to return more than true and false, you need something bigger than a bit.

 

Or you could send a pointer to an int to the bool func() and put the status in the int:

bool transmits_msb_first(Protocol_Type protocol, int* status) {
    if(protocol == NEC) {
        return true;
    } else if (protocol == ANOTHER_PROTOCOL) {
        return false
    } else {
        *status = SOME_ENUM;
    }
}

 

Greg Muth

Portland, OR, US

Xplained/Pro/Mini Boards mostly

 

Make Xmega Great Again!

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Agree with Greg about the return code passed by reference but it does then make you wonder why this function really needs TWO returns? What purpose does the bool actually serve if you are providing more detail by the return code anyway? Is the use of bool purely so you can use it in the construct:

if (transmits_msb_first(NEC)) {
    ...
}

You might as well just have the single, wider return:

if (transmits_msb_first(NEC) == OK_RESULT) {
    ...
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't like the solution with reference to the status variable because there is large overhead of code (both source and binary) required to handle it. I prefer one of the following:

1. Use enum instead of bool, for example: enum { order_msb_first, order_msb_last, order_unknown }. Size of the result value is still 1 byte, as for bool. You can use one switch/case for checking the result instead of separate if-s for status and result.

2. Change the transmits_msb_first function so it doesn't handle the incorrect argument, for example:

bool transmits_msb_first(Protocol_Type protocol) {
    if(protocol == NEC) {
        return true;
    } else {
        return false
    }
}

and check for correct protocol prior to calling transmits_msb_first function. The second solution is good if protocol value is used in more than once. In such situation you have to check for correct protocol at the beginning and rest of the code can assume that it is correct.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Try to avoid more than one return in a function. For your latter code:

bool transmits_msb_first(Protocol_Type protocol) {
    bool retval;
    if(protocol == NEC) {
        retval = true;
    } else {
        retval = false;
    }
    return retval;
}

(and, no, this won't generate any more code - in fact the likelihood is that it may be more efficient).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
return protocol == NEC;

Iluvatar is the better part of Valar.