mis*_*coo 1 c++ undefined-behavior unspecified-behavior
我只知道i = i++;是未定义的行为,但如果在表达式中调用了两个或更多函数,并且所有函数都相同.这是不确定的?例如:
int func(int a)
{
std::cout << a << std::endl;
return 0;
}
int main()
{
std::cout << func(0) + func(1) << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Jim*_*hel 12
表达的行为func(0) + func(1)是,所述结果将是通过调用所获得的结果的总和定义func同的参数0和func与一个参数1.
但是,调用函数的顺序可能取决于实现,尽管可能未指定.也就是说,编译器可以生成相当于的代码:
int a = func(0);
int b = func(1);
int result = a + b;
Run Code Online (Sandbox Code Playgroud)
或者它可以生成:
int a = func(1);
int b = func(0);
int result = a + b;
Run Code Online (Sandbox Code Playgroud)
除非func副作用取决于呼叫顺序,否则这通常不会成为问题.
这个程序的行为不是未定义的,而是未指定的,如果我们看一下C++ 标准草案1.9 的程序执行第15段说(重点是我的):
\n\n\n除非另有说明,否则各个运算符的操作数和各个表达式的子表达式的求值都是无序的。[ 注意:在程序执行期间多次求值的表达式中,其子表达式的无序和不确定顺序求值不需要在不同的求值中一致地执行。\xe2\x80\x94end note ] 运算符操作数的值计算先于运算符结果的值计算排序。如果标量对象上的副作用相对于同一标量对象上的另一个副作用或使用同一标量对象的值的值计算而言是无序的,则该行为是未定义的。
\n
如果我们检查涵盖的5.7 加法运算符+部分,并且-该部分没有指定顺序,因此它是无序的。
在这种情况下func会产生副作用,因为它正在输出stdout,因此输出的顺序将取决于实现,甚至可能会因后续评估而改变。
请注意,表达式语句的;末尾和“表达式语句”部分表示:6.2
\n\n\n[...]表达式语句的所有副作用都会在执行下一条语句之前完成。[...]
\n
因此,尽管函数调用的顺序未指定,但每个语句的副作用都会在下一个语句之前完成。
\n