Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Is func()+;func()未定义的行为?_C++_Undefined Behavior_Unspecified Behavior - Fatal编程技术网

C++ Is func()+;func()未定义的行为?

C++ Is func()+;func()未定义的行为?,c++,undefined-behavior,unspecified-behavior,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; } int func(int a) { st

我只知道
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;
}
int func(int a)
{

std::cout表达式
func(0)+func(1)
的行为定义为:结果将是通过调用
func
获得的结果的总和,参数为
0
,调用
func
获得的结果的总和,参数为
1

但是,调用函数的顺序可能是,尽管可能未指定。也就是说,编译器可以生成相当于以下内容的代码:

int a = func(0);
int b = func(1);
int result = a + b;
或者它可以产生:

int a = func(1);
int b = func(0);
int result = a + b;

这通常不会成为问题,除非
func
具有依赖于调用顺序的副作用。

表达式
func(0)+func(1)的行为
的定义是,结果将是通过调用参数为
0
func
和参数为
1
func
获得的结果之和

std::cout << func(0) + func(1) << std::endl;
但是,调用函数的顺序可能是,尽管可能未指定。也就是说,编译器可以生成相当于以下内容的代码:

int a = func(0);
int b = func(1);
int result = a + b;
或者它可以产生:

int a = func(1);
int b = func(0);
int result = a + b;

这通常不会是一个问题,除非
func
具有依赖于调用顺序的副作用。

std::cout
std::cout如果我们看一下
1.9
部分,程序执行第15段说(重点是我的):

std::cout << func(0) + func(1) << std::endl;
除非另有说明,否则对单个运算符的操作数和单个表达式的子表达式的求值是不排序的。[注:在程序执行期间多次求值的表达式中,其子表达式的未排序和不确定排序求值不需要在不同求值中一致执行。-结束注]运算符操作数的值计算在运算符结果的值计算之前排序。如果对标量有副作用 对象相对于同一标量对象上的另一个副作用或使用同一标量对象的值进行的值计算未排序,行为未定义

如果我们检查包含
+
-
的第
5.7节
加法运算符,则该节未指定排序,因此它是不排序的

在这种情况下,
func
会产生副作用,因为它会输出到
stdout
,因此输出的顺序将取决于实现,甚至可能会在后续评估中更改

请注意,
结束了表达式语句,第6.2节
表达式语句说:

[…]在执行下一条语句之前,表达式语句的所有副作用都已完成。[…]


因此,尽管函数调用的顺序未指定,但每个语句的副作用都是在下一个语句之前完成的。

如果我们看一下
1.9节的话,这个程序的行为不是,而是,程序执行第15段说(重点是我的):

除非另有说明,否则对单个运算符的操作数和单个表达式的子表达式的求值是不排序的。[注:在程序执行期间多次求值的表达式中,其子表达式的未排序和不确定排序求值不需要在不同求值中一致执行。-结束注]运算符操作数的值计算在运算符结果的值计算之前排序。如果对标量有副作用 对象相对于同一标量对象上的另一个副作用或使用同一标量对象的值进行的值计算未排序,行为未定义

如果我们检查包含
+
-
的第
5.7节
加法运算符,则该节未指定排序,因此它是不排序的

在这种情况下,
func
会产生副作用,因为它会输出到
stdout
,因此输出的顺序将取决于实现,甚至可能会在后续评估中更改

请注意,
结束了表达式语句,第6.2节
表达式语句说:

[…]在执行下一条语句之前,表达式语句的所有副作用都已完成。[…]


因此,尽管函数调用的顺序未指定,但每个语句的副作用都会在下一个语句之前完成。

i=i++不是未定义的……据我所知。我认为这是未指定的行为。@thang:
i=i++
具有未定义的行为。当程序修改并单独访问标量对象时,没有C++中的C++标准没有定义行为,i= i++是不定义的……据我所知,我认为它是未指定的行为。@ thang:<代码> i=i++< /COD>具有未定义的行为。当程序修改和单独访问标量对象而没有中间的序列点时,C++标准不定义。ine行为。或
func(0)
func(1)
可以并行执行,并且假设线程安全的
cout
,输出可能是
10\n\n1\n
@KenY-n:足够正确。这是否意味着如果我在
func
中更改全局变量
I
,则
I
的结果未定义?@KenY-n,则调用不能并行进行。如果调用func()设置一个全局变量,这将引入数据竞争,这将向程序中注入未定义的行为