in Programming in C recategorized by
21,130 views
73 votes
73 votes

What is the return value of $f(p,p)$, if the value of $p$ is initialized to $5$ before the call? Note that the first parameter is passed by reference, whereas 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;
}
in Programming in C recategorized by
by
21.1k views

4 Comments

Just a simple doubt.

Is marks for all means, Is it only to those who attended this question

OR

To everyone , who didn’t even attend this question also ?
1
1
Is it at all a valid C code? I doubt…

They some how tried to test the concept in some pseudo language which supports both pass by reference and pass by value…
0
0
how can you increase the address. shouldn’t the program send segmentation fault.
0
0

2 Answers

109 votes
109 votes
Best answer

In GATE 2013 marks were given to all as the same code in C/C++ produces undefined behavior. This is because $*$ is not a sequence point in C/C++. The correct code must replace:

return f(x,c) * x;
with
res = f(x,c); // ';' forms a sequence point 
//and all side-effects are guaranteed to be completed here 
//-- updation of the x parameter inside f is guaranteed 
//to be reflected in the caller from the next point onwards. 
return res * x;

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

Good Read:

edited by
by

28 Comments

@Arjun you are awesome thanks.
5
5
reshown by
res = f(x,c);
 return res * x;

where x is pointer now the thing is whether * is multiply or dereferencing ???

how the compiler will come to know that which refernce to this operator is to use ........so i think it still remain ambigious
0
0
return res * x;

where x is a pointer while multiplication on pinters is not valid so it is still ambigious
0
0
That ambiguity is taken care of by C grammar. After the parsing stage, it will be either "multiplication' or 'dereference' and in this case it will be just 'multiplication'.
2
2
sir, what is sequence point?
1
1

Usually we expect every operator to be a sequence point - as the case of Java. But in C sequencepoints are broader than operators. These are the places where all side effects are guaranteed to be complete. ";" is the most common sequence point. Others can be found here:

https://en.wikipedia.org/wiki/Sequence_point

8
8
thanx
1
1

what arjun sir has written:
 

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


is somewhat like doing left-factoring to remove non determinism, Isn't it sir?

6
6
yes. Exactly. Bringing a ";" actually puts a sequence point which avoids non-determinism and sequences the operations. ";" is a sequence point while "*" is not. Actually no arithmetic operations in C/C++ form a sequence point whereas logical operators && and || form sequence points. "," operator forms a sequence point but not the "," separator used in parameter list.
13
13
What affect does f(x,c) * x; statement cause and * is not sequence point...?
@Arjun Sir
1
1
If x is modified inside f(), should we multiply with the modified value or the old value? This causes the issue.
16
16
ohh sorry....
Got it.
0
0
edited by

 then tell me sir  here also sequence point problem or not .   according to me sir here also sequence point for the statemnet  return fun(a+a, b/2)+a; but answer given is 99 which is wrong according to you sir plz clear the doubt .  @arjun sir , @manoj k , @leen sharma ,@nichant , @kapil, @gabbar

0
0

@Arjun Sir. This is in response to the above comment by @rajan 

The concerned statement is: 
return fun(a+a, b/2)+a;

If there was something like: func1 () + func2 () then there would have been ambuiguity since either of func1 and func2 can execute first. 
But what we have here is: function call() + some constant value  so there should not be any undefined behaviour here right? I mean, Atleast there should not be any effect on the output of the program isn't it?  
Can you please confirm if the ouput is 99? Please correct me if I'm wrong. 

1
1
Not commenting as the question is not clear to me. The whole point of undefined behaviour for the question in post is due to "pass by reference" being used and this is not there in C though can be simulated via pointers.
2
2

Sir here is the question I am taking about.
https://www.facebook.com/groups/core.cs/permalink/1256338371065080/?comment_id=1256365671062350&comment_tracking=%7B%22tn%22%3A%22R2%22%7D

I have uploaded a picture in the comments about the solution. Can you please look into it?
 

0
0
edited by
Moreover

int f (int &x, int c)
             $\Lambda$
it should be * not &. I may be wrong. But i never see such thing. So Give me example where i can use this.

Also
x = x + 1; // This is also wrong.
It should be.
*x = *x + 1.
12
12

" But due to pass by reference, x in all the previous functions is now 9 "

Why this happened ? Can Somone explain plz?

0
0
@Pawan Kumar i.e how call by reference work,updated the value hand to hand.
4
4
Yes, there are many typing mistakes in the question.
0
0

Its not a mistake bro.. This concept is called aliasing which is used in C++ . Here you can directly use "x" without any de-referencing operator. Its like a extra name(nick name) to the same variable . 

9
9
Reference...?
0
0

Does this mean that int &x=p is a way to declare x as a pointer to p?

Also, would x=x+1 mean p=p+1?

1
1

Code Implementation

Beware, it's only after the problem given in the code has been addressed as suggested by arjun sir. This is not the real program as given in the question.

https://ideone.com/g7Gi6g

2
2

This is the code for above question:

#include <stdio.h>

int p=5;

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

}

int main()
{
    printf("%d",f(&p,p)); 
    
    return 0;
}

 

OUTPUT: 6561

8
8
awesome answer
0
0
$&x$ will evaluate to address of the pointer and not the value of p. As mentioned in the question, the value of p(first parameter) is passed by reference so it must be something like this:

$f(&p, p)$

$f(&x, c)$

where $x = &p$ and $*x = value of p = 5$ and  $&x = address of the pointer$. So why are we substituting &x as *x?
1
1

If you are having doubt regarding the use of $\&$ in the code read this : https://stackoverflow.com/questions/6877052/use-of-the-operator-in-c-function-signatures

string s = "Hello, wordl";
string* p = &s; // Here you get an address of s
string& r = s; // Here, r is a reference to s    
0
0
2 votes
2 votes
I think Answer is (B)
Since c is passed by value and x is passed by reference, all functions will have same copy of x, but different copies of c.
f(5, 5) = f(x, 4)*x = f(x, 3)*x*x = f(x, 2)*x*x*x = f(x, 1)*x*x*x*x = 1*x*x*x*x = x^4
Since x is incremented in every function call, it becomes9 after f(x, 2) call. So the value of expression x^4 becomes 9^4 which is 6561
Answer:

Related questions