a = a++

M

Mugunth

Can anyone de-mystify this?

I wrote a C# program, the entire code is shown below.

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int a = 0;
a = a++;
Console.WriteLine(a.ToString());
}
}
}

The output is 0 and not 1 as expected.

My question here is, why is C# ignoring the post increment operator
during a self-assignment?
I created a class and wrote a operator ++ function and tried the same
instead of "int". the operator overloaded function is getting called!

Alternatively if the assignment statement is changed to b = a++; the
output (value for a) is 1.

Can anyone de-mystify this?
 
J

Jon Skeet [C# MVP]

Mugunth said:
Can anyone de-mystify this?

I wrote a C# program, the entire code is shown below.

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int a = 0;
a = a++;
Console.WriteLine(a.ToString());
}
}
}

The output is 0 and not 1 as expected.

My question here is, why is C# ignoring the post increment operator
during a self-assignment?

It's not. The post-increment is happening, and *then* the assignment is
happening. The value assigned is the original value (because you're
using a *post* increment) so the overall result is a no-op.

The main point to take out of this is that writing code with
side-effects like this is a bad idea in terms of readability, even
though at least C# specifies the exact behaviour.

Jon
 
?

=?ISO-8859-2?Q?Marcin_Grz=EAbski?=

Hi,

Mugunth napisa³(a):
Can anyone de-mystify this?

I wrote a C# program, the entire code is shown below.

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int a = 0;
a = a++;
Console.WriteLine(a.ToString());
}
}
}

The output is 0 and not 1 as expected.

My question here is, why is C# ignoring the post increment operator
during a self-assignment?
I created a class and wrote a operator ++ function and tried the same
instead of "int". the operator overloaded function is getting called!

Alternatively if the assignment statement is changed to b = a++; the
output (value for a) is 1.

Can anyone de-mystify this?

This is my version:

a=0;
a=Function(ref a);

// where a=Function(ref a) equals a=a++
static int Function(ref a1) {
int result=a1;
a1++;
return result;
}

So, result is taken before 'a' incrementation, but
it is asigned to 'a' after whole function.

with regards
Marcin
 
M

Michael C

Mugunth said:
Can anyone de-mystify this?

I wrote a C# program, the entire code is shown below.

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int a = 0;
a = a++;
Console.WriteLine(a.ToString());
}
}
}

The output is 0 and not 1 as expected.

My question here is, why is C# ignoring the post increment operator
during a self-assignment?
I created a class and wrote a operator ++ function and tried the same
instead of "int". the operator overloaded function is getting called!

Alternatively if the assignment statement is changed to b = a++; the
output (value for a) is 1.

It must grab the value for a, increment a and then assign the original value
to a. You probably shouldn't write code like this although I presume you're
just doing this as a test.

Michael
 
M

Mugunth

Hey,
Thanks, I could understand the behavior now.
But, in why is this behavior of C# different from conventional C++?
(where value of a becomes 1)

Has platform independence something to do with this?
FYI: Java also behaves this way. (value of a = 0)

Is there any distinct relationship between this way of treating
precedence and CLR/CTS rules?

Regards,
Mugunth
Mugunth said:
Can anyone de-mystify this?

I wrote a C# program, the entire code is shown below.

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int a = 0;
a = a++;
Console.WriteLine(a.ToString());
}
}
}

The output is 0 and not 1 as expected.

My question here is, why is C# ignoring the post increment operator
during a self-assignment?

It's not. The post-increment is happening, and *then* the assignment is
happening. The value assigned is the original value (because you're
using a *post* increment) so the overall result is a no-op.

The main point to take out of this is that writing code with
side-effects like this is a bad idea in terms of readability, even
though at least C# specifies the exact behaviour.

Jon
 
A

Alex

Mugunth пиÑал(а):
Can anyone de-mystify this?

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int a = 0;
a = a++;
Console.WriteLine(a.ToString());
}
}
}

The output is 0 and not 1 as expected.

My question here is, why is C# ignoring the post increment operator
during a self-assignment?
I created a class and wrote a operator ++ function and tried the same
instead of "int". the operator overloaded function is getting called!

Can anyone de-mystify this?

As you know, there are two types of using operator ++. a++ and ++a.
In first case firstly doing operation =, then ++.
But after operation =, result mustn't change, so operation a++ isn't
working.
In second case firstly ++, then =.
a = ++a will return 1.
I try it. For a result is 1, but for b is 0.
 
B

Ben Newsam

It's not. The post-increment is happening, and *then* the assignment is
happening. The value assigned is the original value (because you're
using a *post* increment) so the overall result is a no-op.

It can't be quite as simple as that. In the "normal" way, if the
increment operator is applied first, the value of "a" would become 1,
which then would be assigned to "a". If it were the other way round,
zero would be assigned to "a", which would then be incremented. Those
are the only logical inferences to be drawn from a line like "a =
a++". A zero result implies that both operations are performed
simultaneously.
 
H

Hans Kesting

It's not. The post-increment is happening, and *then* the assignment is
happening. The value assigned is the original value (because you're
using a *post* increment) so the overall result is a no-op.

It can't be quite as simple as that. In the "normal" way, if the
increment operator is applied first, the value of "a" would become 1,
which then would be assigned to "a". If it were the other way round,
zero would be assigned to "a", which would then be incremented. Those
are the only logical inferences to be drawn from a line like "a =
a++". A zero result implies that both operations are performed
simultaneously.
[/QUOTE]

It doesn't need to be simultaneous: if I understand correctly, the
statement 'a=a++' means: assign to "a" the value of the expression
"a++". The value of that expression is the "old" value of 'a' (=0).
Then the value of 'a' is increased (a++ is executed, so 'a' will now be
1). But the assignment (a=...) happens last, so 'a' will be assigned
the value of the exression, which is it's old value (0).

Hans Kesting
 
M

Mugunth

I agree Hans,
But why is it so happens that in C++, the same program gives 1 as
output?
I guess that there is a strong correlation between this *unexpected*
result and
C# memory model. (The way operations are broken down in IL).
I'm not sure whether this memory model has anything to do with Platform
Independence as Java also behaves this way.
It'll be gr8 if someone can throw light on this.

Regards,
Mugunth
 
E

Ebbe Kristensen

Mugunth said:
I agree Hans,
But why is it so happens that in C++, the same program gives 1 as
output?

Because in the C++ standard, the result of that operation is undefined. So
even though the compiler(s) you have tested this on produces the result 1,
that may not be the case for other compilers.

Ebbe
 
J

Jon Skeet [C# MVP]

Mugunth said:
Thanks, I could understand the behavior now.
But, in why is this behavior of C# different from conventional C++?
(where value of a becomes 1)

C/C++ doesn't actually specify the behaviour here. You may well find
that different compilers give you different results.
Has platform independence something to do with this?
FYI: Java also behaves this way. (value of a = 0)

Indeed - because it's the more logical way of working, IMO. Each
expression is evaluated in turn, with the side effects being processed,
and then the assignment occurs.
Is there any distinct relationship between this way of treating
precedence and CLR/CTS rules?

Nope - the CLR isn't involved here at all, I believe.

Jon
 
J

Jon Skeet [C# MVP]

Ben said:
It can't be quite as simple as that. In the "normal" way, if the
increment operator is applied first, the value of "a" would become 1,
which then would be assigned to "a".

No - the result of the expression is assigned to "a", and the result of
the expression "a++" is "the original value of a".
If it were the other way round,
zero would be assigned to "a", which would then be incremented. Those
are the only logical inferences to be drawn from a line like "a =
a++". A zero result implies that both operations are performed
simultaneously.

Not at all. The assignment happens after the post increment, but the
*original* value is used as the result of the expression, which is the
whole point of a post increment.
From the spec:

<quote>
* x is evaluated to produce the variable.
* The value of x is saved.
* The selected operator is invoked with the saved value of x as
its argument.
* The value returned by the operator is stored in the location
given by the evaluation of x.
* The saved value of x becomes the result of the operation.
</quote>

Jon
 
D

david.boyle

Mugunth said:
I agree Hans,
But why is it so happens that in C++, the same program gives 1 as
output?
<snip>

"C++" doesn't give that value back - the compiler you used to test this
on just so happened to give 1 as ouput but it could give any value back
at all. There isn't a sequence point between these two operations on
'a' so the behaviour in C++ is completely undefined.

This is an interesting test to gain a better understanding of side
effects and sequence points but this sort of code should *never* show
up in production software.

Cheers,

Dave
 
M

Mike Klaene

As someone who has taught Intro to C++, you have fallen into a common
trap. You always have to be careful whenever the same variable appears
on both sides of the assignment operator as you are usually at the mercy
of the compiler writers as to what will actually happen.

While I have not read the rules for C#, my feelings are that the results
of the " a = a++ " expression is probably undefined.
 
J

Jon Skeet [C# MVP]

Mike Klaene said:
As someone who has taught Intro to C++, you have fallen into a common
trap. You always have to be careful whenever the same variable appears
on both sides of the assignment operator as you are usually at the mercy
of the compiler writers as to what will actually happen.

While I have not read the rules for C#, my feelings are that the results
of the " a = a++ " expression is probably undefined.

Fortunately not - the ordering of expression evaluation is much more
clearly defined in C#.
 
B

Bruce Wood

Ben said:
It can't be quite as simple as that. In the "normal" way, if the
increment operator is applied first, the value of "a" would become 1,
which then would be assigned to "a".
If it were the other way round,
zero would be assigned to "a", which would then be incremented.

You misunderstand how a++ post-increment works. You're confusing the
assignment and the post-increment because you see "a" on both sides of
the assignment operator, so you're mentally turning it into a single
operation. It isn't. Here are the two possibilities you outlined,
correctly stated:

1. The counterintuitive way: assignment happens before post-increment,
so the result of "a++" (which is 0) is assigned to a, then a is
incremented via the post-increment operator, leaving a as 1.

2. The logical way (which is what the C# spec says): assignment happens
after post-increment, so a is incremented first (setting a to 1), and
then the result of the post-increment operation (which is 0) is
assigned to a, leaving a as 0.

It's that last bit that's confusing you: the result of a++ is 0, not 1.
The "result of a++" and the "value of a" are not the same thing. That's
why it's called POST-increment: the result of the expression is the
value before increment, and the value of the variable thus increment is
_not_ the same as the result of the expression.

Now, if one were to write:

a = ++a;

then the result will be 1, not 0, because the result of the
PRE-increment operator is the incremented value, and in that case the
result of the expression and the value of "a" would be the same.
Those are the only logical inferences to be drawn from a line like "a = a++".

Only if you misunderstand how a++ works.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top