odd outputs in cout statement

Hello,

I recently came across something strange. I have a class, Polynomial, that is basically an array of terms, that are a coefficient and a power, ie 2x^3 or 3x. For the class there is an ostream (ie cout) operator defined to output the polynomial, along with a function to remove the last term. The latter functions returns a reference to itself.
[hr]
The code
[code] Polynomial P("x^3 + x^2 + x + 1");

cout << P << '
' << P.RemoveLastTerm() << '
';[/code]
would assumably have the output
[code]x^3 + x^2 + x + 1
x^3 + x^2 + x[/code]
but, the output is
[code]x^3 + x^2 + x
x^3 + x^2 + x[/code]
This doesn't seem to make sense, looking from left to right at each of the things that is outputted. The only thing I can think of is that all the to-be-outputted objects are evaluated first, then the output starts from the beginning. But, this is really just a wild guess, and I was wondering why this occurs. Thanks for your time.

-Tony

Comments

  • : Hello,
    :
    : I recently came across something strange. I have a class, Polynomial, that is basically an array of terms, that are a coefficient and a power, ie 2x^3 or 3x. For the class there is an ostream (ie cout) operator defined to output the polynomial, along with a function to remove the last term. The latter functions returns a reference to itself.
    : [hr]
    : The code
    : [code] Polynomial P("x^3 + x^2 + x + 1");
    :
    : cout << P << '
    ' << P.RemoveLastTerm() << '
    ';[/code]
    : would assumably have the output
    : [code]x^3 + x^2 + x + 1
    : x^3 + x^2 + x[/code]
    : but, the output is
    : [code]x^3 + x^2 + x
    : x^3 + x^2 + x[/code]
    : This doesn't seem to make sense, looking from left to right at each of the things that is outputted. The only thing I can think of is that all the to-be-outputted objects are evaluated first, then the output starts from the beginning. But, this is really just a wild guess, and I was wondering why this occurs. Thanks for your time.
    :
    : -Tony
    :

    [blue]Since you did not post any of the code it is impossible for anyone to answer your question. I suggest you use your compiler's debugger and step through your class to find out why it is behaving badly. [/blue]

  • : [blue]Since you did not post any of the code it is impossible for anyone to answer your question. I suggest you use your compiler's debugger and step through your class to find out why it is behaving badly. [/blue]
    :
    :

    Sorry about the lack of code, but I don't think this is a class-specific issue. For example, the following code also demonstrates this behavior.

    [code]#include
    using namespace std;

    int main()
    {
    int i = 0;

    cout << i << '
    ' << (i+=2) << '
    ';

    return 0;
    }[/code]

    with the output being:

    [code]2
    2[/code]

    instead of (what I expected):

    [code]0
    2[/code]

    -Tony

  • This is an operator precedence issue. The assignment is being done before the output operator, so that the value of i is changed before it begins printing the results. I think it's because the parenthesis are higher priority than the output operator (<<).
    It works as expected if you do this:

    cout << i << endl;
    cout << i+=2 <<endl;

    I don't think there is any other way to do this, and it seems a violation of the principle of seperation of presentation and logic to do it the way you initially had it.

    :
    : Sorry about the lack of code, but I don't think this is a class-specific issue. For example, the following code also demonstrates this behavior.
    :
    : [code]#include <iostream>
    : using namespace std;
    :
    : int main()
    : {
    : int i = 0;
    :
    : cout << i << '
    ' << (i+=2) << '
    ';
    :
    : return 0;
    : }[/code]
    :
    : with the output being:
    :
    : [code]2
    : 2[/code]
    :
    : instead of (what I expected):
    :
    : [code]0
    : 2[/code]
    :
    : -Tony
    :
    :

  • : This is an operator precedence issue. The assignment is being done before the output operator, so that the value of i is changed before it begins printing the results. I think it's because the parenthesis are higher priority than the output operator (<<).
    : It works as expected if you do this:
    :
    : cout << i << endl;
    : cout << i+=2 <<endl;
    :
    : I don't think there is any other way to do this, and it seems a violation of the principle of seperation of presentation and logic to do it the way you initially had it.
    :

    Ah, i get it now. Looking back at the table of operator precedence, the output (<<) operator seems to have been omitted, unless it is the same as the left-shift (<<) operator (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_pluslang_c.2b2b_.operators.asp). Thanks, this now makes sense.

    : :
    : : Sorry about the lack of code, but I don't think this is a class-specific issue. For example, the following code also demonstrates this behavior.
    : :
    : : [code]#include <iostream>
    : : using namespace std;
    : :
    : : int main()
    : : {
    : : int i = 0;
    : :
    : : cout << i << '
    ' << (i+=2) << '
    ';
    : :
    : : return 0;
    : : }[/code]
    : :
    : : with the output being:
    : :
    : : [code]2
    : : 2[/code]
    : :
    : : instead of (what I expected):
    : :
    : : [code]0
    : : 2[/code]
    : :
    : : -Tony
    : :
    : :
    :
    :

  • : This is an operator precedence issue. The assignment is being done before the output operator, so that the value of i is changed before it begins printing the results. I think it's because the parenthesis are higher priority than the output operator (<<).
    : It works as expected if you do this:
    :
    : cout << i << endl;
    : cout << i+=2 <<endl;
    :
    : I don't think there is any other way to do this, and it seems a violation of the principle of seperation of presentation and logic to do it the way you initially had it.
    :

    I'm not sure if it's an (<<) operator precedence issue because the same situation exists when using printf.

    printf("%d, %d
    ", i, (i+=2));

    It just has to do with the whole statement being evaluated before any output occurs.



    : :
    : : Sorry about the lack of code, but I don't think this is a class-specific issue. For example, the following code also demonstrates this behavior.
    : :
    : : [code]#include <iostream>
    : : using namespace std;
    : :
    : : int main()
    : : {
    : : int i = 0;
    : :
    : : cout << i << '
    ' << (i+=2) << '
    ';
    : :
    : : return 0;
    : : }[/code]
    : :
    : : with the output being:
    : :
    : : [code]2
    : : 2[/code]
    : :
    : : instead of (what I expected):
    : :
    : : [code]0
    : : 2[/code]
    : :
    : : -Tony
    : :
    : :
    :
    :

    [italic][blue]To understand recursive, first you need to understand recursive[/blue][/italic]

  • : I'm not sure if it's an (<<) operator precedence issue because the same situation exists when using printf.
    :
    : printf("%d, %d
    ", i, (i+=2));
    :
    : It just has to do with the whole statement being evaluated before any output occurs.

    Yeah, I'm not sure either, but it still comes down to the fact that the math gets done before any output. Same for the function call that was the original example here.
  • [b][red]This message was edited by stober at 2003-10-1 19:18:23[/red][/b][hr]
    : : I'm not sure if it's an (<<) operator precedence issue because the same situation exists when using printf.
    : :
    : : printf("%d, %d
    ", i, (i+=2));
    : :
    : : It just has to do with the whole statement being evaluated before any output occurs.
    :

    [blue]If you look at the assembly language code for that printf statement it becomes clearer why the output is the same for i and i+=2 parameters. C/C++ push the values of the parameters in reverse order of that shown in the statements. So (i += 2) is evaluated first, the result saved in the storage location for i (becuse of the += operator) and the result pushed onto the stack for the function call. Then the second parameter (i) is pushed onto the stack, but by then the value of i is changed from the result of the previous operation. This is from my test example using VC++ 6.0. The program was compiled for debug mode, so some operations are not optimized.[/blue]
    [code]
    10: int i = 5;
    [red]//initialize i = 5[/red]
    00401218 mov dword ptr [ebp-4],5
    11: printf("%d
    %d", i, (i += 2));
    [red]// load eax with current value of i [/red]
    0040121F mov eax,dword ptr [ebp-4]
    [red]// increment eax by 2 (i += 2) [/red]
    00401222 add eax,2
    [red]// save new value in i [/red]
    00401225 mov dword ptr [ebp-4],eax
    00401228 mov ecx,dword ptr [ebp-4]
    [red]// push result of (i += 2) onto the stack for function call [/red]
    0040122B push ecx
    [red] // push first parameter (i) onto stack for function call [/red]
    0040122C mov edx,dword ptr [ebp-4]
    0040122F push edx
    [red] // push pointer to format string [/red]
    00401230 push offset string "%d
    %d" (0042201c)
    [red] // call printf function [/red]
    00401235 call printf (004017f0)
    0040123A add esp,0Ch
    12: return 0;
    [/code]


    [blue]Note that the result would have been what you expected had the function looked like below because the value of i is not changed.[/blue]
    [code]
    printf("%d
    %d", i, (i+2));
    [/code]











  • : [b][red]This message was edited by stober at 2003-10-1 19:18:23[/red][/b][hr]
    : : : I'm not sure if it's an (<<) operator precedence issue because the same situation exists when using printf.
    : : :
    : : : printf("%d, %d
    ", i, (i+=2));
    : : :
    : : : It just has to do with the whole statement being evaluated before any output occurs.
    : :
    :
    : [blue]If you look at the assembly language code for that printf statement it becomes clearer why the output is the same for i and i+=2 parameters. C/C++ push the values of the parameters in reverse order of that shown in the statements. So (i += 2) is evaluated first, the result saved in the storage location for i (becuse of the += operator) and the result pushed onto the stack for the function call. Then the second parameter (i) is pushed onto the stack, but by then the value of i is changed from the result of the previous operation. This is from my test example using VC++ 6.0. The program was compiled for debug mode, so some operations are not optimized.[/blue]
    : [code]
    : 10: int i = 5;
    : [red]//initialize i = 5[/red]
    : 00401218 mov dword ptr [ebp-4],5
    : 11: printf("%d
    %d", i, (i += 2));
    : [red]// load eax with current value of i [/red]
    : 0040121F mov eax,dword ptr [ebp-4]
    : [red]// increment eax by 2 (i += 2) [/red]
    : 00401222 add eax,2
    : [red]// save new value in i [/red]
    : 00401225 mov dword ptr [ebp-4],eax
    : 00401228 mov ecx,dword ptr [ebp-4]
    : [red]// push result of (i += 2) onto the stack for function call [/red]
    : 0040122B push ecx
    : [red] // push first parameter (i) onto stack for function call [/red]
    : 0040122C mov edx,dword ptr [ebp-4]
    : 0040122F push edx
    : [red] // push pointer to format string [/red]
    : 00401230 push offset string "%d
    %d" (0042201c)
    : [red] // call printf function [/red]
    : 00401235 call printf (004017f0)
    : 0040123A add esp,0Ch
    : 12: return 0;
    : [/code]
    :
    :
    : [blue]Note that the result would have been what you expected had the function looked like below because the value of i is not changed.[/blue]
    : [code]
    : printf("%d
    %d", i, (i+2));
    : [/code]
    :

    Yes Stober you're right about reverse order, because simply reversing the parameters causes the statement to work as expected. Something new to be learned everyday. ;-)

    [code]
    printf("%d, %d
    ", (i+=2), i);
    [/code]



    [italic][blue]To understand recursive, first you need to understand recursive[/blue][/italic]

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories