0

in C this works as I expect

void foo(int a, int b ) { printf("%i,%i ",a,b ); }

int main()
{
  int i=1;
  foo(i++,i);
  foo(i++,i);
  foo(i++,i);
  foo(i++,i);
  return(0);
}

output: 1,2 2,3 3,4 4,5

Now, the following does not work as I would have guessed: void foo(int a, int b ) { printf("%i,%i ",a,b ); }

int main()
{
  int a[] = { 100,200,300,400,500,600,700 };
  int i=0;
  foo(a[i++],a[i]);
  foo(a[i++],a[i]);
  foo(a[i++],a[i]);
  foo(a[i++],a[i]);
  return(0);
}

It returns 100,100 200,200 300,300 400,400

Following the logic of the previous example, I would have expected 100,200 200,300 300,400 400,500

My first suspicion was that the increment was only called after the function call, however, as the first example shows, i is indeed incremented inside the function call, unless it is used as an index for the array.

I also tried the same using foo(*(a+(sizeof(int)i++)),(a+(sizeof(int)*i))); just to check, and it also acts like the second example.

The compiler is gcc version 4.6.3

My question is, why does it work when I'm using the variable i directly as the function parameter, but not when I use the variable i as an index for an array which is used as the function parameter?

DusteD
  • 1,400
  • 10
  • 14
  • not only this is a duplicate, but also the question arises, why do people want to write such crufty code? what is so bad in doing `foo(a[i], a[i+1]); i++;` ? – Jens Gustedt Jan 23 '14 at 14:34
  • @JensGustedt: They write such code because they have a different mental model of how C works. In their model, arguments are completely evaluated in the order they are written, and `foo(i++, i)` is completely defined. The actual C model violates two normal human habits: The order of evaluation is not the same order the text is read in, and the order of evaluation is not uniquely determined. Because these properties are unfamiliar to some learners, they must be taught. The latter property is also abstract and therefore harder to teach by example. – Eric Postpischil Jan 23 '14 at 14:45
  • @JensGustedt for( i= 0; i < 8; i+=2) someFunction(array[i++], array[i] ); - That's why, I know I can just do someFunction( array[i], array[i+1] ); but that's way too readable. – DusteD Jan 23 '14 at 15:06

1 Answers1

4

Both of your code invokes undefined behavior. You may get either expected or unexpected result.
Compile your code with -Wall flag. Compiler should give the warning:

[Warning] operation on 'i' may be undefined [-Wsequence-point]  

Read the C_FAQ - 3.8. It explains this issue pretty well.

haccks
  • 104,019
  • 25
  • 176
  • 264