在使用除float以外的其他类型进行编码时,是否应该使用'> ='而不是'=='来确保安全?

时间:2018-10-22 18:08:27

标签: c floating-point int comparison operators

使用浮点数时,应该使用

a <= 0.0

代替

a == 0.0

确保您获得期望的行为,因为使用浮点变量时round-off errors存在问题。


但是当使用诸如int之类的其他变量类型时,这样做是否有用?就像您有一个用于循环访问int变量(如索引)的for循环一样,当它到达数字时,它应该执行某些操作。当比较结果相同时,是否应该将比较设置为>=而不是==?就像在以下情况下可能不会评估==

for (int i = 0; i < 10; i++)
{
    if (i == 5)
    {
        break;
    }
}

相反,执行以下操作将是“安全的”:

for (int i = 0; i < 10; i++)
{
    if (i >= 5)
    {
        break;
    }
}

如果在“安全”编码方面两者之间没有区别,是否存在任何性能或可读性差异或其他可以在编码方式之间做出选择的事物?

试图用谷歌搜索,但是找不到任何说明。但这可能与搜索运算符有关。

我是否也很想问这个问题?

3 个答案:

答案 0 :(得分:2)

问题的前提是错误的;盲目使用a <= 0.0代替a == 0.0并不是有效的浮点操作。有关该主题的处理,请参见How dangerous is it to compare floating point values?

话虽如此,在某些情况下,使用不等式关系运算符比使用等式运算符“更坚硬”,反之亦然。通常,我建议您不要这样做,因为它可能会给您带来错误的安全感;例如,在您的问题中带有i==5i>=5的示例中,编译器很可能能够证明它们是相同的,并且可以根据需要对另一个进行优化。这意味着它不一定会采取任何措施来保护您免受堆栈溢出或中微子或任何其他原因的影响,这些原因可能导致i的值可能超出语言定义的语义之外的范围,而不是0..5。

在某些情况下,平等的使用不是由不平等定义的,特别是涉及指针的情况。如果posend都是指针,则pos==end定义良好,只要它们都有效。但是,如果它们都为null,而pos==end是定义良好且为true,则pos>=end是未定义的行为。同样,如果它们都指向不同的数组(特别是如果end指向不属于数组的哨兵),则pos==end始终为false,但是pos>=end是未定义的行为。

当您知道if (i>=5)在逻辑上是不可能的时,我还发现写i>5有误导性-它使读者停下来思考是否可能,以及为什么不这样做的if (i==5)

答案 1 :(得分:1)

答案是,这取决于。如果您有这样的循环:

MSAL

那么for (int i = 0; i < 10; i++) { if (i == 5) { break; } } 跳过i就没有危险。

另一方面,如果您有这样的事情:

5

然后volatile int i; void interrupt(void) { i++; } void foo(void) { for (i = 0; i < 10; i++) { if (i == 5) { break; } } } 可能会在程序的正常流程之外更改(例如由于中断)。在这种情况下,i是谨慎的。

答案 2 :(得分:1)

  

像可能会出现==未被评估的情况

否,使用==是安全的。整数表示准确使用的整数类型范围内的所有值。没有惊喜。

  

然后将比较设置为> =而不是==

由于结果是相同的,所以您可以两者都做,但是我会发现>=令人困惑。因此,出于可读性考虑,我更喜欢==

  

有什么表现。 。 。可以在编码方式之间做出选择

通过查看C代码无法分辨。这取决于所使用的系统(CPU)。但总的来说,我会怀疑您会遇到什么重大差异。