Order of Evaluation
void solve() {
int n;
cin >> n;
vector<int> pr(n + 1), ne(n + 1);
auto conn = [&](int x, int y) {
pr[y] = x;
ne[x] = y;
};
auto dis = [&](int x, int y) {
pr[y] = 0;
ne[x] = 0;
};
auto out = [&](int x) {
while (ne[x] != 0)
x = ne[x];
int cnt = 1;
while (pr[x] != 0) {
++cnt;
x = pr[x];
}
cout << cnt << " ";
while (x != 0) {
cout << x << " ";
x = ne[x];
}
cout << "\n";
};
int q;
cin >> q;
for (int i = 0; i < q; i++) {
int t;
cin >> t;
if (t == 1) {
conn(RI, RI);
} else if(t == 2) {
dis(RI, RI);
} else {
out(RI);
}
}
}
其中 RI
是一个宏,它的定义是
#define RI \
([] { \
int x; \
std::cin >> x; \
return x; \
})()
上面那个程序运行时,函数调用 conn(RI, RI)
里两个参数的求值顺序(order of evaluation)是不确定的,可能是第一个参数先求值,也可能是第二个参数先求值。这个行为在 C++ 标准里是有说明的。
C++17 standard draft, Section 8.2.2 Function call
A function call is a postfix expression followed by parentheses containing a possibly empty, comma-separated list of initializer-clauses which constitute the arguments to the function. …
When a function is called, each parameter shall be initialized with its corresponding argument. …
The postfix-expression is sequenced before each expression in the expression-list and any default argument. The initialization of a parameter, including every associated value computation and side effect, is indeterminately sequenced with respect to that of any other parameter.