Fundamentals 6 min read

Why Does ++i + i++ Print 3? Exploring C Evaluation Order with Assembly

This article dissects the C expression ++i + i++, shows how compiler‑generated assembly executes both increments exactly once, and demonstrates why the result is 3 while highlighting the pitfalls of undefined evaluation order in C.

Liangxu Linux
Liangxu Linux
Liangxu Linux
Why Does ++i + i++ Print 3? Exploring C Evaluation Order with Assembly

Expression ++i + i++ in C

The increment operators have higher precedence than addition, and both have higher precedence than assignment, so ++i and i++ are evaluated before the + operator.

Compilation and generated assembly (gcc -O0 -S)

# assembly generated for ++i + i++
    .file   "1125.c"
    .text
    .globl  main
main:
    subq    $16, %rsp
    movl    $0, -8(%rbp)          # i = 0
    addl    $1, -8(%rbp)          # ++i, i becomes 1
    movl    -8(%rbp), %eax        # load i (1) into %eax
    leal    1(%rax), %edx        # i++ (post‑increment), %edx = 2
    movl    %edx, -8(%rbp)        # store incremented i (2)
    addl    %edx, %eax            # %eax + %edx = 1 + 2 = 3
    movl    %eax, -4(%rbp)        # store result
    ...

The assembly shows that the original value of i (1) is loaded into %eax, then i is incremented to 2, and finally the two values are added, producing the result 3.

Variant i++ + ++i

# assembly generated for i++ + ++i
    movl    $0, -8(%rbp)          # i = 0
    movl    -8(%rbp), %eax        # load i (0)
    leal    1(%rax), %edx        # ++i, %edx = 1
    movl    %edx, -8(%rbp)        # store incremented i (1)
    addl    $1, -8(%rbp)          # i++ (post‑increment), i becomes 2
    movl    -8(%rbp), %edx        # load new i (2)
    addl    %edx, %eax            # %eax + %edx = 0 + 1 = 1 (the addition uses the value before the post‑increment)
    ...

Here the post‑increment loads the original i (0) into %eax, the pre‑increment makes i become 1, and the addition yields 1 (0 + 1).

Manual assembly assembly and execution script

# 1125.sh – assemble, link and run the program
# gcc -O0 -S 1125.c   (produces 1125.s)
as -o 1125.o 1125.s
ld -m elf_x86_64 -dynamic-linker /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 \
   "1125.o" /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o \
   /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o /usr/lib/gcc/x86_64-linux-gnu/5/crtend.o \
   /usr/lib/x86_64-linux-gnu/crtn.o -lc -o "1125_64"
chmod 777 1125_64
./1125_64

Modifying the generated assembly to reset -8(%rbp) to zero before the increment sequence still produces the value 3, confirming that each increment is executed exactly once.

Key instruction sequence for ++i + i++

Initialize i at -8(%rbp) to 0. addl $1, -8(%rbp) // ++i, i becomes 1. movl -8(%rbp), %eax // load i (1) into %eax. leal 1(%rax), %edx // i++ (post‑increment), %edx = 2. movl %edx, -8(%rbp) // store incremented i (2). addl %edx, %eax // 1 + 2 = 3.

Key instruction sequence for i++ + ++i

Initialize i to 0. movl -8(%rbp), %eax // load original i (0). leal 1(%rax), %edx // ++i, %edx = 1. movl %edx, -8(%rbp) // store incremented i (1). addl $1, -8(%rbp) // i++ (post‑increment), i becomes 2. addl %edx, %eax // 0 + 1 = 1.

These experiments demonstrate that the order of evaluation of sub‑expressions in C is undefined. Relying on side‑effects such as multiple increments of the same variable within a single expression can lead to surprising results.

Reference: https://zh.cppreference.com/w/c/language/eval_order

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

compilerOperator PrecedenceEvaluation Order
Liangxu Linux
Written by

Liangxu Linux

Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.