Skip to content

C Post Increment Assignment Of Rents

The behavior of "++i * ++i" is undefined, and the result will vary from implementation to implementation. Refer to the C language standard, section 6.5, paragraphs 2 and 3. The behavior of modifying the value of an object through the evaluation of an expression more than once between sequence points is undefined. The behavior of using the value of an object in one expression when its being modified in another expression without an intervening sequence point is also undefined.

So, the result of expressions like ++i * ++i is undefined, but so is the result of expressions like a[i] = i++ (or a[i++] = i).

Why is this the case? With few exceptions, C does *not* guarantee that expressions are evaluated from left to right, nor does it guarantee that side effects are applied *immediately* after an expression has been evaluated. For example, given the expression

z = ++x * y++

the following sequence of operations is allowed:

t0 = y
t1 = x + 1
z = t1 * t0
y = y + 1
x = x + 1

gcc on SLES 10 also gives me 49 as opposed to the expected 42. See the generated assembly below to understand why; i gets updated twice *before* the multiplication happens.

  1.    1              >----->-------.file>--"undef.c"<

  2.    2              >----->-------.section>-------.rodata<

  3.    3              >-----.LC0:<

  4.    40000 7A203D20 >---->-------.string>"z = %d, i = %d


  5.    4      25642C20-<

  6.    4      69203D20-<

  7.    4      25640A00-<

  8.    5              >----->-------.text<

  9.    6              >-----.globl main<

  10.    8              >-----main:<

  11.    9              >-----.LFB2:<

  12.   10000055       >---->-------pushq>--%rbp<

  13.   11              >-----.LCFI0:<

  14.   120001 4889E5   >---->-------movq>---%rsp,%rbp<

  15.   13              >-----.LCFI1:<

  16.   140004 4883EC10 >---->-------subq>---$16,%rsp<

  17.   15              >-----.LCFI2:<

  18.   160008 C745F805 >---->-------movl>---$5,-8(%rbp)<

  19.   16      000000<

  20.   17 000f 8345F801 >---->-------addl>---$1,-8(%rbp)<

  21.   180013 8345F801 >---->-------addl>---$1,-8(%rbp)<

  22.   190017 8B45F8   >---->-------movl>----8(%rbp),%eax<

  23.   20 001a 0FAF45F8 >---->-------imull>---8(%rbp),%eax<

  24.   21 001e 8945FC   >---->-------movl>---%eax,-4(%rbp)<

  25.   220021 8B55F8   >---->-------movl>----8(%rbp),%edx<

  26.   230024 8B75FC   >---->-------movl>----4(%rbp),%esi<

  27.   240027 BF000000 >---->-------movl>---$.LC0,%edi<

  28.   24      00<


  29.   25 002c B8000000 >---->-------movl>---$0,%eax<

  30.   25      00<

  31.   260031 E8000000 >---->-------call>---printf<

  32.   26      00<

  33.   270036 B8000000 >---->-------movl>---$0,%eax<

  34.   27      00<

  35.   28 003b C9       >---->-------leave<

  36.   29 003c C3       >---->-------ret<

Когда санитары отвезли тело Танкадо в морг, офицер попытался расспросить канадца о том, что произошло. Единственное, что он понял из его сбивчивого рассказа, - это что перед смертью Танкадо отдал кольцо.

- Танкадо отдал кольцо? - скептически отозвалась Сьюзан. - Да.