2
a[i] = i++;

Why does the above code not work?

What is wrong with above code? I am asking this question to improve my knowledge.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
Parag
  • 7,746
  • 9
  • 24
  • 29
  • 2
    what do u mean by doesnt work?any error you are getting or you are not getting the expected result??what what what? – Vijay Mar 30 '12 at 05:59
  • What does the code do? What did you expect it to do? – jkerian Mar 30 '12 at 06:00
  • Fun discovery in my undefined behavior searching just now: http://en.wikipedia.org/wiki/Undefined_behavior#Examples_in_C_and_C.2B.2B The last example is this exact snippet of code. (Bonus fun point, if you google "a[i] = i++;" a ton of a articles about UB come up. – Corbin Mar 30 '12 at 06:13
  • Re that possible duplicate, you need to be careful. Users asking a question like this will almost certainly not know the term "sequence point" so will be very unlikely to correlate the two questions. Not saying it isn't a dupe, just that I'd look for a better one than that. – paxdiablo Mar 30 '12 at 06:16
  • There's also this one: http://stackoverflow.com/questions/949433/could-anyone-explain-these-undefined-behaviors-i-i-i-i-i-etc But it doesn't have any array access examples. EDIT: It does, [this answer](http://stackoverflow.com/a/4177063/922184) has this exact example. – Mysticial Mar 30 '12 at 06:18
  • Each person must make their own mind up but I tend to only close if the _question_ is a dupe (because that's what people should look at before asking questions). Having to search through all the answers is not something I'd expect of them. But, as I say, make up your own mind - I suspect it will be closed because there's _bound_ to be a dupe somewhere even by my strict standards :-) – paxdiablo Mar 30 '12 at 06:33
  • 1
    @paxdiablo: If a dozen people ask questions about a dozen different lines of code that invoke UB due to lack of sequence points, would you leave them all open? If you don't already know the answer, there's no good way to ask the question, and it's nigh impossible to search for duplicates of this sort, even for well-intentioned askers who do their homework. – Adam Rosenfield Mar 30 '12 at 20:50

2 Answers2

9

Because the ISO standard says that you are not allowed to change a variable more than once (or change and use one) without an intervening sequence point.

There is no sequence point between the use of i in a[i] and the change of i in i++.

The list of sequence points from C11 (not really changed that much since C99) are described in Annex C:

  • Between the evaluations of the function designator and actual arguments in a function call and the actual call.
  • Between the evaluations of the first and second operands of the following operators: logical AND &&; logical OR ||; comma ,.
  • Between the evaluations of the first operand of the conditional ?: operator and whichever of the second and third operands is evaluated.
  • The end of a full declarator: declarators;
  • Between the evaluation of a full expression and the next full expression to be evaluated. The following are full expressions: an initializer; the expression in an expression statement; the controlling expression of a selection statement (if or switch); the controlling expression of a while or do statement; each of the expressions of a for statement; the expression in a return statement.
  • Immediately before a library function returns.
  • After the actions associated with each formatted input/output function conversion specifier.
  • 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.

and 5.1.2.3 Program execution states:

Evaluations A and B are indeterminately sequenced when A is sequenced either before or after B, but it is unspecified which.

The presence of a sequence point between the evaluation of expressions A and B implies that every value computation and side effect associated with A is sequenced before every value computation and side effect associated with B.

Section 6.5 Expressions pretty much covers your exact case:

If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.

This paragraph renders undefined statement expressions such as i = ++i + 1; and a[i++] = i; while allowing i = i + 1; and a[i] = i;.

Community
  • 1
  • 1
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
1

It does work, but possibly not as expected. The problem is if it's not clear if i gets incremented before the assignment and, if so, then a[i] will reference the next item in the array.

Your question was very terse so you can expand on it if you want more information. But it's just hard to tell exactly which element of a that syntax assigns to.

Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
  • No, it does not work. It is *undefined behavior*. – Adam Rosenfield Mar 30 '12 at 06:01
  • 3
    @Adam: Just because it's behavior is not defined by the standard hardly means that it doesn't work. Depending on the implementation, it might work very well. (Nevermind the fact that *doesn't work* is a horrible explanation and should never be used by developers trying to describe a technical problem.) – Jonathan Wood Mar 30 '12 at 06:03