dbu*_*ush 12 c casting undefined-behavior
我uint16_t在网络协议中使用a 作为序列计数器.这个计数器通常会按预期包装.当接收器获取数据包时,它会根据最近收到的数据来检查此计数器,以查看它是新数据包还是无序数据包.
比较序列号时需要考虑环绕声.因此,如果例如最后的序列号为0x4000,然后从一个序列号0x4001,以0xBFFF较新,且从一个序列号0xC000,以0xFFFF和0x0000到0x3FFF更小.
我目前正在这样做的方式如下:
uint16_t last;
uint16_t current;
...
// read in values for last and current
...
if ((int16_t)(current - last) > 0) {
printf("current is newer\n");
} else {
printf("current is older (or same)\n");
}
Run Code Online (Sandbox Code Playgroud)
通过减去两者并将结果视为a int16_t,我可以很容易地看出哪个更大,哪个更多.因此,例如,如果当前序列号比最后一个序列号少至少5,即((int16_t)(current - last) < -5),我可以假设这不是由于正常的分组重新排序和丢弃分组.
我意识到签名的环绕是未定义的,但是在这种情况下,为了进行比较,我将无符号值视为已签名.这是否会调用未定义的行为,如果是这样,那么进行此类比较的更好方法是什么?
超出范围转换的行为是实现定义的.
你为什么不完全避免这个问题,并写道:
if ( current != last && current - last < 0x8000 )
printf("current is newer\n");
else
printf("current is older (or same)\n");
Run Code Online (Sandbox Code Playgroud)
注意:此答案仅适用于涉及的具体问题uint16_t.对于其他类型,将需要不同的代码.
| 归档时间: |
|
| 查看次数: |
463 次 |
| 最近记录: |