-2

I know postfix operator increment value after using the variable. But in this case, is it a valid statement? since it seems like i am modifying a variable after its return statement.

#include <iostream>

using namespace std;

int val = 0;

int foo()
{
        return val++;
}

int main()
{
        cout<<foo();
        cout<<endl<<val;
}

Any elaboration will be helpful.

mchouhan_google
  • 1,775
  • 1
  • 20
  • 28
  • 1
    `val` is a global variable. – Jacob Seleznev Mar 25 '15 at 01:29
  • 6
    Instead of thinking `val++` increments `val` *after* the return statement, think of it this way: `val++` saves off the original value of `val` to some unseen temp, then increments the value in `val`, then uses the unseen temp as the `return` value. – WhozCraig Mar 25 '15 at 01:45

4 Answers4

6

Saying that return val++ first returns val and then increments it is not quite true. The expression val++ increments the value of val, but evaluates to the old value of val.

You can think of the postfix ++ as a function that uses a helper variable to hold the old value:

int temp = val; // save old value to temp
++val;          // increment actual value
return temp;    // evaluate to old value
Emil Laine
  • 41,598
  • 9
  • 101
  • 157
2

Yes it's valid.

Don't think of it as returning val and then incrementing it afterwards.

Instead, you're returning the result of the operation val++.

Jonathan Potter
  • 36,172
  • 4
  • 64
  • 79
2

Okay, val is a global variable, as you might notice.

When you call foo(),

int foo()
{
    return val++;
}

It will return val first, which is 0, and then increment the value of val, hence val = 1.

As quoted by Zenith,

The expression val++ increments the value of val, but evaluates to the value of val before incrementing.

Now, when you cout val, val is obviously 1, hence the output is justified.

shauryachats
  • 9,975
  • 4
  • 35
  • 48
1

In order to see the exact steps the compiler has taken to represent your code, I examined the dissassembly.

Line 00324C2E copies the value of your global variable "val" into the CPU's eax register.

Line 00324C33 copies the value from eax into the "foo" function's local stack space.

Line 00324C39 copies the value of your global variable "val" into the CPU's ecx register.

Line 00324C3F adds one to the value in the ecx register.

Line 00324C42 copies the incremented value from the ecx register back to your global variable "var".

Line 00324C48 copies the unaffected copy of the value, which was stored in the "foo" function's local stack space (see line 00324C33 above), into the CPU's eax register. It's copied to the eax register because it is the value that is returned to the calling function ("main" in this case).

Therefore, 0 is returned from foo(), but the global variable "val" contains 1 after foo() has returned.


int foo()
{
  00324C10  push        ebp  
  00324C11  mov         ebp,esp  
  00324C13  sub         esp,0C4h  
  00324C19  push        ebx  
  00324C1A  push        esi  
  00324C1B  push        edi  
  00324C1C  lea         edi,[ebp-0C4h]  
  00324C22  mov         ecx,31h  
  00324C27  mov         eax,0CCCCCCCCh  
  00324C2C  rep stos    dword ptr es:[edi]  
      return val++;
  00324C2E  mov         eax,dword ptr ds:[0032F320h]  
  00324C33  mov         dword ptr [ebp-0C4h],eax  
  00324C39  mov         ecx,dword ptr ds:[32F320h]  
  00324C3F  add         ecx,1  
  00324C42  mov         dword ptr ds:[32F320h],ecx  
  00324C48  mov         eax,dword ptr [ebp-0C4h]  
}
Richard Gieg
  • 1,276
  • 8
  • 17
  • Just realized my answer isn't a very good explanation on its own, but is better as a supplement to the brilliant explanation in Zenith's answer (which doesn't need a supplement IMO). I just enjoy disassembling things. :) – Richard Gieg Mar 25 '15 at 02:52