在开关盒中铸造成更大的类型

时间:2015-06-25 15:28:03

标签: c embedded

在工作期间,我看到了以下代码片段,现在我想知道,如果有理由将“case-values”转换为更大的数据类型。我猜,它用于提供以后有超过256个不同状态的可能性,但是,状态变量也必须更大。 这是我正在谈论的代码:

google.maps.LatLng

还有其他原因吗?

4 个答案:

答案 0 :(得分:6)

  

还有其他原因吗?

没有

这是一个错误,muppetry或遗留(可能是state,而宏曾经是其他东西,但这个特殊代码永远不会改变?)。

我个人投票支持muppetry。有时候你会遇到别人写的那些代码不好的代码,而这就是它的样子。

答案 1 :(得分:2)

看起来在8位或16位微控制器上摆脱隐式整数提升的尝试略显失败。

首先,整数提升不会在这里造成伤害,所以防止它过于迂腐,只会降低可读性。一眼就看起来像废话。

但是

也许强制使用的编码标准不允许隐式转换?例如MISRA-C。在这种情况下,代码突然变得有意义:他们希望通过静态分析工具来抑制警告。

使用显式强制转换也可以证明你实际上已经知道了隐式类型的促销(遗憾的是只有少数几个C程序员)并且你在代码中处理它们。

但如果是这样,那么程序员就会错过一次整数推广活动,即:switch(state)。这就是switch语句的工作原理:

  

对控制表达式执行整数提升。常数   每种情况下的表达式标签都会转换为控件的提升类型   表达

因此,如果程序员关注隐式促销,他们应该将代码编写为switch((uint16_t)state),然后在每个case中保留转换。

如果你嘲笑问题中的代码,请考虑以下事项:

  • 你真的知道switch语句中有哪些隐式促销,你是否考虑过它们可能对这些代码产生什么影响?
  • 你知道整数推广规则的含义吗?您是否知道并认为uint8_t会在此代码中升级为(已签名)int
  • 您自己使用编码标准和静态分析工具吗?

答案 2 :(得分:1)

这看起来就像是糟糕的风格。你应该有一个typedef状态:

typedef uint8_t State;

然后你的代码看起来像这样:

#define STATE_1 (State)(0x00)
#define STATE_2 (State)(0x01)
...
#define STATE_n (State)(0x..)

void HandleState(State state)
{
  switch(state)
  { 
    case (State)STATE_1:
      // handle state 1
      break;

    case (State)STATE_2:
      // handle state 2
      break;

    ...
    case (State)STATE_n:
      // handle state n
      break;

    default:
      break;
  }

}

然后,如果您以后发现需要uint16_t,则只需更改一行。

答案 3 :(得分:1)

它可能旨在为比较强制执行unsigned int类型提升,但unit16_t也不能保证大小相同,只是转换状态就足够了。

也许状态代码是以前版本中的枚举标签?默认情况下这些是int - 但即使这样,演员也没什么意义。

请注意,演员阵容甚至可能会抑制有关不适当大小的警告。最好是使用枚举,或#define标签只是未签名,例如0x00U没有修复类型。