【发布时间】:2015-07-30 01:32:39
【问题描述】:
以下代码是否会调用 C 中的未定义行为?
int a = 1, b = 2;
a = b = (a + 1);
我知道以下确实调用了 UB:
a = b = a++;
原因是它违反了标准中的以下条款:
在前一个序列点和下一个序列点之间,一个对象应该有它的 表达式的评估最多修改一次存储的值。 此外,应仅访问先验值以确定 要存储的值。
但是,第一个sn-p 并不违反此条款。一位同事说声明a = b = a+1 可能意味着任一
a = a + 1;
b = a + 1;
或
b = a + 1;
a = b;
我认为由于= 的“从右到左”的关联性,它总是意味着a = (b = (a+1)),而不是
a = a + 1;
b = a + 1;
不过,我并不积极。是UB吗?
【问题讨论】:
-
您对关联定律是正确的。表达式
b = (a+1)的结果是b在赋值之后将取的值(尽管赋值在评估之前没有排序,无论如何在C11 之前,但这在这里无关紧要)。 -
赋值表达式的值是左操作数的值(赋值后)。所以,你的同事错了——它只能指第二个。
-
该副本与问题无关。但是,这可能是重复的:stackoverflow.com/questions/19353686/…
-
@gopi 恕我直言,这不是重复的。显然,OP知道
a = a++是UB,他想知道a = b = (a + 1);是否也是UB。 -
请注意,
a = a = a +1的定义并不明确。因为在同一个表达式中对同一个变量有两个副作用,中间没有序列点。当然,如果你根本不使用这种称为“多重赋值”的危险、完全愚蠢和完全多余的功能,就不会有任何问题,也不会造成任何混乱。
标签: c undefined-behavior