这个C / C ++ if()语句是否可以评估为TRUE?

时间:2011-11-11 07:57:42

标签: c++ c if-statement conditional-statements

根据 PC-lint ,以下声明永远不会是TRUE

if((variable & 0x02) == 1)

我正在为嵌入式系统使用C编译器,只要TRUE中的相应位置位,就会将其评估为variable。我想编译器正在对TRUE的两边进行FALSE / ==比较,而不是比较得到的数字。换句话说,每次表达式(varable & 0x02)不为零(即TRUE)时,语句也将为TRUE,因为值1 is also TRUE(非零)。 / p>

我不知道C/C++标准是否清楚地定义了编译器在这种情况下的行为方式。是否有C/C++位专家可以根据标准(例如C90, C99,等)的说法回答这个问题?

P.S。:在上面的陈述中,“variable”是一个unsigned char。

6 个答案:

答案 0 :(得分:11)

PC-lint是对的。假设var是一个整数变量,表达式var & 0x02可以计算为两个值:02。它永远不会等于1,这是if语句正在测试的内容。

为了对此进行扩展,将等于运算符应用于两个整数值。重要的是两个操作数是否评估相同的数字,而不是它们是否同时“真实”或“错误”。

要测试是否设置了位1,可以使用:

if (variable & 0x02) {
  ...
}

鉴于您的编译器的行为与您所说的一样,它显然是不合规的。但是,它几乎肯定会正确处理if (variable & 0x02)。我的建议是修复代码,这样如果你要更改编译器,它就不会默默地破坏。

最后,如果出现以下情况则情况不同:(1)代码是C ++而不是C; (2)variable是一个类的实例; (3)该类使有问题的运算符超载。在这种情况下,行为可以归结为重载运算符实际执行的操作。

答案 1 :(得分:6)

在C ++中,如果(且仅当)variable是具有重载operator&且不符合正常按位AND语义的类的实例,则可以求值为真值。

在C中,这种情况总是错误的。 §6.5.10定义了按位AND运算符的语义,它非常简单,重点突出:

  

4.二进制&的结果operator是操作数的按位AND(也就是每个位   当且仅当转换的操作数中的每个相应位都是时,才设置结果   设定)。

很明显,结果不能为1,因为在右侧操作数的转换值中没有设置1位(即0x02)。

当然,如果在程序过去(或编译时)的某个时刻调用了未定义的行为,那么任何事情都可能发生。但是,除非存在这种可能性,否则您的编译器不符合要求。也就是说,破碎了。不幸的是,这在奇数嵌入式编译器上非常非常常见。如果你很幸运,你甚至可以报告错误并修复它。

答案 2 :(得分:4)

我不认为该标准对这个非常具体和不寻常的问题有任何定义。正如aix所说,该陈述永远不会成立,因为(二进制):

XXXX XXXX -> variable
0000 0010 -> 0x02
--------- AND
0000 00X0 -> result

(简化为8位类型)

所以你唯一的结果可能是0000 0010(即2)或0000 0000(即0)。

答案 3 :(得分:1)

对于C,答案是否定的。

C standard&(6.5.10):

  

二进制&的结果operator是操作数的按位AND(也就是每个位   当且仅当转换的操作数中的每个相应位都是时,才设置结果   设定)。

因为在2中只设置了位1,所以表达式的值只能设置位1.它不能使用除2和0之外的其他值.2和0都不能比较等于1

整数的位表示在6.2.6.2中定义(对于通常方式的非负值)。

答案 4 :(得分:0)

基本上,lint就在这里。至少在我所知道的任何平台上,这种情况都会产生错误。查看数字的位表示:x&对于任何整数x,2(0010)将始终为0或2(0010),因此不同于1(0001)。

答案 5 :(得分:0)

让我们考虑二进制值2

  02 = 0010 (say a 4 bit number)

,二进制值为1

  01 = 0001 

2的最小有效位始终为零,即最左边的位为0. SO
& (和)0的操作从不给1,因此我们可以说它永远不会等于1

      0 0 =>    0
      0 1 =>    0
      1 1 =>    1 

注意:&表示位和操作

   2 - 0010
   3 - 0011
       0010

所以输出xx& 2将为0或2。