这个问题在这里已有答案:
起源
答案:
您有未定义的行为,因为您的操作在两个连续之间 序列点 (函数参数评估之间没有序列点)。您可以将序列点松散地视为“时间”标记,并且在两个连续的标记之间不允许多次修改同一个变量。
基本上你的代码相当于
std::cout << x << x++; // undefined behaviour
以来 y
只是一个参考(别名) x
。
1.9程序执行[intro.execution] (强调我的)
14)每一个 价值计算 和 副作用 与...相关联 full-expression在每个值计算和side之前排序 与要评估的下一个完整表达式相关联的效果。
15)除非另有说明, 评估个人的操作数 运算符和单个表达式的子表达式是 未测序。 [注意:在不止一次评估的表达式中 在执行程序期间,无序和不确定 不需要执行其子表达式的有序评估 始终在不同的评估中。 - 结束说明]价值 运算符操作数的计算在之前排序 值计算运算符的结果。 如果对a有副作用 标量对象相对于另一个副作用而言是无序的 相同的标量对象或使用值的值计算 相同的标量对象,它们不是潜在的并发(1.10), 行为未定义。 [注:下一节强制类似, 但对潜在的并发计算有更复杂的限制。 -endnote]
在调用函数时(无论函数是否为内联函数),每次调用 值计算和与任何参数相关的副作用 表达式,或使用指定被调用的后缀表达式 函数,在执行每个表达式之前排序或 被调用函数体中的语句。 [注意:价值 与不同参数相关的计算和副作用 表达式没有排序。 - 尾注]每一次评价 调用函数(包括其他函数调用)不是 否则在执行之前或之后专门排序 被调用函数的主体是不确定地被排序的 执行被调用的函数.9 C ++中的几个上下文 导致函数调用的评估,即使没有相应的 函数调用语法出现在翻译单元中。 [例如: 对new-expression的评估调用一个或多个分配和 构造函数;见5.3.4。再举一个例子,调用一个 转换函数(12.3.2)可能出现在没有的情况下 出现函数调用语法。