2011-05-29 60 views
2

它来到了我的注意following fact:功能评价的目的,例如在一笔,是在标准未指定,并因此可以在任何顺序进行。 (我怀疑它,它可能涉及到代码的重新洗牌,但在当今的多核环境中,我猜一些编译器可能会看到一个机会通过隐式地并行执行这两个调用来优化缺乏规范)?函数调用的顺序。它是编译器还是情况依赖?

编辑:我想澄清。订单在标准中没有说明的事实并不意味着它对于特定的编译器(可以选择使其在文档中指定,我假设)没有指定。未指定的行为可能会使您不可移植,但编译器可能会按照给定的规则保持一致。如果这个规范实际上是由编译器完成的(例如在手册中),并且如果这个选择是一致的,或者可能被编译器选项或其他因素改变,我有兴趣知道纯粹是为了学术好奇。例如,拿gcc。它的行为如何?它是一致的吗?

+0

我认为它也可能取决于调用约定。 – kennytm 2011-05-29 19:08:52

+0

@ Kenny你为什么这么认为? – 2011-05-29 19:13:38

+0

这甚至可以在编译之间改变。 – Xeo 2011-05-29 19:15:04

回答

3

回答你的第二个问题:

编辑:我想澄清。订单在标准中没有说明的事实并不意味着它对于特定的编译器(可以选择使其在文档中指定,我假设)没有指定。未指定的行为可能会使您不可移植,但编译器可能会按照给定的规则保持一致。如果这个规范实际上是由编译器完成的(例如在手册中),并且如果这个选择是一致的,或者可能被编译器选项或其他因素改变,我有兴趣知道纯粹是为了学术好奇。例如,拿gcc。它的行为如何?它是一致的吗?

我从来没有见过这个记录对于任何编译器。这样做会限制未来版本编译器的选项,而不会为当前版本的用户提供太多价值。 如果你有一个特定的计算顺序尤其需要,你总是可以得到,它通过添加一些额外的分号!

代码是不是在一个时间优化一个声明,但在整体功能,甚至更大的部分,如果代码被内联。您如何评估特定声明取决于周围的代码。也许有一个价值已经在前面的陈述中被计算和使用了?它可能已经存在于CPU寄存器中,可以重新使用。

或者子表达式或许一个以后可以重复使用,如果是计算最后?这会影响评估顺序,调用约定也可以用于特定调用。

无论如何,对一个特定的编译器的具体情况进行编码通常是一个坏主意。你永远不知道什么时候你必须移植到另一个。

12

它是不明 - 我还有什么可说?因为你不应该编写依赖于顺序的代码(因为编译器当然可以改变它),所以这个问题只有学术兴趣。如果你真的对你的具体编译器有什么兴趣,在你感兴趣的场景中检查发出的机器代码。

+0

是的,我只对内部好奇。我不打算利用本地编译器行为。 – 2011-05-29 19:23:02

+0

我同意没有指定,但在实际中,根据编译器的不同,给定的编译器将以一致的,可预测的方式运行或不运行。我希望能得到这样的答案:这个编译器总是按照这个顺序调用,但是这个其他编译器利用并行性,并且可能会根据它在早上如何唤醒来调用,或者这个编译器的顺序是这样的,但是如果你这样做 - O3可能会洗牌。 – 2011-05-29 19:26:35

+0

@Stefano嗯,我怀疑很多人(除了编译器实现者)都有能力说出这些东西。我从来没有对我使用的编译器实施的评估顺序感兴趣,我从来没有在任何编译器的文档中看到它的记录。 – 2011-05-29 19:31:18

4

它不能交错函数调用(在情况下,你可以分辨出来),因为在调用和从函数返回有序列点。

除此之外,编译器可以以任何顺序计算表达式的部分其认为合适的。该标准明确规定,没有规定的顺序,从除在表达式中使用的运营商下文。

+0

+1指出交织函数/并行运行并不是合法的优化(除非函数可以被证明是纯粹的或者至少不会产生彼此可见的副作用)。 – 2011-05-29 23:58:00

相关问题