-1

我从 C 编译器得到以下测试代码的错误 asm 代码。这是由于未定义的行为吗?

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

什么标准说:

6.5.16 赋值运算符

操作数的求值顺序未指定。如果尝试修改赋值运算符的结果或在下一个序列点之后访问它,则行为未定义

C 运算符优先级规则

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

对于问题案例: if ( (a) || (b && c || d) == 1 ) 编译器按以下顺序计算表达式并生成错误代码

1.(b && c || 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

想知道问题案例是否属于未定义的行为类别。

问候,

苹果电脑

4

2 回答 2

7

相等运算符==的优先级高于逻辑或||运算符。因此编译器是正确的并且没有未定义的行为。

评估等同于:

a || ( ( b && c || d ) == 1 )
于 2016-07-29T09:59:48.993 回答
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 )

但是编译器编译正确。人类头脑中发生的事情并不是很明显。

于 2016-07-29T11:11:19.860 回答