0

Suppose we have this code (seen in an interview test), the order of arithmetical operations is well defined in the standard (left to right), but the question is: the order of execution for the functions is defined (the same as for the operations) or this code is undefined behavior?

int test_b = 1;
int test_x() {test_b++; return test_b;}
int test_y() {test_b = 3; return test_b - 1;}
int test_z() {test_b = test_b+8; return test_b + 2;}

int a = test_x() - test_y() + test_z();

Please keep in mind that this question is not related to sequence points (we have function calls)

PS: I have tried few online compilers on https://godbolt.org/, from what I have tested the result is always 13.

cprogrammer
  • 5,503
  • 3
  • 36
  • 56
  • 2
    *"the order of arithmetical operations is well defined in the standard (left to right)"* [Evaluation order](https://en.cppreference.com/w/cpp/language/eval_order) and operator precedence are distinct things. Whereas precedence is defined, the evaluation order is unsequenced here. – Jarod42 Sep 16 '22 at 08:08
  • Operator precedence and order of evaluation are not the same thing. See [Operator Precedence vs Order of Evaluation](https://stackoverflow.com/questions/5473107/operator-precedence-vs-order-of-evaluation) – Jason Sep 16 '22 at 08:10
  • Well, exactly this is the question: knowing that operator precedence and order of evaluation are not the same thing, the order of evaluation is well defined ? – cprogrammer Sep 16 '22 at 08:12
  • 1
    The "duplicate" answer is not a duplicate from my point of view, is related to sequence points as there is no "function call" layer that could change the order. – cprogrammer Sep 16 '22 at 08:14
  • *"the order of execution for the functions is defined (the same as for the operations) or this code is undefined behavior?"* None of those, order is unspecified, but function cannot overlap, so modification of `test_b` doesn't lead to UB. Any permutations `x`, `y`, `z` might happens. – Jarod42 Sep 16 '22 at 08:16
  • thank you @Jarod42 . But if the order of evaluation of x, y, z might happen, the result is UB (different results on different compilers). this is not clear to me as this case is not related to sequence points (we have function calls) – cprogrammer Sep 16 '22 at 08:21
  • 1
    @Jaro42 But, because the functions may be called in any order, then there ***is*** potential for UB. The value of `a` will depend on which order the functions are called in. – Adrian Mole Sep 16 '22 at 08:22
  • For info I have tested on a lot of compilers on https://godbolt.org/ but the order of execution seems to remain test_x, test_y, test_z. – cprogrammer Sep 16 '22 at 08:25
  • 1
    @AdrianMole this is implementation defined, not undefined, behaviour, because the bodies of the functions are indeterminately sequenced, not unsequenced. It's the same rule that makes multiple `std::make_unique` calls exception safe – Caleth Sep 16 '22 at 08:27
  • 1
    @AdrianMole There are plenty of dupes for this. For example, see [Order of function call](https://stackoverflow.com/questions/4737344/order-of-function-call) – Jason Sep 16 '22 at 08:29
  • 1
    @cprogrammer just because everywhere you checked does it one way doesn't make that way mandatory – Caleth Sep 16 '22 at 08:30
  • 1
    @JasonLiam OK, that's a better duplicate. – Adrian Mole Sep 16 '22 at 08:31
  • 1
    The correct answer to the interview test is "I will never write code like this. Promise!". – BoP Sep 16 '22 at 08:34
  • @Caleth totally agree with you. This is why I have put the question here. But yes, is a duplicate, I didn't search well (found only seq points refs) – cprogrammer Sep 16 '22 at 08:34
  • 1
    @Caleth: Pedantically, it is not even implementation defined, any order can happen at each call... – Jarod42 Sep 16 '22 at 08:35
  • 1
    @Caleth *this is implementation defined* No, it is unspecified. The order of evaluations can even differ between invocations. – j6t Sep 16 '22 at 08:35
  • @j6t No, it cannot differ between invocations, that is cristal clear. I have checked the compiled result and is predictable. The only question is if this is predictable for all compilers ``` rcall test_x() mov r16,r24 mov r17,r25 rcall test_y() sub r16,r24 sbc r17,r25 rcall test_z() ``` – cprogrammer Sep 16 '22 at 08:42
  • 1
    @cprogrammer If the expression `test_x() - test_y() + test_z()` were inlined at different call sites (because it occurs in an inline function, for example), then each site can choose a different evaluation order. I count that as "different between invocations". – j6t Sep 16 '22 at 08:48
  • It could be inlined, but 'rcall' doesn't sound like an inlined function. – cprogrammer Sep 16 '22 at 14:23

0 Answers0