17 + + and -- operator analysis

Keywords: C REST

++And -- the essence of operators

  • ++And -- operators correspond to two assembly instructions

    • Preposition

      • Variable increment (decrement) 1
      • Take variable values
    • Postposition

      • Take variable values
      • Variable increment (decrement) 1

++And -- operator usage analysis

  • A troubling pair of brothers

int i = 0;

(i++) + (i++) + (i++);
(++i) + (++i) + (++i);

What are the values of the two expressions?

Case study: a headache brother

#include <stdio.h>

int main()
{
    int i = 0;
    int r = 0;
    
    r = (i++) + (i++) + (i++);
    
    printf("i = %d\n", i);
    printf("r = %d\n", r);
    
    r = (++i) + (++i) + (++i);
    
    printf("i = %d\n", i);
    printf("r = %d\n", r);
    
    return 0;
}
output_1: VC
i = 3
r = 0
i = 6
r = 18

//Output 2: GCC
i = 3
r = 0
i = 6
r = 16

//Analysis 1: [compilation - VC]

r = (i++) + (i++) + (i++);

    mov         eax,dword ptr [i]  
    add         eax,dword ptr [i]  
    add         eax,dword ptr [i]  
    mov         dword ptr [r],eax  ; r = i + i + i ==> r = 0 + 0 + 0 = 0
    
    mov         ecx,dword ptr [i]  
    add         ecx,1  
    mov         dword ptr [i],ecx  ; i = i + 1 = 1
    
    mov         edx,dword ptr [i]  
    add         edx,1  
    mov         dword ptr [i],edx  ; i = i + 1 = 2
     
    mov         eax,dword ptr [i]  
    add         eax,1  
    mov         dword ptr [i],eax  ; i = i + 1 = 3

r = (++i) + (++i) + (++i);

    mov         eax,dword ptr [i]  
    add         eax,1  
    mov         dword ptr [i],eax  ; i = i + 1 = 4
    
    mov         ecx,dword ptr [i]  
    add         ecx,1  
    mov         dword ptr [i],ecx  ; i = i + 1 = 5
    
    mov         edx,dword ptr [i]  
    add         edx,1  
    mov         dword ptr [i],edx  ; i = i + 1 = 6
    
    mov         eax,dword ptr [i]  
    add         eax,dword ptr [i]  
    add         eax,dword ptr [i]  
    mov         dword ptr [r],eax  ; r = i + i + i = 6 + 6 + 6 = 18
Analysis 2: [compilation GCC]

r = (i++) + (i++) + (i++);

int i = 0;
movl $0x0,0x1c(%esp)
int r = 0;
movl $0x0,0x18(%esp)

mov 0x1c(%esp),%eax
add %eax,%eax
add 0x1c(%esp),%eax
mov %eax,0x18(%esp)    ; r = i + i + i ==> r = 0 + 0 + 0 = 0

addl $0x1,0x1c(%esp)   ; i = i + 1 = 1
addl $0x1,0x1c(%esp)   ; i = i + 1 = 2
addl $0x1,0x1c(%esp)   ; i = i + 1 = 3

r = (++i) + (++i) + (++i);

    addl $0x1,0x1c(%esp)   ; i = i + 1 = 4
    addl $0x1,0x1c(%esp)   ; i = i + 1 = 5
    
    mov 0x1c(%esp),%eax    
    add %eax,%eax          ; eax = i + i = 10
    
    addl $0x1,0x1c(%esp)   ; i = i + 1 = 6 
    
    add 0x1c(%esp),%eax
    mov %eax,0x18(%esp)    ; r = i + eax = 16

  • C only specifies the corresponding execution order of + + and -- corresponding instructions
  • ++And -- corresponding assembly instructions may not be executed continuously
  • In hybrid operations, assembly instructions for + + and -- may be interrupted [different compilers have different behaviors]

[C language gray area] + and -- participate in mixed operation results are uncertain

**"++ -- Do not mix with other operators"**

"Wonderful flowers" in interview

How does the compiler explain it?

  • ++i+++i+++i
  • a+++b

    • a++ +b
    • a + ++b

Greedy method: reading skill of + + - expression

  • The compiler handles that each symbol should contain as many characters as possible
  • The compiler reads as many characters as possible from left to right
  • When the read in character is impossible to form a legal symbol with the read in character

Case study: greedy reading

#include <stdio.h>

int main()
{
    int i = 0;
    // int j = ++i+++i+++i; 
    
    int a = 1;
    int b = 4;
    int c = a+++b;
    
    int *p = &a;
    
    // b = b/*p;
    
    printf("a = %d\n", a);
    printf("b = %d\n", b);
    printf("c = %d\n", c);
    
    return 0;
}
Output:
a = 2
b = 4
c = 5

//Analysis:
int j = ++i+++i+++i; ==> error: lvalue required as increment operand
                     ==> ++i++ ==> 1 ++ 
c = a+++b;           ==> a++ + b
b = b/*p;            ==> Commentary begins
  • Space can be used as a rest of a complete symbol in C language. The compiler processes the previously read symbol immediately after reading the space
  • Reasonable use of space, while increasing readability, clearly tells the compiler our purpose

Summary

  • ++And -- operators may behave differently in mixed operations
  • The compiler uses greedy method to deal with subexpressions in expressions
  • Space can be used as a rest of a complete symbol in C language
  • The compiler processes the previously read symbols as soon as it reads the spaces

The above contents refer to the series courses of Ditai Software Institute, please protect the original!

Posted by Eskimo on Mon, 02 Dec 2019 22:31:37 -0800