【问题标题】:Order of evaluation: undefined behavior? or compiler defect?评估顺序:未定义的行为?还是编译器缺陷?
【发布时间】:2016-12-03 23:54:33
【问题描述】:

我从 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

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

问候,

苹果机

【问题讨论】:

  • 关于您的 C 运算符优先级规则的评论:&& 的优先级高于 ||,因此它们不必在同一行跨度>
  • 如果你想得到你的“预期结果”,你似乎缺少一组括号
  • 寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅:如何创建最小、完整和可验证的示例。
  • 如果您认为任何答案回答了您的问题,请考虑接受(答案左侧的灰色复选标记)。

标签: c undefined-behavior ansi unspecified-behavior


【解决方案1】:

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

评估等同于:

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

【讨论】:

    【解决方案2】:

    这个:

     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 )
    

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

    【讨论】:

      猜你喜欢
      • 2013-06-28
      • 2012-06-26
      • 2010-11-24
      • 2012-09-28
      • 2013-09-17
      • 2011-07-10
      • 2011-02-06
      • 1970-01-01
      • 2017-03-03
      相关资源
      最近更新 更多