Sign in to follow this  

recursion with reference parameter

This topic is 1854 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So I have this function that recursively flows through a tree of vectors of pointers to Locations. Notice the reference parameter int&total

[source lang="cpp"]int score(Location* locationToScore, int&total){
total++;
int n = locationToScore->explored?1:0;
for (int i=0; i<locationToScore->subLocations.size(); i++) n += score(locationToScore->subLocations[i], total);
return n;
}[/source]

I call this function like this:

[source lang="cpp"]int total = 0;
cout << score(sol, total) << "/" << total;[/source]

But it keeps displaying the total as 0.

Just to make sure I was doing it right I made a simpler program to test it and it works fine in the test program but I can't see a difference:

Test program:
[source lang="java"]#include <iostream>

using namespace std;

int testFunction(int x, int&y){
y++;
if (x==0) return 1;
else return 1 + testFunction(x-1, y);
}

int main(){
int y = 3;
cout << testFunction(3, y);
cout << y;
}[/source] Edited by sooner123

Share this post


Link to post
Share on other sites
You keep adding up the values depending on [i]locationToScore->explored[/i], but you never change the [i]explored[/i]-member anywhere so my guess is that all of them are false and thus you keep adding up zeros all the time.

Share this post


Link to post
Share on other sites
Actually, scratch that, I was so focused on the return value from the score function that I didn't see that you actually print the value of [i]total[/i] after that.

The reason is the order of evaluation of parameters within an expression. The language does not specify the order in which sub-expressions within an expression are evaluated. In this case, you have two sub-expressions that causes the problem:
[list=1]
[*]The value of the function call to [i]score[/i].
[*]The value of [i]total[/i].
[/list]
The language does not specify the order in which these two sub-expressions are evaluated. If the value of total is evaluated before the function call, then the value of total results in zero, and then the function is called, setting it to its new value. In essence, you have two expressions where one (the value of [i]total[/i]) depends on the other (the function call), and where the one expression has a side effect on the other expression. Your program is not well formed.

You need to call the function and grab its return value before printing it to ensure that the function is actually called before printing the value of [i]total[/i].
[code]
int total = 0;
int myscore = score(sol, total);
cout << myscore << "/" << total;
[/code] Edited by Brother Bob

Share this post


Link to post
Share on other sites
That did it. Thanks!

It had vaguely occurred to me that this might be the case, but I ignored myself. :( Edited by sooner123

Share this post


Link to post
Share on other sites
[quote name='sooner123' timestamp='1355999807' post='5012752']
I call this function like this:

[CODE]int total = 0;
cout << score(sol, total) << "/" << total;[/CODE]


But it keeps displaying the total as 0.
[/quote]

Your recursive function is probably working fine: this line of code is the problem.
The order of evaluation for parameters passed to cout using the << operator is effectively undefined. For various reasons, it is most likely evaluating them in the opposite order to that which you expect - it's printing the value of total first, (which is initially zero) and THEN calling the score function.

Note in your test program, you are outputting the return value of the function, and the value returned by reference in different cout calls. This works exactly as you expect.

Try using separate cout calls or call the score function outside of cout, e,g:

[code]
int total = 0;
int currentScore = score(sol, total);
cout << currentScore << "/" total;
[/code]

e;fb Edited by Sandman

Share this post


Link to post
Share on other sites
Sign in to follow this