"return i++, i, i++;" 是 C 中未定义的行为吗?

Is "return i++, i, i++;" undefined behaviour in C?

如果我这样写:

i = i++, i, i++;

在C语言中是未定义的行为

但是,如果我这样写:

return i++, i, i++; // Is it UB?

这是未定义的行为吗?

示例:

#include <stdio.h>

int f(int i)
{
    return i++, i, i++; // Is it UB?
}
int main() {
    int i = 1;
    i = i++, i, i++;

    i = f(i);
    printf("%d\n",i);
    return 0;
}
return i++, i, i++;

不,这不是未定义的行为,因为逗号运算符定义了一个序列点,它将对 i.

的修改访问分隔开来

因此这段代码等同于:

i++;        // The left-most subexpression
i;
return i++; // The right-most subexpression

比较:

i = i++, i, i++;

这个 未定义的行为,因为 , 的优先级低于 =,所以它等同于:

(i = i++), i, i++;

并且 i = i++ 是未定义的行为(有关此特定情况的更多信息,请参阅 this 问题)。

i = i++, i, i++; 是 UB,因为 = 的优先级高于 ,,因此表达式被解析为 (i = i++), i, i++,其中子表达式 i = i++ 调用UB1).

即使代码写成i = (i++, i, i++);仍然是UB,因为现在最右边的[=17]之间没有序列点=]和i=的左操作数1).

但是,当您删除 i = 部分时,您就删除了这种不明确的行为。 return i++, i, i++; 必须 排序为:

i++, the left one
sequence point from left comma
i
sequence point from right comma
i++, the right one
sequence point before returning

所以定义明确。


来源:

1) C11 6.5/2

If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.

然后还有C11 6.5.16/3

The side effect of updating the stored value of the left operand is sequenced after the value computations of the left and right operands. The evaluations of the operands are unsequenced.

值得注意的是,上面关于赋值的文本在 C11 和 C++11 之间是不同的。