Evaluation order when i++ is used

J

Jon

In the following, the second parameter value is put in arr2[2]. Can I assume that the first is also
put in arr1[2] and not arr1[3]? More generally, in C#, at what point is i incremented?

int i=2;
func(out arr1, out arr2[i++]);
 
J

Jon Skeet [C# MVP]

In the following, the second parameter value is put in arr2[2]. Can I assume that the first is also
put in arr1[2] and not arr1[3]? More generally, in C#, at what point is i incremented?

int i=2;
func(out arr1, out arr2[i++]);


First i is evaluated (for the first argument) then i is evaluated
again (for the second argument) then i is incremented.

However, code like this won't get past any worthwhile code review.
It's nice that the behaviour is specified, but it's awful in terms of
readability.

Jon
 
J

Jon

Thanks Jon.

Out of curiosity, is incrementing i always after evaluation, eg if the i++ is in the first rather
than in the second parameter, does the increment still happen after all evaluations?

Jon


In the following, the second parameter value is put in arr2[2]. Can I assume that the first is
also
put in arr1[2] and not arr1[3]? More generally, in C#, at what point is i incremented?

int i=2;
func(out arr1, out arr2[i++]);


First i is evaluated (for the first argument) then i is evaluated
again (for the second argument) then i is incremented.

However, code like this won't get past any worthwhile code review.
It's nice that the behaviour is specified, but it's awful in terms of
readability.

Jon
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,


--
Ignacio Machin
http://www.laceupsolutions.com
Mobile & warehouse Solutions.
Jon said:
Thanks Jon.

Out of curiosity, is incrementing i always after evaluation, eg if the i++
is in the first rather
than in the second parameter, does the increment still happen after all
evaluations?


AFAIK yes.

Now a more interesting question is what happens if instead of using the
after evaluation you use the before evaluation operator ( ++i) and do
something like :

func(out arr1[++i], out arr2[++i])

Again, I coincide with Jon, that is an horrible code!
 
J

Jon Skeet [C# MVP]

Out of curiosity, is incrementing i always after evaluation, eg if the i++ is in the first rather
than in the second parameter, does the increment still happen after all evaluations?

No - the first parameter is completely evaluated (including side-
effects), then the second parameter is completely evaluated, etc.

It's easy enough to show this:

using System;

public class Test
{
static void PrintArgs(int x, int y)
{
Console.WriteLine ("{0}, {1}", x, y);
}

static void Main(string[] args)
{
int i = 0;
PrintArgs (i++, i++);
Console.WriteLine ("i is now {0}", i);
}
}

The output is:

0, 1
i is now 2

Jon
 
L

Lasse Vågsæther Karlsen

Jon said:
In the following, the second parameter value is put in arr2[2]. Can I assume that the first is also
put in arr1[2] and not arr1[3]? More generally, in C#, at what point is i incremented?

int i=2;
func(out arr1, out arr2[i++]);


Regardless of how it works, wether it is specified somewhere and wether
you can trust that, the fact that you have to ask should tell you that
you should probably not use it that way.

Think of the next person that will have to decipher it, just because you
figured it out doesn't mean he knows how it works and perhaps that
person has to ask too, go to a newsgroup to figure it out...

Time lost.
 
M

Marc Gravell

Agree; it is also very susceptible to subtle bugs when it is
maintained... for instance, somebody decides the screen is showing the
wrong values for left/right (or it is showing a -ve instead of +ve,
etc)... "I know! swap the operands":

func(out arr2[i++], out arr1);

Oops!
 
J

Jon

Thanks Lasse, Jon Skeet and Ignacio on your comments on readability - I agree, I'm not going to use
it.

What are your thoughts on func(var, out arr2[i++]) where i is only referenced once?

On Jon Skeet's comment: "this won't get past any worthwhile code review" I don't have code reviews
since I'm actually an electronics designer, not a programmer. Sometimes though I need to write a
relatively short programme eg to test some theory. Programmers in the company I work for do have
code reviews, but I keep quiet about my programmes!

Jon


Jon said:
In the following, the second parameter value is put in arr2[2]. Can I assume that the first is
also
put in arr1[2] and not arr1[3]? More generally, in C#, at what point is i incremented?

int i=2;
func(out arr1, out arr2[i++]);


Regardless of how it works, wether it is specified somewhere and wether
you can trust that, the fact that you have to ask should tell you that
you should probably not use it that way.

Think of the next person that will have to decipher it, just because you
figured it out doesn't mean he knows how it works and perhaps that
person has to ask too, go to a newsgroup to figure it out...

Time lost.
 
J

Jon Skeet [C# MVP]

Thanks Lasse, Jon Skeet and Ignacio on your comments on readability -
I agree, I'm not going to use it.

Goodo :)
What are your thoughts on func(var, out arr2[i++]) where i is only referenced once?

The mixture of "out" (slightly confusing) and post-increment (slightly
confusing) seems a bad one to me. I'd separate them out. I *very
occasionally* use a pre/post-increment with a method parameter, but
only if it improves readability for some other reason.
On Jon Skeet's comment: "this won't get past any worthwhile
code review" I don't have code reviews
since I'm actually an electronics designer, not a programmer.
Sometimes though I need to write a relatively short programme eg to test some theory.
Programmers in the company I work for do have
code reviews, but I keep quiet about my programmes!

I think it's generally a good idea to *imagine* there will be a code
review when writing anything other than *completely* throw-away code
anyway.

Jon
 
J

Jon

Thanks Jon.

I suppose I like func(var, out arr2[i++]) because it's saying I've used i, now I need to increment
it straight away before I forget. However, in my case I won't be using it since i is used twice in
the function call as in my original example in a previous post.

If by "imagine" you mean that I should write code anticipating that someone else will check it, even
though no one will, then yes, I think that's a good point.

I can't take it too far though since I'd have to read up on the company coding standards which would
be quite a task. Also, everyone here uses C or C++ (often embedded programmes rather than GUI
programmes). I decided to change from DOS-based Turbo C++ to Windows-based C# a year ago since I can
get a free compiler (no purchase needed which also helps to hide away my programming). We have no
coding standards for C#.

This may sound very underhand, but it does get the job done.

Jon


Thanks Lasse, Jon Skeet and Ignacio on your comments on readability -
I agree, I'm not going to use it.

Goodo :)
What are your thoughts on func(var, out arr2[i++]) where i is only referenced once?

The mixture of "out" (slightly confusing) and post-increment (slightly
confusing) seems a bad one to me. I'd separate them out. I *very
occasionally* use a pre/post-increment with a method parameter, but
only if it improves readability for some other reason.
On Jon Skeet's comment: "this won't get past any worthwhile
code review" I don't have code reviews
since I'm actually an electronics designer, not a programmer.
Sometimes though I need to write a relatively short programme eg to test some theory.
Programmers in the company I work for do have
code reviews, but I keep quiet about my programmes!

I think it's generally a good idea to *imagine* there will be a code
review when writing anything other than *completely* throw-away code
anyway.

Jon
 
J

Jon Skeet [C# MVP]

I suppose I like func(var, out arr2[i++]) because it's
saying I've used i, now I need to increment
it straight away before I forget. However, in my case
I won't be using it since i is used twice in
the function call as in my original example in a previous post.

Do you really need it to be an out parameter rather than a return
value? That would make it considerably less complicated.
If by "imagine" you mean that I should write code anticipating
that someone else will check it, even
though no one will, then yes, I think that's a good point.

I can't take it too far though since I'd have to read up on the
company coding standards which would
be quite a task. Also, everyone here uses C or C++ (often
embedded programmes rather than GUI
programmes). I decided to change from DOS-based
Turbo C++ to Windows-based C# a year ago since I can
get a free compiler (no purchase needed which also helps
to hide away my programming). We have no coding
standards for C#.

This may sound very underhand, but it does get the job done.

I wouldn't worry about *company* coding standards - just imagine that
someone else might read the code some time, and think about what their
reaction might be.

Jon
 
J

Jon

"Do you really need it to be an out parameter rather than a return value? That would make it
considerably less complicated."

In my original example yes: func(out arr1, out arr2[i++]); but I've decided against this since
it's too confusing.

My new example was artificial - I was just curious about the more general case of using i++ as part
of a parameter expression where i is only used once in the parameters.


"I wouldn't worry about *company* coding standards - just imagine that someone else might read the
code some time, and think about what their reaction might be."

More good advise, thanks.

Jon


I suppose I like func(var, out arr2[i++]) because it's
saying I've used i, now I need to increment
it straight away before I forget. However, in my case
I won't be using it since i is used twice in
the function call as in my original example in a previous post.

Do you really need it to be an out parameter rather than a return
value? That would make it considerably less complicated.
If by "imagine" you mean that I should write code anticipating
that someone else will check it, even
though no one will, then yes, I think that's a good point.

I can't take it too far though since I'd have to read up on the
company coding standards which would
be quite a task. Also, everyone here uses C or C++ (often
embedded programmes rather than GUI
programmes). I decided to change from DOS-based
Turbo C++ to Windows-based C# a year ago since I can
get a free compiler (no purchase needed which also helps
to hide away my programming). We have no coding
standards for C#.

This may sound very underhand, but it does get the job done.

I wouldn't worry about *company* coding standards - just imagine that
someone else might read the code some time, and think about what their
reaction might be.

Jon
 
K

KWienhold

"Do you really need it to be an out parameter rather than a return value? That would make it
considerably less complicated."

In my original example yes: func(out arr1, out arr2[i++]); but I've decided against this since
it's too confusing.

My new example was artificial - I was just curious about the more general case of using i++ as part
of a parameter expression where i is only used once in the parameters.

"I wouldn't worry about *company* coding standards - just imagine that someone else might read the
code some time, and think about what their reaction might be."

More good advise, thanks.

Jon

I suppose I like func(var, out arr2[i++]) because it's
saying I've used i, now I need to increment
it straight away before I forget. However, in my case
I won't be using it since i is used twice in
the function call as in my original example in a previous post.

Do you really need it to be an out parameter rather than a return
value? That would make it considerably less complicated.
If by "imagine" you mean that I should write code anticipating
that someone else will check it, even
though no one will, then yes, I think that's a good point.
I can't take it too far though since I'd have to read up on the
company coding standards which would
be quite a task. Also, everyone here uses C or C++ (often
embedded programmes rather than GUI
programmes). I decided to change from DOS-based
Turbo C++ to Windows-based C# a year ago since I can
get a free compiler (no purchase needed which also helps
to hide away my programming). We have no coding
standards for C#.
This may sound very underhand, but it does get the job done.

I wouldn't worry about *company* coding standards - just imagine that
someone else might read the code some time, and think about what their
reaction might be.

Jon


"[...]just imagine that someone else might read the code some time,
and think about what their reaction might be."

Another good reason to heed this advice is that that someone may very
well be you, when you revisit the code a year from now.
 
L

Lasse Vågsæther Karlsen

Jon said:
Thanks Lasse, Jon Skeet and Ignacio on your comments on readability - I agree, I'm not going to use
it.

What are your thoughts on func(var, out arr2[i++]) where i is only referenced once?

On Jon Skeet's comment: "this won't get past any worthwhile code review" I don't have code reviews
since I'm actually an electronics designer, not a programmer. Sometimes though I need to write a
relatively short programme eg to test some theory. Programmers in the company I work for do have
code reviews, but I keep quiet about my programmes!

I'm replying a bit late here, busy with other things and all.

To be honest, I tend to not mix the ++ and -- syntax in with other
things if I can help it, the reason being that anything that makes me
stop, rewind a line or a couple of code points and re-read to understand
it interrupts the flow of the code, in my mind.

It's like reading a "heavy" book (doubt "heavy" is the right word,
except in norwegian), where you sometimes have to stop reading and
re-read an entire sentence, or worse, paragraph, just to understand what
the heck that the text is about.

I do use ++ and -- syntax though, but unless the expression becomes
*really* hard to write without it inside it, I tend to split it out and
if needs be, use a temporary variable.

It then becomes much easier to see if it occurs before the next
statement, or after the previous one.

Just my two cents anyway.
 
C

christery

To be honest, I tend to not mix the ++ and -- syntax in with other
things if I can help it, the reason being that anything that makes me
stop, rewind a line or a couple of code points and re-read to understand
it interrupts the flow of the code, in my mind.

bur for a little for loop, isn´t that sorta nice "for(int i=0; i<5; i+
+)"

//CY
 
M

Marc Gravell

LVK> tend to not mix the ++ and -- syntax in with other
LVK> things if I can help it,

CY> bur for a little for loop, isn´t that sorta
CY> nice "for(int i=0; i<5; i++)"

I think the key words here are "mix"..."in with other things" -
presumably meaning method invokes, indexers, obscure assignment
expressions with pre/post-increment/decrement, etc.
In this "for" context, the "for-iterator" (i++) is a single expression
that is not going to cause any confusion nor interrupt the flow; in
fact, almost any other syntax *would* break the flow as it would be
unexpected.

Marc
 
L

Lasse Vågsæther Karlsen

bur for a little for loop, isn´t that sorta nice "for(int i=0; i<5; i+
+)"

//CY

Of course I use it with for-loops, and I bet there are other small
places I use it as well, but the general rule for me is not to mix it
with other things.
 
B

Ben Voigt [C++ MVP]

Lasse Vågsæther Karlsen said:
Jon said:
Thanks Lasse, Jon Skeet and Ignacio on your comments on readability - I
agree, I'm not going to use it.

What are your thoughts on func(var, out arr2[i++]) where i is only
referenced once?

On Jon Skeet's comment: "this won't get past any worthwhile code review"
I don't have code reviews since I'm actually an electronics designer, not
a programmer. Sometimes though I need to write a relatively short
programme eg to test some theory. Programmers in the company I work for
do have code reviews, but I keep quiet about my programmes!

I'm replying a bit late here, busy with other things and all.

To be honest, I tend to not mix the ++ and -- syntax in with other things
if I can help it, the reason being that anything that makes me stop,
rewind a line or a couple of code points and re-read to understand it
interrupts the flow of the code, in my mind.

It's like reading a "heavy" book (doubt "heavy" is the right word, except
in norwegian), where you sometimes have to stop reading and re-read an
entire sentence, or worse, paragraph, just to understand what the heck
that the text is about.

I do use ++ and -- syntax though, but unless the expression becomes
*really* hard to write without it inside it, I tend to split it out and if
needs be, use a temporary variable.

It then becomes much easier to see if it occurs before the next statement,
or after the previous one.

I think a much better rule of thumb is that the variable that is being
incremented should not appear elsewhere on the line. Then it doesn't matter
when the value is incremented before or after other actions in the same
statement, it just matters whether the variable is read before or after the
increment and that is clear.

E.g.:

a[i++] = x + y; // good
a[i++] = i * x; // bad
 
H

Hilton

Jon said:
I think it's generally a good idea to *imagine* there will be a code
review when writing anything other than *completely* throw-away code
anyway.

Assume that the person who is going to maintain your code is a psychopathic
serial murder who knows where you live.

Hilton
 

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