During work i saw the following code snippet and now i wonder, if there is a reason for casting the "case-values" to a larger datatype. I guess, that it is used to offer the possibility of having more than 256 different states later on, but then, the state variable must also be larger. Here is the code i am talking about:
#define STATE_1 (uint8_t)(0x00)
#define STATE_2 (uint8_t)(0x01)
...
#define STATE_n (uint8_t)(0x..)
void HandleState(uint8_t state)
{
switch(state)
{
case (uint16_t)STATE_1:
// handle state 1
break;
case (uint16_t)STATE_2:
// handle state 2
break;
...
case (uint16_t)STATE_n:
// handle state n
break;
default:
break;
}
}
Is there another reason for this?
Is there another reason for this?
No.
It's either a mistake, muppetry, or legacy (perhaps state and the macros used to be something else, but this particular code never got changed?).
I'm voting for muppetry, personally. Sometimes you run into code that somebody else wrote that is bad code, and that's just the way it is.
It looks like a slightly failed attempt to get rid of implicit integer promotions on a 8-bit or 16-bit microcontroller.
First of all, there is no way integer promotion can cause harm here, so preventing it is overly pedantic and just reduces readability. At a glance it looks like nonsense.
But.
Perhaps the coding standard used enforced that no implicit conversions are allowed? Which for example MISRA-C does. In that case, the code suddenly makes sense: they wished to surpress warnings from their static analysis tool.
Using explicit casts would then also be a way of demonstrating that you are actually aware of implicit type promotions (something that only a handful of C programmers are, sadly) and that you handle them in your code.
But if so, the programmer missed out one integer promotion taking place, namely here: switch(state). This is how switch statements work:
The integer promotions are performed on the controlling expression. The constant expression in each case label is converted to the promoted type of the controlling expression.
So if the programmer was concerned about implicit promotions, they should have written the code as switch((uint16_t)state) and then also kept the casts in each case.
If you sneered at the code in the question, consider the following:
uint8_t will get promoted to a (signed) int in this code?If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With