简体   繁体   English

function 调用的顺序。 它是编译器还是取决于情况?

[英]order of function call. is it compiler or situation dependent?

It came to my attention the following fact : order of function evaluation, for example in a sum, is unspecified in the standard, and can therefore be performed in any order.我注意到以下事实:function 评估的顺序,例如总和,在标准中未指定,因此可以按任何顺序执行。

This raises the question: is it compiler dependent, optimization dependent, or potentially even execution dependent (I doubt it, it may involve reshuffling of the code, but in today's multicore environments, I guess some compilers may see a chance for optimization in this lack of specification, by implicitly performing the two calls in parallel)?这就提出了一个问题:它是依赖于编译器,依赖于优化,还是可能依赖于执行(我对此表示怀疑,它可能涉及代码的重新洗牌,但在今天的多核环境中,我猜一些编译器可能会在这种缺乏的情况下看到优化的机会规范,通过隐式并行执行两个调用)?

Edit : I want to clarify.编辑:我想澄清一下。 The fact that order is unspecified in the standard, does not imply it's unspecified for a particular compiler (which may choose to make it specified in the documentation, I assume).标准中未指定 order 的事实并不意味着特定编译器未指定它(我假设它可能选择在文档中指定它)。 Unspecified behavior may make you non-portable, but the compiler may behave consistently according to a given rule.未指定的行为可能会使您无法移植,但编译器可能会根据给定的规则一致地运行。 I am interested in knowing, purely for academic curiosity, if this specification is actually made by compilers (eg in the manual) and if yes, if this choice is consistent or may be altered by compiler options or other factors.纯粹出于学术好奇心,我很想知道这个规范是否实际上是由编译器(例如在手册中)制定的,如果是,这个选择是否一致或可能被编译器选项或其他因素改变。 Example, take gcc.以 gcc 为例。 How does it behave?它的行为如何? is it consistent?是否一致?

It's unspecified - what more can we say?这是未指定的 - 我们还能说什么? As you should never write code that depends on the order (because the compiler certainly could change it), the question is of academic interest only.由于您永远不应该编写取决于顺序的代码(因为编译器当然可以更改它),所以这个问题仅具有学术兴趣。 If you are really interested in what your specific compiler gets up to, examine the emitted machine code in the scenarios that interest you.如果您真的对特定编译器的工作感兴趣,请在您感兴趣的场景中检查发出的机器代码。

It can't interleave function calls (in cases where you can tell the difference) because there are sequence points at calling and returning from a function.它不能交错 function 调用(在可以区分的情况下),因为在调用和从 function 返回时存在序列点。

Other than that, the compiler can evaluate parts of an expression in any order it sees fit.除此之外,编译器可以以它认为合适的任何顺序评估表达式的一部分。 The standard explicitly states that it doesn't prescribe an order, except what follows from the operators used in the expression.该标准明确声明没有规定顺序,除非从表达式中使用的运算符得出。

Answering your second question:回答你的第二个问题:

Edit: I want to clarify.编辑:我想澄清一下。 The fact that order is unspecified in the standard, does not imply it's unspecified for a particular compiler (which may choose to make it specified in the documentation, I assume).标准中未指定 order 的事实并不意味着特定编译器未指定它(我假设它可能选择在文档中指定它)。 Unspecified behavior may make you non-portable, but the compiler may behave consistently according to a given rule.未指定的行为可能会使您无法移植,但编译器可能会根据给定的规则一致地运行。 I am interested in knowing, purely for academic curiosity, if this specification is actually made by compilers (eg in the manual) and if yes, if this choice is consistent or may be altered by compiler options or other factors.纯粹出于学术好奇心,我很想知道这个规范是否实际上是由编译器(例如在手册中)制定的,如果是,这个选择是否一致或可能被编译器选项或其他因素改变。 Example, take gcc.以 gcc 为例。 How does it behave?它的行为如何? is it consistent?是否一致?

I have never seen this documented for any compiler.我从未见过任何编译器都记录了这一点。 Doing so would limit the options for future versions of the compiler, without giving much value to the users of the current version.这样做会限制编译器未来版本的选项,而不会给当前版本的用户带来太多价值。 If you have a particular need for a specific evaluation order, you can always get that by adding a few extra semicolons!如果您对特定的评估顺序有特殊需求,您总是可以通过添加一些额外的分号来实现!

Code isn't optimized one statement at a time, but over the whole function or even larger parts if code is inlined.代码不是一次优化一个语句,而是在整个 function 甚至更大的部分(如果代码被内联)。 How you evaluate a particular statement depends on the surrounding code.您如何评估特定语句取决于周围的代码。 Perhaps one value has already been computed and used in a preceding statement?也许已经在前面的语句中计算并使用了一个值? It may already be present in a CPU register and can be reused.它可能已经存在于 CPU 寄存器中并且可以重复使用。

Or perhaps one of the subexpressions can be reused later, if it is computed last?或者,如果最后计算其中一个子表达式,以后可以重用它吗? That an affect the evaluation order, as can the calling convention used for a specific call.这会影响评估顺序,就像用于特定调用的调用约定一样。

It is anyway generally a bad idea to code against the specifics of a particular compiler.无论如何,针对特定编译器的细节进行编码通常是一个坏主意。 You never know when you will have to port to another one.你永远不知道什么时候必须移植到另一个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM