我从C编译器得到了以下测试代码的错误asm代码。这是由于未定义的行为吗?
void SimulatedTest(void)
{
if ( (a) || (b && c || d) == 1 )
{
i = 2;
}
else
{
i = 4;
}
}
什么标准说:
6.5.16分配运算符
操作数的求值顺序未指定。如果尝试用于修改赋值运算符的结果或访问它在下一个序列点之后,行为未定义
C运算符优先级规则
- ()
- ==
- ||&
对于问题情况:如果((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:为逻辑OR运算添加括号时
if ( ((a) || (b && c || d)) == 1 )//compiler generates expected code
情况3:操作之间不使用括号
if ( a || b && c || d == 1 )//compiler generates expected code
想知道问题案例是否属于未定义的行为类别。
问候,
Mac
Equality运算符==
的优先级高于逻辑运算符或||
运算符。因此,编译器是正确的,不存在未定义的行为。
评估与相同
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) )
或
if ( ((a) || (b && c || d)) == 1 )
但是编译器是正确编译的。人类的心理到底会发生什么,这并不十分明显。