2

Cosider the sequence points in the following expression

i = (++i,i++,i);

If I am correct the steps of execution will be as follows:

1)

++i, i++

2)

step1,i

3)

i = step2

For evaluation in step 1, the value of i should be modified only once for the construct to be termed as defined(since after evaluation of comma operator there is a sequence point). But I think it is not the case here. Hence it should be undefined. Please see this answer. Here the above expression is termed as defined. Am I missing something ?

Community
  • 1
  • 1
bubble
  • 3,408
  • 5
  • 29
  • 51
  • 1
    Annex C of the C11 final draft: *The following are the sequence points described in 5.1.2.3: [...] Between the evaluations of the first and second operands of the following operators: logical AND && (6.5.13); logical OR || (6.5.14); **comma ,** (6.5.17).* You are missing a sequence point which happens between `++i` and `i++`. – DCoder Sep 01 '12 at 07:04
  • I would strongly recommend using `i += 2` instead, and avoid the problem. :-) – Bo Persson Sep 01 '12 at 09:55
  • @BoPersson It was about finding the problem which may exist.. And I feel it's good to avoid while knowing what exactly we are avoiding. – bubble Sep 01 '12 at 10:00
  • 1
    @bubble - I just couldn't resist. :-) We get several questions here every week about `i = i++ + ++i - i--;` and don't see why it is so interesting. If you take code like this to a code review, your boss will hit you over the head anyway! – Bo Persson Sep 01 '12 at 10:04

1 Answers1

4

The behavior of the following instruction is well-defined.

i = (++i, i++, i);

There is indeed a sequence point between the evaluations of the first and the second operands of the comma operator (,). The annex C of the standard, although informative, provides a description of the sequence points.

C11, Annex C Sequence points

The following are the sequence points described in 5.1.2.3:

— Between the evaluations of the function designator and actual arguments in a function call and the actual call. (6.5.2.2).

— Between the evaluations of the first and second operands of the following operators: logical AND && (6.5.13); logical OR || (6.5.14); comma , (6.5.17).

— Between the evaluations of the first operand of the conditional ? : operator and whichever of the second and third operands is evaluated (6.5.15). — The end of a full declarator: declarators (6.7.6);

— Between the evaluation of a full expression and the next full expression to be evaluated. The following are full expressions: an initializer that is not part of a compound literal (6.7.9); the expression in an expression statement (6.8.3); the controlling expression of a selection statement (if or switch) (6.8.4); the controlling expression of a while or do statement (6.8.5); each of the (optional) expressions of a for statement (6.8.5.3); the (optional) expression in a return statement (6.8.6.4).

— Immediately before a library function returns (7.1.4). — After the actions associated with each formatted input/output function conversion specifier (7.21.6, 7.29.2).

— Immediately before and immediately after each call to a comparison function, and also between any call to a comparison function and any movement of the objects passed as arguments to that call (7.22.5).

md5
  • 23,373
  • 3
  • 44
  • 93