简体   繁体   中英

Function call in wrong order

This is what i have coded today

#include <iostream>
using namespace std;

int function1()
{
  cout<<"hello from function1()"; return 0;
}

int function2()
{
  cout<<"hello from function2()"; return 0;
}

int main()
{
    int func_diffresult = 0;
    func_diffresult = function1() - function2();
    cout<<func_diffresult; /** prints 0 correctly **/
}

the output is get is hello from function2()hello from function1() . I think the output should be hello from function1()hello from function2() . Is my compiler playing with me?

The order of evaluation of arguments of - operator is unspecified . So functions may be called in either order.

The - operator effectively becomes operator-(function1(), function2()) , and the order of evaluation of function parameters is deliberately unspecified.


Related notes:

One really good reason to leave it unspecified is to handle calling conventions efficiently. For example, the C calling convention requires parameters be pushed on the stack in reverse order.

Therefore, it makes sense to evaluate the functions in reverse order since the result may be pushed immediately. To evaluate parameters from left-to-right and then push the results from right-to-left involves storing all results before pushing any of them. If you really need to do this, you can do it manually. If it doesn't matter to you, the performance benefit probably does.

The ISO standards does not guarantee the order in which subexpressions will be evaluated.

From the c++0x draft standard:


1.9. Program execution:
:
13/ Sequenced before is an asymmetric, transitive, pair-wise relation between evaluations executed by a single thread, which induces a partial order among those evaluations. Given any two evaluations A and B, if A is sequenced before B, then the execution of A shall precede the execution of B. If A is not sequenced before B and B is not sequenced before A, then A and B are unsequenced. [Note: The execution of unsequenced evaluations can overlap.]

Evaluations A and B are indeterminately sequenced when either A is sequenced before B or B is sequenced before A, but it is unspecified which. [Note: Indeterminately sequenced evaluations cannot overlap, but either could be executed first.]
:
15/ Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.
:
When calling a function (whether or not the function is inline), every value computation and side effect associated with any argument expression, or with the postfix expression designating the called function, is sequenced before execution of every expression or statement in the body of the called function [Footnote: In other words, function executions do not interleave with each other] . [Note: Value computations and side effects associated with different argument expressions are unsequenced.]

Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function.


In other words, the implementation is free to arrange the calls using whatever method it desires. However, function calls are treated specially as per the footnote - they do not interleave.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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