C++ Bug probably scope problem

Hello,
I have some difficulty to understand the scope of this program adapted from C++ book of D.S. Malik I am reading.
I put the header and the main program as attachment to save space. My problem is the output:

$ ./prog1009_die
Line 4: Not yet rolled, die1 gets default number: 1
Line 5: Not yet rolled, die2 gets default number: 1

Line 6: After first rolling die1: 4
Line 7: After first rolling die2: 5
Line 8: The sum of the numbers rolled by the dice is: 9

Line 6-2: After second rolling die1: 2
Line 7-2: After second rolling die2: 4

Line 9: After rolling again (third time), 
die1 (die1.roll()): 5
die2 (die2.roll()): 4
the sum of the numbers rolled [die1.getNum() + die2.getNum()] is: 8
the sum of the numbers rolled [die1.roll() + die2.roll()] is: 8

Line 9-2: After rolling again (third time)
die1 (die1.getNum()): 5
die2 (die2.getNum()): 4
the sum of the numbers rolled [die1.getNum() + die2.getNum()] is: 9

I was expecting Line 9 part would be the same result as Line 9-2 part, but the sum of the two numbers is not right. It is difficult for me to understand why. The problem may be related to die::roll() and die::getNum() functions in this case, but I am not sure.

int die::roll()
{
    num = rand() % 6 + 1;
    return num;
}

int die::getNum() const
{
    return num;
}

Also I am aware the rand() function here so each time the number will change. Can somebody elaborate it for me? Thanks a lot!

You rolled again for sum so the sum is for that roll. Do get for sum.

1 Like

Thanks!
Just to confirm: Did you mean this part in the source code?:

Line 9 ... ... <<"\nthe sum of the numbers rolled [die1.roll() + die2.roll()] is: " << die1.roll() + die2.roll() << endl;

causing roll() anther time?

Wait a minute! Yes, roll() was called again, then Line 9-2 the sum of the numbers rolled [die1.getNum() + die2.getNum()] should print the same as Line 9 the sum of the numbers rolled [die1.roll() + die2.roll()] , Right?
2) Does getNum() const; play some trick here?
I was confused with the scope of getNum() and roll() here. Thanks again!

You have a big long cout calling multiple things which have side-effects on each other, and the order they are done is ambiguous -- remember this is a compiled, heavily optimized language, not a one-at-a-time string interpreter. Re-imagine your code like this:

myfunction(die1.getnum(), die2.getnum(), die1.roll(), die2.roll());

When written that way, whether roll() gets called before or after getnum() is more obviously ambiguous.

Split it into two cout statements to avoid the side-effects.

It has nothing to do with the const. It just means that calling that function has no side-effects. It doesn't guarantee that all other functions have no side effects however.

1 Like

Almost got your point. I re-wrote the code as:

cout << "Line 9: After rolling again (third time), ";
cout << "\ndie1 (die1.roll()): " << die1.roll();    //Line 9 - a1
cout << "\ndie2 (die2.roll()): " << die2.roll();    //Line 9 - a2
cout << "\nthe sum of the numbers rolled [die1.getNum() + die2.getNum()] is: " << die1.getNum() + die2.getNum();         //Line 9 - c1
cout << "\nthe sum of the numbers rolled [die1.roll() + die2.roll()] is: " << die1.roll() + die2.roll() << endl;          //Line 9 - c2

Line 9-c1 die1.getNum() + die2.getNum() was from previous rolling.
At Line 9-c2 die1.roll() and die2.roll() gets rolled again when they are combined together as die1.roll() + die2.roll() . That caused the confusion.
In turn, Line 9-c2 prints out the same as next Line 9-2 because die1.getNum()+ die2.getNum() are from the roll() of Line 9-c2.

Without your suggestion, I could not figure this out.
Thanks again!

Yifang

If roll() returns void then people will not be confused when rolling and when examining with get(). Compiled code will be same or smaller and faster.