1

Consider this code :

int func1()
{
    cout<<"Plus"<<endl;
    return 1;
}
int func2()
{
   cout<<"Multiplication"<<endl;
   return 2;
}
int main()
{
  cout<<func1()+4*func2();
}

According to this page * operator has higher precedence than + operator So I expect the result to be :

Multiplication 
Plus
9

But the result is

Plus 
Multipication
9

!! What is going on in compiler parser ?! Does compiler prefer Operator associaty ? Is the output same in all c/c++ compilers?

uchar
  • 2,552
  • 4
  • 29
  • 50
  • 13
    Operator precedence has nothing to do with function evaluation order. Seeing that the result is `9` and not `10`, as would be the case when `+` had precedence shows this. – arne Aug 21 '13 at 16:21
  • 2
    There is NOTHING in the C++ standard that says which order functions that goes into arguments to other functions are called. Take for example: `func(getchar(), getchar());`, with the input "ab", there is no telling whether the first or second argument to `func` will have "a" in it - because the compiler is allowed to order those getchar in whichever way it likes. That's part of the C and C++ standard, so live with it. You may not ACCEPT it, but that's like hoping not to fall when you step off from a height by not accepting gravity. – Mats Petersson Aug 21 '13 at 17:18
  • 2
    `cout<<4*x/++x;` is undefined behaviour. – jrok Aug 21 '13 at 17:27
  • @jrok why ?can you explain more. – uchar Aug 21 '13 at 17:41
  • @MatsPetersson Actually it is in c++ standard look at the Operator precedence Table ! and the intersting part is that visual studio's compiler shows the correct result '4'. – uchar Aug 21 '13 at 17:50
  • 1
    Well, operator precedence is defined. Which order multiple functions that make up an expression functions are called is not. Nor is whether `++x` is done before or after `4*x` - it is only defined that `++x` is done before the end of the whole expression - which is why you may not get the result you expect. So if you do `cout << getchar() << getchar() << endl;` and enter "ab", the output may be "ba" or "ab". – Mats Petersson Aug 21 '13 at 17:55
  • 1
    @omid `4*x/++x` is explicitly *undefined* in both C and C++ (if the type of `x` is `int`). Read about evaluation order: http://stackoverflow.com/questions/4176328 or http://en.cppreference.com/w/cpp/language/eval_order – Cubbi Aug 21 '13 at 18:18

2 Answers2

27

Operator precedence is not the same thing as order of evaluation.

You have no guarantee about the order of evaluation - the compiler is free to call functions in whatever order it likes within an expression so long as you get the correct result.

(A minor qualification: anything which introduces a sequence point (which includes short circuit operators), will have an effect on order of evaluation, but there are no sequence points within the expression in this particular case.)

Paul R
  • 208,748
  • 37
  • 389
  • 560
  • Would short-circuiting logical operators be an exception? – Matt Kline Aug 21 '13 at 16:23
  • Yes, anything which introduces a sequence point (which includes short circuit operators), would have an effect on order of evaluation. – Paul R Aug 21 '13 at 16:24
  • @Sergey: thanks - this conflation of precedence and order of evaluation comes up so often I thought it deserved a little extra emphasis. ;-) – Paul R Aug 21 '13 at 16:29
  • Note that the term "sequence point" doesn't exist anymore starting with C++11 standard. – sasha.sochka Aug 21 '13 at 16:31
  • @sasha: thanks - the question has multiple language tags, but what would be the corresponding concept of a sequence point in C++11 ? – Paul R Aug 21 '13 at 16:33
  • @PaulR, just looked at the wiki - it says "usage of the term sequence point has been replaced by specifying that either one evaluation is sequenced before another, or that two evaluations are unsequenced." – sasha.sochka Aug 21 '13 at 16:42
  • @paulR I edited my question your explanation doesn't seems correct to me – uchar Aug 21 '13 at 16:59
  • 2
    @omid: think about it a little more - you can calculate `4*func2()` first and then add this to `func1()` - or you can calculate `func1() first and add this to `4*func2()` - the result is the same, and in both cases you are respecting *operator precedence*, but the *order of evaluation* is different. – Paul R Aug 21 '13 at 17:09
  • Sequence points are an outdated concept - the new relations in C++11 are "sequenced before", "indeterminately sequenced" and "unsequenced". :) – Xeo Aug 21 '13 at 22:46
8

The compiler is free to evaluate functions in any order it pleases - the only cases within expressions where the order of evaluation is guaranteed are the sequence points; operators ||, &&, ,, and ? of the ternary conditional operator ? : are sequence points. In each case the left side has all its values and side effects evaluated before the right side is touched.