简体   繁体   中英

Sequence points in C / function calls

I'm just learning some C, or rather, getting a sense of some of the arcane details. And I was using VTC advanced C programming in which I found that the sequence points are :

  • Semicolon
  • Comma
  • Logical OR / AND
  • Ternary operator
  • Function calls (Any expression used as an argument to a function call is finalized the call is made)

are all these correct ?. Regarding the last one I tried:

void foo (int bar) { printf("I received %d\n", bar); }

int main(void) 
{

  int i = 0;

  foo(i++);

  return 0;

}

And it didnt print 1, which according to what the VTC's guy said and if I undertood correctly, it should, right ?. Also, are these parens in the function call the same as the grouping parens ? (I mean, their precedence). Maybe it is because parens have higher precedence than ++ but I've also tried foo((i++)); and got the same result. Only doing foo(i = i + 1); yielded 1.

Thank you in advance. Please consider that I'm from South America so if I wasnt clear or nothing makes sense please, oh please, tell me.

Warmest regards, Sebastian.

Your code is working like it should and it has nothing to do with sequence points. The point is that the postfix ++ operator returns the non-incremented value (but increments the variable by 1 nonetheless).

Basically:

  • i++ – Increment i by one and return the previous value
  • ++i – Increment i by one and return the value after the increment

The position of the operator gives a slight hint for its semantics.

Sequence means i++ is evaluted before foo is invoked.

Consider this case ( I am not printing bar ! ):

int i = 0;
void foo (int bar) { printf("i = %d\n", i); }
int main(void){
    foo(i++);
    return 0;
}

i = 1 must be printed.

C implements pass-by-value semantics. First i ++ is evaluated, and the value is kept, then i is modified (this may happen any time between the evaluation and the next sequence point), then the function is entered with the backup value as the argument.

The value passed into a function is always the same as the one you would see if using the argument expression in any other way. Other behavior would be fairly surprising, and make it difficult to refactor common subexpressions into functions.

When you do something like: int i = 0, j;

j = i++;

the value of i is used first and then incremented. hence in your case the values of i which is 0 is used (hence passed to your function foo) and then incremented. the incremented values of i (now 1) will be available only for main as it is its local variable.

If you want to print 1 the do call foo this way:

foo(++i);

this will print 1. Rest you know, why!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM