Is undefined behavior the given code?

What is the return value of f (p, p) if the value of p is equally initialized to 5 before the call? Note that the first parameter is passed by reference, while the second parameter is passed by value.

int f (int &x, int c) { c = c - 1; if (c==0) return 1; x = x + 1; return f(x,c) * x; } 

Options:

  • 3024
  • 6561
  • 55440
  • 161051

I am trying to explain:


There will be four recursive calls in this code with parameters (6,4), (7,3), (8,2) and (9,1). The last call returns 1. But due to the passage by reference x in all previous functions is now 9. Therefore, the value returned by f (p, p) will be 9 * 9 * 9 * 9 * 1 = 6561.


This question is related to the GATE competitive exam, ( see Q.no.-42 ). The response key is set by GATE "Marks for all" (means that there is no correct option.) Key set-C, Q.no.-42 . Somewhere explained as:

In GATE 2013, the marks were marked by everyone, since the same code in C / C ++ creates undefined behavior. This is because * not a sequence point in C / C ++. The correct code should replace

 return f(x,c) * x; 

with

  res = f(x,c); return res * x; 

But this code is working fine. Is the GATE key wrong? Or is it really a mistake with a question?

+5
source share
2 answers
  return f(x,c) * x; 

The result of this operation depends on the order in which two things are evaluated. Since you cannot predict the order that they will evaluate, you cannot predict the result of this operation.

+14
source

C ++ 03 chapter 5:

Except where noted, the order of evaluation of the operands of individual operators and the subexpressions of individual expressions and the order in which side effects occur are not defined.

Thus, in the case f(x,c) * x order of evaluation of the operands is not specified, which means that you cannot know whether the first or right operand will be evaluated first.

Your code has undefined behavior, which means that it will behave in a certain way that is known only to the compiler. The programmer cannot know what the code will do, only that he will either check the left operand or the right operand first. The compiler is even allowed to change the evaluation order in each case for optimization purposes.

If the evaluation order matters, you need to rewrite the code. Code based on unspecified behavior is always a mistake, possibly quite subtle, that won't open right away.

Undefined behavior is different from undefined behavior, which would mean that something could happen, including a program coming with haywire or a crash.

+9
source

Source: https://habr.com/ru/post/1232596/


All Articles