Sign in to follow this  

Interesting about - -x

This topic is 3665 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

int main()
{
    int x = 100;
    printf("%d %d %d",--x, --x, --x);
    return 0;
}
Its output
97 98 99
Isn't it suppose to display 99 98 97? Another thing:
int main()
{
    int x = 100;
    x = --x + --x;
    printf("%d", x);
    return 0;
}
Its output
196
Isn't 99 + 98 = 197? Any explaination?

Share this post


Link to post
Share on other sites
"C++ requires that the arguments to a function be completely evaluated
(and all side-effects posted) prior to entering the function, but the
implementation is free to evaluate the arguments in any order."

So you are basically relying on undefined behavior.

The answer to your second question:

In your second example your compiler may evaluate the expression left of '+' first, or the expression right of '+'. Lets say it performs the left side first:

-First you perform 100-1, which is 99. This result is assigned to the variable 'x'
-Next you perform 99-1, which is 98. This result is assigned to the same variable 'x'
-As a result you evaluate x=98+98, which equals 196

Share this post


Link to post
Share on other sites
The C++ standard makes no guarantees about the order of evaluation in expressions containing several increment/decrement operators. For this reason, it's a good idea to keep such operations to expressions of their own.

I don't think there's anything too shocking about the results you're getting regarding the decrement operator, but I'm surprised that printf seems to parse its arguments in reverse-order.

The second example does exactly what I would expect: the -- operator precedes the = assignment, and so x is decremented twice before summing the result with itself. Though I'm not sure that this is reliable behaviour.

Share this post


Link to post
Share on other sites
1) The variables are pushed into the stack from "RIGHT TO LEFT." For example, when you're calling printf("%d", a, b, c), the actual function call will be...

push c
push b
push a
push offset "%d"
call _printf
(_cdecl functions readjust the stack by themselves.)

So when you call printf("%d %d %d", --x, --x, --x); the rightmost variable is subtracted first, then the middle one, then the left one. This is not undefined behavior. lol...

2) This one's a little tricky.

x = --x + --x;

-- directives are executed prior to = directive. So, --x is executed twice before the statement evaluates the total sum.

x = 98 + 98 = 196

Does this make sense? This one does not go from left to right either. x is subtracted twice in the statement, so x becomes 98. Then the two Xs are added into x. To help you understand, try these statements.

x = --x;
x = --x;
x = x + x;

Hope this helped.

Share this post


Link to post
Share on other sites
Here's the actual disassembly code from Visual Studio 2005. :)


2)

/////// int x = 100;
0041138E mov dword ptr [x],64h <-- x = 64h ( 16 * 6 + 4 = 100 )

/////// x = --x + --x;

//Step 1) Load x into eax register
00411395 mov eax,dword ptr [x]

//Step 2) Subtract 1 from eax register
00411398 sub eax,1

//Step 3) Store the value back to x
0041139B mov dword ptr [x],eax


//Step 4) Load x into ecx register
0041139E mov ecx,dword ptr [x]

//Step 5) Subtract 1 from ecx register
004113A1 sub ecx,1

//Step 6) Store the value back to x
004113A4 mov dword ptr [x],ecx


//Step 7) Load x into edx register
004113A7 mov edx,dword ptr [x]

//Step 8) edx = edx + x
004113AA add edx,dword ptr [x]

//Step 9) Store the value back to x
004113AD mov dword ptr [x],edx


In conclusion, x is subtracted twice before the addition.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sangha Im
So when you call printf("%d %d %d", --x, --x, --x); the rightmost variable is subtracted first, then the middle one, then the left one. This is not undefined behavior. lol...

It most certainly is. Today MSVC does it this way. Tomorrow it might decide to reorder things, particularly if it's inlining functions. Maybe it'll identify an unreferenced variable and move the decrement to after the statement. Maybe it won't. This is what it means for behavior to be undefined. Obviously it does something, but what it does should on no account be relied upon.

Share this post


Link to post
Share on other sites
Consider an expression which evaluates "--x" twice. Do the two expressions evaluate to 99 and 98 (as in the printf example) or to 98 and 98 (as in the addition example) ? There is no steadfast language-level rule for this, because the language standard has explicitly mentioned that such constructs are illegal. In short, don't use them, because there's no way to tell reliably what will happen.

Sangha Im:

Your explanation is wrong. Such a level of incorrectness as the one in your reply can only come from someone who is utterly ignorant of the notion of sequence points. Because of this, you are not a reliable source of information for order-of-evaluation and side-effect resolution in C and C++. I will politely suggest that you get a clue about this area of programming by reading the link OrangyTang provided (quoted above for your viewing pleasure) and all its cited sources.

Quote:
This is not undefined behavior. lol...


You've just described two situations which evaluated '--x' twice. In the first, the result is 99 and 98, while in the second it is 98 and 98. How can you call this defined?

Share this post


Link to post
Share on other sites
Even though I was able to trace out what happened in my reply, I was wondering if the result of his second example is defined:


int x = 100;
x = --x + --x;


As far as I know that should always equal 196, so my guess is that is it defined, but I've been wrong before.

Share this post


Link to post
Share on other sites
Actually thinking about it operator order makes it work out right. In the case of x = --x + --x. -- operator has higher precedence than +. so it has to perform both -- before the add giving 196.

Share this post


Link to post
Share on other sites
No.

The issue is with values being modified more than once between sequence points. There's no sequence points in that expression, other than the one following the completion of the expression itself (at which point undefined behavior has already been invoked).

Share this post


Link to post
Share on other sites
Quote:
Original post by stonemetal
In the case of x = --x + --x. -- operator has higher precedence than +. so it has to perform both -- before the add giving 196.


Operator precedence only describes how ambiguities are solved when the parentheses are absent.

That is, -- having greater precedence than + merely states that '--x + --x' should be parenthesized as '(--x) + (--x)' instead of '--(x + (--x))'. In particular, it has no bearing on the relative order of evaluation of the two terms (either may be executed before the other) or on whether the side-effects have a defined or undefined behavior.

Share this post


Link to post
Share on other sites

int main()
{
int x = 100;
x = --x + --x + --x + --x;
printf("%d", x);
return 0;
}


It output: 389

As you guy explained, it suppose to be x = 96 + 96 + 96 + 96 because it decrease
4 times. However 96 + 96 + 96 + 96 = 384. I found out that

x = 100
x = --x + --x = (99 + 98 - 1)

x = 100
x = --x + --x + --x = (99 + 98 + 97 - 1)

x = 100
x = --x + --x + --x + --x = (99 + 98 + 97 + 96 - 1)

Share this post


Link to post
Share on other sites
It's not supposed to be any particular value, it can be anything. It can even change if you change your compiler settings (for example from debug to release or back). It can also crash your program with a bus lock if it schedules two decrements on the same memory address at the same time on one of the more sensitive processor architectures.

Share this post


Link to post
Share on other sites
Quote:
Original post by DinGY
As you guy explained, it suppose to be


Actually, what we've been explained it that it's not supposed to be anything at all—it certainly is something, but there's no way to know ahead of time what the result will be.

Share this post


Link to post
Share on other sites

This topic is 3665 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this