30

If I have for example a class with instance method and variables

class Foo
{

   ...

   int x;
   int bar() { return x++; }
 };

Is the behavior of returning a post-incremented variable defined?

Lazer
  • 90,700
  • 113
  • 281
  • 364
patros
  • 7,719
  • 3
  • 28
  • 37

7 Answers7

58

Yes, it's equivalent to:

int bar()
{
  int temp = x;
  ++x;
  return temp;
}
Peter Alexander
  • 53,344
  • 14
  • 119
  • 168
  • If `int` is not an `int`, but a `MyClassWithOverloadedOperators`, then you're just wrong. – P Shved Mar 04 '10 at 18:39
  • 7
    @Pavel: I disagree. A class with an overloaded post-increment operator that doesn't implement the proper post-increment semantics is wrong. – Void - Othman Mar 04 '10 at 18:56
  • @Void, if you overload a post-increment, it doesn't magically become a *pre*-increment, does it? – P Shved Mar 04 '10 at 21:35
  • @Pavel: Ok, yes, you are technically correct -- a class may not have a pre-increment, or the pre-increment may have a different effect than the post-increment (other than its pre-ness), but that's such an obscure scenario that I didn't think it was worth mentioning, and I certainly don't think it was deserving of a down-vote (assuming that was you). – Peter Alexander Mar 04 '10 at 22:22
  • @Poita, I think that 1 mistake in an answer of a length of 100 bytes deserves a downvote. For this question such matter is certainly not worth *mentioning*, but it is worth changing `++x` to `x++`; just to be correct. – P Shved Mar 04 '10 at 22:29
  • @Pavel: Of course not. The point is that a properly implemented post-increment operator will retain the semantics that @Poita_ illustrated in his code sample. – Void - Othman Mar 04 '10 at 22:56
  • 7
    @Pavel: I changed it from an `x++` to a `++x` otherwise I would be defining `x++` in terms of `x++`, and I tend to try to avoid circular definitions. Also, I don't believe it is a mistake, in the same way that I didn't make the clarification that my code only applies if there isn't a #define for temp or bar... Furthermore, my example only describes the operation for an `int` where it is 100% correct. – Peter Alexander Mar 04 '10 at 23:04
12

Yes it is ... it will return the x's value before incrementing it and after that the value of x will be + 1 ... if it matters.

anthares
  • 11,070
  • 4
  • 41
  • 61
6

It is defined.

It returns the value of x before incrementation. If x is a local(non-static) variable this post incrementation has no effect since local variables of a function cease to exist once the function returns. But if x is a local static variable, global variable or an instance variable( as in your case), its value will be incremented after return.

codaddict
  • 445,704
  • 82
  • 492
  • 529
  • But what happens in case of an overloaded `++`-operator on a custom class? Will it's effect be performed? – Dario Mar 04 '10 at 16:22
  • 2
    @Dario Yes, it will be. The expression following "return" will be fully evaluated before the return is executed. –  Mar 04 '10 at 16:24
  • 1
    @Dario. Yes, for exactly the same reason that if you do `return x.dosomething();`, the effect of `dosomething` will be performed before the return. Overloaded post-increment isn't magic, it's just a function that returns a value, that happens to be the old value. – Steve Jessop Mar 04 '10 at 16:47
  • 1
    @Steve "Overloaded post-increment isn't magic, it's just a function that returns a value, that happens to be the old value" - if the programmer decided to implement it as such :-) –  Mar 04 '10 at 16:55
  • Yes, fair point. "Happens to be the old value, if the programmer has the good sense he was born with". – Steve Jessop Mar 04 '10 at 17:29
6

Yes.

In postincrement (x++) the value of x is evaluated (returned in your case) before 1 is added.

In preincrement (++x) the value of x is evaluated after 1 is added.

Edit: You can compare the definition of pre and post increment in the links.

Mizipzor
  • 51,151
  • 22
  • 97
  • 138
2

Most programming languages, like C++, are recursive in the order that operations are carried out (I'm not making any implication about how the code is actually implemented by the compiler here). Compound operations that are composed of any well defined operations are themselves well defined, since each operation is carried out on a last-in, first-out basis.

Post-increment returns the value of the variable being incremented before incrementing it, so the return operation recieves that value. No special definition of this behavior has to be made.

Andrew Noyes
  • 5,248
  • 1
  • 18
  • 14
  • 1
    I don't think the concern was about what value would be returned, but rather about whether the increment would occur. It's an understandable concern if your mental model has it that "return" causes an immediate end to the function — is there really time for the increment to be applied if the function is already over? Of course we know the answer is *yes*, but only because the compiler performs a transformation like in Poita's answer to ensure that the function doesn't actually return until all the side effects have been applied. – Rob Kennedy Mar 04 '10 at 23:32
  • That's what I mean. The `return` statement is encountered after `x++` "returns". Since `x++` is an operation, it should be thought of as returning as in the demonstration code that Poita_ provided. That way, it's easy to see that since `x++` is executed and its return value is passed to the `return` statement. It doesn't make sense that `x++` would return and *then* increment. – Andrew Noyes Mar 09 '10 at 16:12
2

I know this question is answered long before but here's why it is defined. Compound operators are basically syntax sugar for functions. If you're wondering how the increment happens after returning from the function, it doesn't. It happens just before the operator "function" returns the previous value.

For an integer, think of the post increment operator function defined like this:

int post_increment(int *n)
{
    int temp = *n;
    *n = *n + 1;
    return temp;
}
Amal K
  • 4,359
  • 2
  • 22
  • 44
0

I think it is defined but not preferred. It causes confusion to people. For example, the following code prints 1 instead of 2.

#include <iostream>
#include <cstdlib>

using namespace std;

int foo()
{
    int i = 1;
    return i++;
}

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

    return 0;
}
Huiguorou
  • 317
  • 2
  • 4
  • 1
    Try and get out of the habit of `using namespace std`. That prefix is there for a reason: To protect you from naming collisions and to make it clear where those functions, data structures and other things come from. – tadman Jul 20 '18 at 18:24