Question

I'm trying to pin down my understanding of sequence points in C -- just wanted to check something. At present, I believe that (1) is undefined whereas (2) is merely unspecified, on the basis that in (2), there are sequence points after evaluating the arguments for g and h (so we're not modifying i twice between sequence points), but the order of evaluation of the arguments of f is still unspecified. Is my understanding correct?

#include <stdio.h>

int g(int i) {
    return i;
}

int h(int i) {
    return i;
}

void f(int x, int y) {
    printf("%i", x + y);
}

int main() {
    int i = 23;
    f(++i, ++i); // (1)
    f(g(++i), h(++i)); // (2)
    return 0;
}

EDIT:

It seems the key point here is whether the compiler is free to perform both the increments before either g or h is called -- my understanding from the answers below is that it is, although I'd appreciate confirmation that that's the case.

Was it helpful?

Solution

No, per 6.5.2.2 10 there is no sequence point between the evaluation of subexpression arguments, just before the actual call.

One way of looking at it is that it is unspecified whether the behaviour is undefined; if the implementation sequences the two ++i subexpressions before any call to g or h then the behaviour is undefined, but if the ++i subexpressions are evaluated as late as possible (immediately before calling g and h respectively) then the behaviour is unspecified. However, because the implementation is always at liberty to choose between any allowed unspecified behaviour then the overall result is undefined.

OTHER TIPS

Incorrect. Sequence points specify a partial order on the allowed ordering of operations. In case (2), there are sequence points:

  1. At the semicolon at the end of the line (1)
  2. After the evaluation of the arguments of g (i.e. the ++i) but before the call to g
  3. After the evaluation of the arguments of h (i.e. the ++i) but before the call to h
  4. After the evaluation of the arguments of f (i.e. after f and g have returned) but before the call to f
  5. After the return from f

So the partial order looks like this, from top to bottom:

    1
   / \
  /   \
 2     3
  \   /
   \ /
    4
    |
    | 
    5

2 and 3 are not ordered with respect to each other, since the order of evaluation of arguments is unspecified. Since i gets modified twice between the sequence points 1 and 4, the behavior is undefined.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top