评估表达式的结果是unspecified,因为 和 的评估x
是fun(&x, &y)
不确定的。
请注意,允许表达式评估产生未指定的结果并不意味着您的程序具有未定义的行为;相反,这意味着您无法判断该表达式的评估将产生有限的一组可能结果中的哪一个。
在这里解释标准可能非常棘手(事实上,在最初的答案中,我以错误的方式解释了它 - 感谢Jerry Coffin的注意)。
要了解为什么这很棘手,让我们考虑 C++11 标准第 1.9/15 段的第一部分:
除非另有说明,否则单个运算符的操作数和单个表达式的子表达式的求值是未排序的。[...]运算符的操作数的值计算在运算符结果的值计算之前排序。如果标量对象上的副作用相对于同一标量对象上的另一个副作用或使用同一标量对象的值的值计算是未排序的,则行为是未定义的。
例如,给定一个包含计算两个子表达式之和的表达式,例如(考虑operator +
这里没有重载):
e1 + e2
如果 的 评估e1
使用某个标量 的值s
,并且 的评估e2
对该值有副作用,则行为未定义。例如,评估:
(i + i++)
由于上面引用的句子,给出了未定义的行为。
但是,您的情况有所不同。稍后的同一段指定:
当调用一个函数时(无论该函数是否是内联的),[...]调用函数(包括其他函数调用)中的每个评估,在被调用函数的主体执行之前或之后没有特别排序关于被调用函数的执行顺序不确定。
这意味着如果要评估的表达式如下所示:
i + f(i)
和f(i)
increments i
,行为不再是 undefined ,而只是unspecified。换句话说,您的编译器可以按任何顺序进行评估i
,f(i)
但可能的结果只是这些可能评估之一的结果。
另一方面,如果行为未定义,则可能的结果将是任何结果(从崩溃到按您预期的行为,到在控制台上打印奇怪的消息等等)。