3
result= function_1()*function_2();

I am writing a code like above. What I want to know is while doing the multiplication, which function is called first? That is because, the first called function can effect the result returned from the other function. I assumed function_1() is called first, and when I tried I saw that it is really so. However, is it always the case? Does it depend on which compiler I use or the system I work on?

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
oicrisah
  • 83
  • 6

2 Answers2

9

Order of evaluation is unspecified by the C++ (or the C) standard (see answer from Vlad). If your function_1 or function_2 have significant side-effects, it may become some unspecified behavior which you should absolutely avoid (like you should avoid undefined behavior). And in some cases (inlined functions with strong optimizations) the computations might be intermixed.

Think about weird cases like

 static int i;
 int function_1(void) { i++; return i; }
 int function_2(void) { i+=2; return 3*i+1; }

It probably is implementation specific, and might depend upon the actual compiler and the optimization flags.

You should code as if the order of function calls is completely random and not reproducible (even if in practice it might be reproducible). Likewise, you should not expect any particular order of arguments evaluation (e.g. in f(i++, ++j) you don't know if i or j has been incremented first), even if for a given compiler that order might be fixed. Again, you should imagine a completely random and non-reproducible order.

As commented by David Schwartz, if you care about the order, you should code explicitly some sequence points

At last, if your code is depending upon some order, it is completely unreadable and for that simple readability reason you should avoid coding this way.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • 5
    If you care, you need to insert a sequence point between the function calls. Like `result=function_1(); result*=function_2();`. – David Schwartz Oct 29 '14 at 09:15
  • 1
    This cannot cause undefined behaviour (unless `function_1` or `function_2` are macros). There is a sequence point before and after a function body. – M.M Oct 29 '14 at 09:20
  • If `function_1` and `function_2` are inlined, I believe the compiler might optimize to mix both codes... – Basile Starynkevitch Oct 29 '14 at 09:22
  • It still can't cause UB, the compiler has to obey the as-if rule – M.M Oct 29 '14 at 09:23
  • Thanks about UB. Improved my answer! – Basile Starynkevitch Oct 29 '14 at 09:25
  • 2
    "This is unspecified" is too vague. It sounds like the C++ standard doesn't say anything about this. But it does. It specifies that the evaluation order is unspecified. So a more precise statement would be that "the order of evaluation of subexpressions is unspecified". – Kerrek SB Oct 29 '14 at 09:39
  • I think multiplication yields same result in either case (left evaluated first, or right evaluated first). This concern can be checked by putting break points in each function and test , the complier used will follow what sequence. – Ali Kazmi Oct 29 '14 at 09:40
  • Not with `static int i; int function_1(void) {i+=1; return i;}; int function_2(void) {i+=2; return i;}` – Basile Starynkevitch Oct 29 '14 at 09:43
4

According to the C++ Standard (1.9 Program execution)

15 Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.

So in this expression

result= function_1()*function_2();

some compilers can evaluate at first function_1() and then function_2() while other compilers can evaluate at first function_2() and only then function_1(). Even if you write like

result= (function_1())*(function_2());

or

result= (function_1())*function_2();

or

result= function_1()*(function_2());

nothing will be changed relative to the order of evaluation of the operands.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335