Click here to Skip to main content
15,867,686 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
int a = 3;
int b = 5;
int c = 40;
int d = c-- - b * a;
Console.WriteLine($"a={a}, b={b} c={c} d={d}");

an order of "c-- - b * a" expression handling expected like this :

39 15
int d = (c--)-(b*a); == 24? of cource not! d=25!

because in fact an execution order is following:

int d = c-(b*a); and c-- is postdecrement operation and lost somehow

so thiese expressons are equal

int d = c-(b*a) and
int d = (c--)-(b*a)

Could somebody explain how?

and moreover!

if you'll try to use QuickWatch on (c-- - b * a), it fulfilles the procedure in the background and changes the c so when you try to use it again, the result will be 24! because the c has being changed.
I believe it is not correct
because QuickWatch should execute the expression, but in the different place somewhere and shouldn't change the variable.

What I have tried:

simple arythmetic question C#.
Posted
Updated 3-Feb-20 3:10am
Comments
Richard Deeming 4-Apr-19 12:01pm    
Any code which tries to be "clever" by mixing an increment/decrement operator into a larger set of operations in a single statement should be thrown out. There's absolutely no benefit to doing it; it just makes your code harder to read. Even developers with lots of experience of "clever" code will have to stop and think to work out what it's supposed to be doing.

They aren't the same. c-- is a postfix operator which changes c after it's been used.
You need to be very careful when using these, as the results you get may not be what you expected. See here: Why does x = ++x + x++ give me the wrong answer?[^]

Quote:
Thank you so much! I've read an article and found the "Precedence and Order of Evaluation" from MSDN.
For the moment the precedence of operators doesn't answer the question "why"
for example
int a = 5;
int b = 3;
int i = 10;
int x = (i++) + a * b;
logically (if we agree with precedence) i should be 11 (!) and x = 26, not 25, because i++ is placed in brackets.
but the ++ operator is still omit eventually, no matter on evaluation direction


No, you are wrong.
C#
int x = i++ + a * b;
Is using a post fix increment, which says, "use the current value of i and then add one to i"
If you write it long hand, you get this:
C#
int i2 = i;
i += 1;
x = i2 + a * b;
which is:
C#
25 == 10 + 3 * 5;
That's why mixing auto increment and decrement operators in the same expression is so fraught: there are no universal rules to say exactly when the increment should be done.
Think of this, assuming i is 10
C#
x = i++ + i;
What is the value of x?
20?
21?
22?

The "right" answer is 21, and i ends up as 11.
C#
int i2 = i;
i += 1;
x = i2 + i;
But ... it could easily be 20 if strictly evaluated from right to left:
C#
x = i + i;
i += 1;
 
Share this answer
 
v2
Comments
[no name] 2-Apr-19 4:18am    
Hi!
put thiese two expressions in c# and execute.
The result will be equal
OriginalGriff 2-Apr-19 5:20am    
The result in "d" will be the same, which is the whole point - but teh value in "c" will not!
A post decrement in the middle of an expression is perfectly legal - and even sometimes wanted. It has a "side effect" that c is decremented, but it's perfectly legal and will work.
There is no warning, because it does what it is expected and designed to do!
[no name] 2-Apr-19 5:30am    
the question was not about the syntax or uderstanding of an operation execution.
I meant the following:
(look at Solution_2 log)

"look, you should agree, this is not normal situation
int d = c--; // the "c--" is in the end of expression. I agree when the expression is closed after this, the postdecrement operation works as expected and in this case "d==c"

int d = c-- - b * a; //but in this case "c--" is in the middle of an expression and apparently should be executed totally to return the value to the expression it participates

The question is in evidence of an execution
OriginalGriff 2-Apr-19 5:50am    
No, you don't understand. It's a perfectly normal situation.

Pre- and post-fix operators can be used on any lvalue at any point in an expression, they aren't fixed to the "end" of an expression (particularly since many compilers evaluate expressions right to left not left to right, when the order isn't important)

Doesn't matter if you don't "think they should" - they can, just like any other unary operator. Or are you suggesting that "a * -b * c" shouldn't be allowed as well? :laugh:

And the real problem is that it is a "side effect" operator, so you shouldn't write complicated expressions using them. But there is nothing stopping you doing that (other than the ultimate results are not defined in many languages and may change without notice).
[no name] 2-Apr-19 7:12am    
Oh! And That Is quite interesting:
"particularly since many compilers evaluate expressions right to left not left to right, when the order isn't important"
I consider this answer "why" for me!
I did'n know that.

Thank you!
As you are stating yourself, you are using a postdecrement - so the value of c will change after it is used in your expression.

So
d=(c--)-(b*a);
is identical to:
d=c-b*a; c=c-1;
Just like
d=(--c)-(b*a);
is identical to
c=c-1;d=c-b*a;
It only gets really fun when you have multiple of them operating on one variable in one statement. Fun to play with, but never used in production code so personally I just forgot how that works.
 
Share this answer
 
Comments
[no name] 2-Apr-19 4:15am    
Hi!
An explanation is clear.
Asking my question, I meant the operation in this case is not obvious.
It should be the warning mechanism in c# to make is more obvious
lmoelleb 2-Apr-19 4:19am    
The operation is doing exactly what this operation has been doing for many decades across multiple languages - so what exactly should the warning be? Something like "If you do not know how this operation works it might give a different result than you expect"... but that goes for everything. :)
[no name] 2-Apr-19 4:32am    
look, you should agree, this is not normal situation
int d = c--; // the "c--" is in the end of expression. I agree when the expression is closed after this, the postdecrement operation works as expected.
int d = c-- - b * a; //but in this case "c--" is in the middle of an expression and apparently should be executed to return the value to the expression it participates

.But still.. You right "this operation has been doing for many decades across multiple languages"
lmoelleb 2-Apr-19 4:37am    
Personally I prefer avoiding the style, but I would not go so far as saying it is not normal, nor that it should be avoided in all cases. Maybe you can find (or write) a code analyzer if you prefer avoiding it? That way you will get a warning.
[no name] 2-Apr-19 4:40am    
See, "Personally I prefer avoiding the style" - that is what I meant.
Quote:
I believe it is not correct
Your belief is wrong. See, for instance: Increment and decrement operators - Wikipedia[^].
 
Share this answer
 
Interesting. I've never tried a question like this.

This is only a shot in the dark, but do you think the program is reading
"(C--) - (a*b)"
as
"(C(-1)(-1)) - (a*b)"?

I know it's a stretch, but if there's two negatives right next to an int, perhaps they're both turned into (-1)? If that's true, then putting them together multiplies into a multiple of +1:

d = (c--) - (a*b)
d = (c(-1)(-1)) - (3*5)
d = (c(1)) - (15)
d = 40 - 15
d = 25
 
Share this answer
 
Comments
Richard Deeming 3-Feb-20 10:20am    
That's not what's happening. Have a read of the previous solutions, which explain what the problem is.
Jay-Mickey 4-Feb-20 12:02pm    
Ah, I see now.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900