Public Group

# Interesting about - -x

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

## 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 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.

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 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 on other sites
Sequence points. Modifying the same variable twice between sequence points is undefined. Since neither the commas in the function call or the plus operator are sequence points, both are undefined behaviour.

##### Share on other sites
Quote:
 Original post by OrangyTangboth are undefined behaviour.

In a nutshell, your program might launch nuclear missiles. So please don't run it!

##### 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 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 on other sites
Quote:
 Original post by Sangha ImSo 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 on other sites
I think I get you guy mean now. Thanks you

##### 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?

1. 1
2. 2
3. 3
Rutin
22
4. 4
5. 5

• 13
• 19
• 14
• 9
• 9
• ### Forum Statistics

• Total Topics
632936
• Total Posts
3009312
• ### Who's Online (See full list)

There are no registered users currently online

×