在工作期间,我看到了以下代码片段,现在我想知道,如果有理由将“case-values”转换为更大的数据类型。我猜,它用于提供以后有超过256个不同状态的可能性,但是,状态变量也必须更大。 这是我正在谈论的代码:
google.maps.LatLng
还有其他原因吗?
答案 0 :(得分:6)
还有其他原因吗?
没有
这是一个错误,muppetry或遗留(可能是state
,而宏曾经是其他东西,但这个特殊代码永远不会改变?)。
我个人投票支持muppetry。有时候你会遇到别人写的那些代码不好的代码,而这就是它的样子。
答案 1 :(得分:2)
看起来在8位或16位微控制器上摆脱隐式整数提升的尝试略显失败。
首先,整数提升不会在这里造成伤害,所以防止它过于迂腐,只会降低可读性。一眼就看起来像废话。
但是
也许强制使用的编码标准不允许隐式转换?例如MISRA-C。在这种情况下,代码突然变得有意义:他们希望通过静态分析工具来抑制警告。
使用显式强制转换也可以证明你实际上已经知道了隐式类型的促销(遗憾的是只有少数几个C程序员)并且你在代码中处理它们。
但如果是这样,那么程序员就会错过一次整数推广活动,即:switch(state)
。这就是switch语句的工作原理:
对控制表达式执行整数提升。常数 每种情况下的表达式标签都会转换为控件的提升类型 表达
因此,如果程序员关注隐式促销,他们应该将代码编写为switch((uint16_t)state)
,然后在每个case
中保留转换。
如果你嘲笑问题中的代码,请考虑以下事项:
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
没有修复类型。