5
int c = someIntegerValue;

// Some code...

int i;
for ( i = 0; i < 5, i < c; i++ ) {
...
}

My compiler says error: expression has no effect, which sounds about right. So, which of those 2 comparisons will be used here? My guess is the i < c is ignored, but I wanted some confirmation from others as I am not in a position to run this code yet...

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
Michael Dorgan
  • 12,453
  • 3
  • 31
  • 61
  • Not a C expert, but that seems like it is trying to do the equivalent of `i < 5 && i < c` in a strange way, but I'm not totally sure. – Robert McKee Jun 10 '13 at 20:54
  • Compiler's right. `i < 5` here is evaluated, but the value is thrown away without being used, and it has no side effects, so this programmer clearly misunderstood something. – Lee Daniel Crocker Jun 10 '13 at 21:12
  • Why the down vote and close votes? The comma operator isn't the most intuitive thing in the world. It tripped me up and I've been coding C for nearly 2 decades. – Michael Dorgan Jun 11 '13 at 17:32
  • possible duplicate of [What does the comma operator \`,\` do in C?](http://stackoverflow.com/questions/52550/what-does-the-comma-operator-do-in-c) – Mohit Jain Jul 09 '15 at 13:12

6 Answers6

14

The statement

i < 5, i < c

Uses the comma operator, which evaluates all the expressions from left to right but only produces the value of the rightmost one. This means that the expression i < 5 is evaluated and discarded, while the expression i < c is evaluated and actually used by the loop.

I assume that the author meant to write something like this:

i < 5 && i < c

which actually considers both of the expressions.

That said, I'm not sure why this is a compiler error and not a compiler warning. This is legal code, though it's almost certainly a bug. Perhaps you have set the compiler to report errors on warnings?

Hope this helps!

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
  • 4
    I wouldn't call that a "much better way to do this". The version with `&&` is semantically different from the version with the comma operator. It's very likely that the `&&` version is what the author *meant*, but it's impossible to be sure. – Keith Thompson Jun 10 '13 at 20:56
  • 2
    `i < 5 && i < c` and `i < 5 , i < c` are not same. The right expression depends on the logic that original author wanted to implement. – Shiplu Mokaddim Jun 10 '13 at 20:57
  • I believe in `i < 5, i < c`, `i < 5` will be removed my compiler-optimization phase, as its = to not a statement. – Grijesh Chauhan Jun 11 '13 at 11:35
7

That's a comma operator. It evaluates its left and right operands (always in that order), and yields the result of the right operand. It makes sense to use it if the left operand is evaluated for its side effects; since i < 5 has no side effects, your compiler warns you about it.

It's i < 5, not i < c that's ignored. The code is equivalent to:

for ( i = 0; i < c; i++ ) {
     ...
}

It's difficult to guess what it was intended to be. Perhaps the author actually meant:

for ( i = 0; i < 5 && i < c; i++ ) {
    ...
}
Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
3

It is i < 5 that is ignored.

The complete expression is:

i < 5, i < c

Which is two separate expressions joined by the comma-operator.

The comma-operator works by evaluating the first expression (i < 5), then the second expression (i < c), and the full expression takes on the value of the second part.

The first part of the expression only matters if it has side-effects.

It is commonly, and correctly used this way:
example

for(i = 0, j = 10; i < 10; ++i, --j)
/* i goes from 0-10, while j goes from 10-0 at the same time */

But in the way shown in your code, it has no meaningful purpose, and only confuses other people.

abelenky
  • 63,815
  • 23
  • 109
  • 159
3

The result of the comma operator is the value of the right operand.

Here the left operand (i < 5) has no side-effect so

i < 5, i < c

is actually equivalent to

i < c
ouah
  • 142,963
  • 15
  • 272
  • 331
2

It's a result of using the comma operator. The left expression is evaluated, and then the result is discarded. After that the right expression is evaluated. The comma operator's result is the result of the right expression.

Since the left expression (i < 5) is a no-op, you get the warning you're seeing. The question now is "what did the author intend?" Without more context, we can't really say, but it's likely one of these:

  i < 5
  i < c
  i < 5 && i < c
Carl Norum
  • 219,201
  • 40
  • 422
  • 469
1

Here , comma operator plays a role. Means, it evaulates from left to right and returns the last expression. So i<5 is evaluated, i<c is evaluated but returns i<c result as its the last expression.

i < 5, i < c is completely pointless. It has not difference with i < c.

Depending on authors logic its a mistake.

Shiplu Mokaddim
  • 56,364
  • 17
  • 141
  • 187