2016-07-29 93 views
-1

我得到错误的汇编代码从C编译器下面的测试代码。 这是由于未定义的行为?评估顺序:未定义的行为?或编译器缺陷?

void SimulatedTest(void) 
{         
    if ((a) || (b && c || d) == 1) 
    { 
     i = 2; 
    } 
    else 
    { 
     i = 4; 
    } 
} 

什么标准说:

6.5.16赋值运算符

操作数的评价的顺序是不确定的。如果试图 作出修改赋值运算符的结果,或者下一个序列点之后访问它 ,行为是不确定

C运算符优先级规则

  1. ()
  2. ==
  3. || & &

对于该问题的情况下:如果((A)||(B & &Ç|| d)== 1) Compiler将评估以下顺序在表达和产生错误的代码

1.(b & &ç|| d) - > R1

2.R1 == 1 - > R2

3.(A)|| R2

但是编译器生成正确的代码用于以下情况

案例1:。当没有关系 '==' 操作

if ((a) || (b && c || d))//compiler generates expected code 

情况2:当括号中加入用于逻辑或运算

if (((a) || (b && c || d)) == 1)//compiler generates expected code 

情形3:操作之间没有使用括号

if (a || b && c || d == 1)//compiler generates expected code 

想知道这个问题是否情况下,不确定的行为属于类或不。

问候,

的Mac

+1

关于您的_C运算符优先级rule_:'&&'的优先级高于'||',因此它们不必位于同一行上 – Garf365

+0

如果您想要,您似乎缺少一组圆括号得到你的'预期结果' – Shark

+0

寻求调试帮助的问题(“为什么不是这个代码工作?”)必须包括所需的行为,特定的问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题陈述的问题对其他读者无益。请参阅:如何创建最小,完整和可验证示例。 – Olaf

回答

7

相等运算==具有比所述逻辑或运算符||更高的优先级。因此编译器是正确的,没有未定义的行为。

的评价是相同的:

a || ((b && c || d) == 1) 
0

此:

if ((a) || (b && c || d) == 1) 

||的结果与一个整数,而决不是你想要做什么比较。

规定的逻辑运算符的优先顺序,这并不总是人们期望的那样,它通常是最安全的括号内甩出去让事情更清晰的读取,从而

if ((a) || ((b && c) || d) == 1) 

if ((a) || (b && (c || d)) == 1) 

来处理&&||

并取决于你期望==与之比较(如果你真的要做到这一点,我怀疑)

if ((a) || ((b && c || d) == 1)) 

if (((a) || (b && c || d)) == 1) 

但编译器编译权。这对于人类心灵意味着什么并不是非常明显。