请解释这种模棱两可的情况

Please explain this ambiguity?

本文关键字:情况 模棱两可 解释      更新时间:2023-10-16

可能重复:
使用std::cout 评估参数的顺序

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
static int series_num;
void setint(int num) {
    series_num = num;
}
int ser() {
    series_num = series_num + 23;
    return series_num;
}
int main() {
    setint(50);
    cout << ser() << " " << ser();
    getchar();
    getchar();
    return 0;
}

返回我96 73

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
static int series_num;
void setint(int num) {
    series_num = num;
}
int ser() {
    series_num = series_num + 23;
    return series_num;
}
int main() {
    setint(50);
    cout << ser();
    cout << ser() << endl;
    getchar();
    getchar();
    return 0;
}

返回我73和96

 cout << ser() << " " << ser();

这里有两个对ser()的调用,它们之间没有任何序列点
因此,尚不明确将首先评估什么。

相反,在你的第二个例子中,行为是明确定义的和可预测的。

在第一种情况下,您使用一个序列对ser()进行两次调用,这些调用是从右到左进行的,因此您有9673。

在第一种情况下,

cout << ser() << " " << ser();

相当于:

operator<<(cout.operator<<(ser()),"").operator<<(ser());

是一个完整的表达。单个运算符的操作数和单个表达式的子表达式的求值是无序列的。因此,对ser()的两个调用的执行顺序是未定义的。

你唯一知道的是:

  1. 对ser()的第一次调用是在插入cout之前执行的
  2. 对ser()的第二次调用是在插入cout之前执行的
  3. 之前执行的对ser()的调用是未定义的(它们是未排序的)

因此,一个实现返回96 73并且不同的实现返回73 96是有效的。

此外,在执行过程中多次求值的表达式中对于一个程序,其子表达式的无序列和不确定序列的求值不需要在不同的求值中一致地执行。这允许如果表达式

cout << ser() << " " << ser();

在一个程序中运行两次,选择不同的顺序。

在第二个程序中。

cout << ser();
cout << ser() << endl;

是两个完整的表达式(在两个单独的语句中)。在这种情况下,第一个语句在第二个语句之前排序,因为与完整表达式相关联的每个值计算和副作用都在与要评估的下一个完整表达式相关的每个值运算和副作用之前排序。

因此,唯一可能的结果是7396。