C++ 为什么C++;标准1.9/5“谈论”;可能的执行顺序;?

C++ 为什么C++;标准1.9/5“谈论”;可能的执行顺序;?,c++,C++,根据C++03标准1.9/5 执行格式良好的程序的一致性实现应产生与具有相同程序和相同输入的抽象机器对应实例的可能执行序列之一相同的可观察行为 我不明白“作为一个”的部分 如果我有一个特定的程序和一个特定的输入,并且我的程序不包含未定义的行为,为什么可观察的行为会发生变化?C++中的“可能执行序列”中的什么意思?< p>,有些东西只剩下实现。例如,当你写 int x = f(a) + f(b); 实现可以选择先调用f(a)或先调用f(b)。考虑: x = f() + g(); 这允许两种可能

根据C++03标准1.9/5

执行格式良好的程序的一致性实现应产生与具有相同程序和相同输入的抽象机器对应实例的可能执行序列之一相同的可观察行为

我不明白“作为一个”的部分


如果我有一个特定的程序和一个特定的输入,并且我的程序不包含未定义的行为,为什么可观察的行为会发生变化?C++中的“可能执行序列”中的什么意思?

< p>,有些东西只剩下实现。例如,当你写

int x = f(a) + f(b);
实现可以选择先调用f(a)或先调用f(b)。

考虑:

x = f() + g();
这允许两种可能的执行顺序:

__temp1 = f();           /*or*/     __temp1 = g();
__temp2 = g();           /*or*/     __temp2 = f();
x = __temp1 + __temp2;   /*or*/     x = __temp2 + __temp1;

本标准未规定必须执行以下哪项:;只是程序的行为必须像执行了这两个程序中的一个一样。如果<代码> f-()/代码>和<代码>()>代码>有副作用,则程序可能有两种不同的可观察行为。

< P> C++没有定义一些表达式的评估顺序。例如,在:

    proc( a(), b() );
a()和b()都必须在proc()之前求值,但a()可以在b()之前或之后求值。因此,有两个合法的执行序列,如果a()和b()有副作用(例如,print语句),您可以知道编译器使用的是哪一个


(这种关于计算顺序的自由是为了帮助编译器生成更高效的代码。它是否真的对现代机器有帮助还有争议。)

除了其他人已经提到的子表达式计算的未指定顺序之外,请记住C++11添加了线程,这使得执行顺序更加不确定


例如,如果有两个线程正在执行,并且每个线程只打印出“线程A”或“线程B”,那么这些输出的生成顺序就完全没有指定。您可能会得到所有“线程A”输出,然后是所有“线程B”输出,反之亦然,或者它们可能是任意交错的(交错的可能性更大)。

这仅限于未指定的行为吗?@sharptooth:我想是的。当行为被指定时,程序必须按照指定的方式运行。我认为这包括了未指定的行为和实现定义的行为。例如,
sizeof(int)
可以确定实现选择了哪个可能的执行序列,但是
sizeof(int)
不是未指定的行为。