Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cast to larger type in switch case

Tags:

c

embedded

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?

like image 519
m47h Avatar asked Dec 04 '25 09:12

m47h


2 Answers

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.

like image 168
Lightness Races in Orbit Avatar answered Dec 05 '25 23:12

Lightness Races in Orbit


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:

  • Do you actually know what implicit promotions there are in a switch statement and did you consider what impact they might have on this code?
  • Do you know the meaning of the integer promotion rules? Did you know and consider that an uint8_t will get promoted to a (signed) int in this code?
  • Do you use a coding standard and static analysis tools at all, yourself?
like image 29
Lundin Avatar answered Dec 06 '25 00:12

Lundin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!