0
votes

Where can I find the C/C++ implementation of the ++ operator for numbers and pointers?

I looked around the web but didn't find much...

4
Question is hard to understand. Do you mean where do you find the implementation of a ++ operator in C++?DWright
@Erwald: oh, in that case, the builtin is translated to machine code (or byte code) by the compiler. usually it's a single machine code instruction.Cheers and hth. - Alf
@Erwald: C and C++ compilers aren't interpreters, they're compilers. They generate binary output (zero and ones). The interpretation of that code is left to the circuitry in your machine (or "microcode" in your CPU, etc., interpreted by the hardware)... no actual "code" typically exists which executes the increment for integers/pointers, unless we're talking about long long's on some 32-bit systems or such. :)user541686
@Mehrdad, This is vital information. How else would you make a conforming C++ implementation on your 16-bit Hack computer?chris
@GrijeshChauhan Thanks! This is much appreciated!Erwald

4 Answers

4
votes

May be my answer (for number) helpful upto some extend:
you can drive answer for pointer

How i++ works in low level.

int main(){
    int i=0,j=0;
    j=i++;  // expresion includes two operations `+, =      
    printf("%d %d",j,i);
}

You can disassemble it using -S flag with gcc (g++):
My code name is m.c

$ gcc -S m.c

It will create a m.s assembly file.

Read comments I added:

pushl   %ebp
movl    %esp, %ebp
andl    $-16, %esp
subl    $32, %esp

movl    $1, 28(%esp)            // i due to declarations 
movl    $0, 24(%esp)            // j

movl    28(%esp), %eax          // this two lines are j = i
movl    %eax, 24(%esp)

addl    $1, 28(%esp)            // increment to i, i++

movl    $.LC0, %eax
movl    28(%esp), %edx
movl    %edx, 8(%esp)
movl    24(%esp), %edx
movl    %edx, 4(%esp)
movl    %eax, (%esp)
call    printf

This how assignment = happen first then ++. If ++ is postfix.

How compiler works:

(according to my compiler)

Bottom-up evaluation of the abstract syntax tree for expression j = i ++.

source code:

j = i++;  

At Low level broken into two instructions (as you can see in assembly code):
j = i i++

Where i++ is i = i + 1

// abstract syntax tree

       + (post)
      / \
     /   \  
    =     1 
   / \       
  /   \
 j     i  

CASE OF PREFIX ++ (++i):

Also suppose if expression would be j = ++i then I directly writing abstract syntax tree:

It will first increments ++ then = performs;

// abstract syntax tree for j = ++i  

    =
   / \       
  /   \
 j     \ 
       + (prefix)
      / \
     /   \  
    i     1 

Assembly code for j = ++i where j=0 and i=1 initially:

movl    $1, 28(%esp)          // i declaration 
movl    $0, 24(%esp)          // j  
addl    $1, 28(%esp)          // First  Add 1 to i because i++ (before = perform)
movl    28(%esp), %eax        // Below two steps: = performed  j = i 
movl    %eax, 24(%esp)
6
votes

The implementation is in the source code for your compiler.

In general, your compiler will do the following:

  • Deduce the type of i.
  • If i is a plain integer type or a reference to integer, the compiler will produce an intermediate representation that indicates a load from memory (if necessary) and a simple +1 increment.
  • If i is a pointer, the compiler will produce an intermediate representation that indicates a load from memory (if necessary) followed by an add instruction that adds sizeof(*i) instead of +1.
  • If i is a type for which an overloaded operator++() is in scope, it produces an intermediate representation that indicates a function call to the overloaded operator definition.

There is no magic here. i++ maps generally to a simple add or inc instruction for integral types, and potentially maps to a function call in C++.

3
votes

I think you want to see the machine code that is generated for this operation. Here :

//sg
int main()
{
    int i=0;
    ++i;
    return 0;
}

Compile with : gcc -S -fverbose-asm -masm=intel test.c

And here is the assembly (relevant portion) :

mov DWORD PTR [ebp-4], 0    # i,
add DWORD PTR [ebp-4], 1    # i,

Compare this with

//sg
int main()
{
    int i=0,j;
    j=i+1;
    return 0;
}

Which will generate a longer asm :

mov DWORD PTR [ebp-4], 0    # i,
mov eax, DWORD PTR [ebp-4]  # tmp62, i
add eax, 1  # tmp61,
mov DWORD PTR [ebp-8], eax  # j, tmp61

Also note that modern compilers will automatically change i=i+1 to a shorter i++.

1
votes

well this is pretty basic question, which you would best learn about from a textbook

but anyway

for numbers

the built-in ++ increases the number value by 1, changing the memory contents. You can use this operator on both integers and floating point objects. And you can use it both as a prefix operator, writing ++x, and as a postfix operator, writing x++.

The difference is what expression value the prefix and postfix variants produce. The prefix ++x increments x and produces the new value of x (in C++ as I recall it produces a reference to x, with the new value). The postfix x++ increments x and produces the original value of x.

for pointers

the difference between prefix and postfix is the same, but the definition of "increase by 1" is different

for a pointer of type T* pointing to the i'th item of an array of T, after incrementing that pointer it points to the i+1'th item of the array.

this means that the machine code level address is increased by sizeof(T).

the expression p+n where n is an integer yields the same final value as n increments, if the final value is well-defined. this can also be written as n+p.