Foa*_*oad 2 c error-handling casting safety-critical
我得到了一个遗留代码,其中有人不小心double为int变量赋值,例如:
int a = 10;
double b = 20;
a = b;
现在摆脱
警告 C4244:“=”:从“double”到“int”的转换,可能会丢失数据
警告,我尝试在上游编辑代码并删除不必要的double变量,但结果证明太乱了!
我也可以使用铸造:
a = (int) b;
但实际上并不能保证b会在一个整数的范围内。我想过做一个辅助功能:
a = (int) b;
但我不确定这是否是最好的实现。我想知道是否有更规范的方法来处理这个问题?
我想要的是:
b变量超出整数边界的情况下,程序立即停止提前感谢您的支持。
首先,代码按原样没有任何本质上的错误或不安全。赋值转换是 C 语言的一个完全合法的部分。如果这是遗留代码,您不知道它是否安全完成,您需要进行分析以确定它。
如果您发现确实需要捕获可能的越界值(转换为 时会产生未定义的行为(!!) int),则您的代码既错误又脆弱。比较像:
double x;
...
if (x < INT_MAX) ...
强制INT_MAX输入double进行比较。实际上,在doubleIEEE 双精度和int32 位的世界中,这碰巧是安全的,但是例如如果您更改double为float,则会不安全,因为 32 位INT_MAX在单精度中无法表示float。该值将被四舍五入,然后在四舍五入后进行比较。
现在,事实证明您还有一个逐一错误(<= INT_MAX,不是< INT_MAX,是界内的)以及不正确的逻辑(||而不是&&),因此舍入实际上可以解决部分问题。但依赖它是不对的。相反,您需要制造可以比较的 2 的幂,因此转换为浮点数是安全的。例如:
if (x < 2.0*(INT_MAX/2+1) && x >= INT_MIN)if (-x > (-INT_MAX-1) && x >= INT_MIN)if (-x > INT_MIN && x >= INT_MIN)这些都假设INT_MIN实际上是 2 的幂(全范围二进制补码),这是一个合理的现实世界假设,也是 C2x+ 所要求的。如果你想要更多的普遍性,那就是更多的工作。
最后,我首先写了这个作为对你的问题的评论,但我想得越多,它真的属于一个答案:根据你的 C 熟练程度,我会非常谨慎,不要做出任何不必要的或“清理” " 更改此代码。你很可能会破坏比你修复的更多。仅在您已经完成分析以确定存在活动错误的地方进行更改,并且不要重构事物或更改类型来修复。进行简单的直接内联修复。
| 归档时间: | 
 | 
| 查看次数: | 233 次 | 
| 最近记录: |