Skip to main content
gamedev.net
🔒 Locked

Strange stringstream behavior

Started by CuppoJava Jun 22, 2007 at 10:31 AM 3 replies 650+ views
Original Post
CuppoJava
CuppoJava
Hi, I'm having some difficulty understanding the behavior of this code. Could someone tell me what I'm doing wrong?

string temp("ABCDEFG");
istringstream sin(temp, istringstream::in);
while(sin)
  cout <<sin.tellg() <<"   " <<(char)sin.get() <<"   " <<sin.tellg() <<endl;
gives me the output:

1   A   0
2   B   1
3   C   2
4   D   3
5   E   4
6   F   5
7   G   6
-1   ÿ   7
Why is sin.tellg() after the read smaller than sin.tellg() before the read? Thanks for your help -Cuppo
Brother Bob
Brother Bob
The order in which values are evaluated is not specified between sequence points. In the line (the cout one), there are 4 values that needs to be evaluated (two return values from tellg, one from get, and endl) and there are no sequence points involved. That means the order in which these values are evaluated is undefined.

I guess you assume they are evaluated from left to right, meaning the leftmost tellg first, then get, then tellg again, and then endl. This is obviously not what you're experiencing. Most likely, the compiler decided to evaluate them from right to left instead. Perfectly OK as far as the standard goes.

The problem with the code is that you're mixing several evaluations with evaluations that have side effects. A call to get affetcs the return value of tellg. Don't do that.
CuppoJava
CuppoJava
I see. That's a very clear explanation.
Thanks.

ps. so operator precedence and associativity doesn't have any effect on evaluation sequence?
Brother Bob
Brother Bob
No, this has nothing to do with operator precedence. That has to do with how values are combined, sort of. But in order to get the values, expressions needs to be evaluated, and it's the order of evaluation to get the values that is undefined between two sequence points.

As an example, a+b*c is always evaluated as a+(b*c) due to operator precedence, but if the evaluation of one value (a, b or c, which can be return values from functions) have any side effects that changes the value of some other value (in your case, calling get changes the value of tellg), you can't be sure what the final result will be.

But no matter how expressions are evaluated, you will know for sure that the result from evaluating b and c are multiplied, and the result from that is added with the evaluation of a.
CuppoJava
CuppoJava
Okay that makes it much clearer for me.
Thanks a lot for your help.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.