以下具有未指定的结果,因为未指定评估顺序:
std::string f() {
std::cout << "f()";
return "";
}
std::string g() {
std::cout << "g()";
return "";
}
int main() {
std::cout << f() << g();
}
// Output: "f()g()" or "g()f()".
不过,据我所知,它并没有调用未定义的行为。
但是,在序列点之间修改变量两次肯定是 UB,例如:
int main() {
int x = 0;
std::cout << x++ << x++;
}
现在,该规则是否仅适用于当前范围,还是以下内容也是 UB?
int foo() {
static int x = 0;
x++;
return x;
}
int main() {
std::cout << foo() << foo();
}
// Output: "12" or "21", or is it undefined?
我问的原因是我的 GCC 4.7.0 20111217 没有在代码段 3 上发出警告,但是(当然)会在代码段 2 上发出警告。
最佳答案
调用函数和从函数返回都是序列
点,因此您在一个功能中所做的任何事情都不会与您所做的发生冲突
在另一个(即使调用函数的顺序是
未指定)。
请注意,在这方面,用户定义的运算符重载是函数,
并引入内置的序列点
类型。所以像 cout << i++ << i++
这样的东西不是未定义的
如果 i
是用户定义的类型(例如具有用户定义的枚举)的行为operator++
)。 (但是,该顺序仍未指定,并且只是
因为定义了行为并不意味着代码是可读的
或推荐。)
关于c++ - 由于在序列点之间修改变量两次而导致的 UB 是否会延续到 "inner"范围?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8603055/