1

这是Deep C的一个例子(幻灯片 194)

int a = 41;
a++ & printf("%d\n", a);

该演示文稿声称结果未定义。为什么?a在序列点之间只分配一次。我认为a++and之间的执行顺序printf是未指定的,因此这将在所有符合要求的编译器上打印 41 或 42 ,而没有未定义的行为。

4

2 回答 2

5

在这一行 -a++ & printf("%d\n", a);只有一个序列点(不计算函数参数中发生的事情 - 因为a++1发生在这一行本身) - 修改变量并在单个序列点内同时读取它是 UB。如果从对象中读取了先前的值但也有修改,则行为未定义,如i * i++

&&是一个序列点,&如果那是您感到困惑的地方,则不是序列点。

序列点是尘埃落定的时间点,到目前为止已经看到的所有副作用都保证是完整的。C标准中列出的序列点是:

在完整表达式的评估结束时(完整表达式是表达式语句,或任何其他不是任何更大表达式中的子表达式的表达式);在 ||、&&、?: 和逗号运算符处;并在函数调用中(在评估所有参数之后,就在实际调用之前)。

该标准指出

在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的评估修改一次。此外,只能访问先验值以确定要存储的值。

于 2013-10-24T11:16:32.160 回答
3

位运算符&不引入序列点,因此这确实是未定义的行为。

于 2013-10-24T11:16:18.680 回答