views:

348

answers:

3

Hello all, I have a simple question that I am posing mostly for my curiousity.

What are the differences between these two lines of code? (in C++)

for(int i = 0; i < N, N > 0; i++)

for(int i = 0; i < N && N > 0; i++)

The selection of the conditions is completely arbitrary, I'm just interested in the differences between , and &&.

I'm not a beginner to coding by any means, but I've never bothered with the comma operator.

Are there performance/behavior differences or is it purely aesthetic?

One last note, I know there are bigger performance fish to fry than a conditional operator, but I'm just curious. Indulge me.

Edit Thanks for your answers.

It turns out the code that prompted this question had misused the comma operator in the way I've described. I wondered what the difference was and why it wasn't a && operator, but it was just written incorrectly. I didn't think anything was wrong with it because it worked just fine. Thanks for straightening me out.

+28  A: 

Using a comma like that will simply discard the first condition.

The comma operator means "run these statements in this order, and take the value of the last one".

RichieHindle
as in it totally ignores it and doesn't perform the check?
Victor
The value of "`i < N, N > 0`" is the same as the value of "`N > 0`".
ephemient
@Victor: It compares i and N, discards the result, then compares N and 0 and uses the result to decide whether to continue the loop. In optimised code, it will probably not bother to compare i and N.
RichieHindle
The comparison will be performed, but the result will be discarded.
Fred Larson
See my answer for an explanation.
GMan
+3  A: 

Using && will short-circuit if i < N, but the comma operator can't do that.

It's being used incorrectly. The comma operator will have the value of the last statement in it. (5.18 in the C++ standard)

So this:

i < N, N > 0

Will execute i < N, discard the result, then execute N > 0, and use that as the result for the comma operator. That is, in this context you could just replace it with:

N > 0

And have the same behavior. You could probably try something like this:

for(int i = 0; (bool b = i < N, b = b && N > 0); i++)

Which will then be slower than i < N && N > 0, because both operators will execute, unless the compiler optimizes it into i < N && N > 0 anyway.

GMan
for(int i = 0; (bool b = i < N, b = b
CodeFusionMobile
David Thornley
Which is the point. I'm not sure why I was downvoted for this.
GMan
+8  A: 

Although it looks like it,

for(int i = 0; i < N, N > 0; i++)

and

for(int i = 0; i < N && N > 0; i++)

are not equivalent.

Here is the proof.

int main(int argc, char* argv[])
{
  int N = 10;
  int i = 5;

  int val = (N, i);
  cout << val << endl;
}

Result: 5

Which means that the when determining when the loop will exit it will use "N > 0" If N = 10, this means that it will always be true and the loop will never exit.

Run this and see the proof.

int main(int argc, char* argv[])
{
  int N = 10;
  int i = 5;

  for(int i = 0; i < N, N > 0; i++){
     cout << val << endl;
  }
}

bash-2.05$ ./a.out
0
1
2
3
4
5
6
7
8
9
10
11
... 142 143 144 145 146 147 148 ^C

If N is a constant or variable that doesn't change inside the loop then you could just remove the N > 0 check by checking it once first

i.e. if (N > 0){ for (int i = 0; i < N; i++) ... }

Matt H
I don't know why no one voted this up. I like a well thought out and detailed answer when I ask for an explaination. Thanks
CodeFusionMobile
I wouldn't vote it up because it doesn't clearly state the difference, and tries to determine the meaning by experiment, rather than looking at the standard or any documentation.
David Thornley
I like examples and experiments personally. RichieHindle's answer was short and accurate, but not very descriptive nor did it answer my question what is the actual difference. Even if this answer didn't detail the reason behind the problem, it did actually answer the question.
CodeFusionMobile
What do you do when the standard says it "should" do X but is actually doing Y? Compilers can have bugs too! Demonstration through experimentation shows the differences.
Matt H
Read standards and other documentation first, test on specific implementations second. That's my ranking, anyhow. If the compiler has a bug, then at least you know its a bug and won't be surprised if it gets fixed in the future.
ephemient