Post-increment and Pre-increment concept?
Asked Answered
P

14

80

I don't understand the concept of postfix and prefix increment or decrement. Can anyone give a better explanation?

Phosgenite answered 15/12, 2010 at 0:36 Comment(3)
Possible duplicate of What is the difference between ++i and i++Shotten
or perhaps Incrementing in C++ - When to use x++ or ++x? (or, most likely, 10s of others)Engrain
If you understand Hindi :), this explains very clearly youtube.com/watch?v=yRt-zYFJIvEDisturb
W
133

All four answers so far are incorrect, in that they assert a specific order of events.

Believing that "urban legend" has led many a novice (and professional) astray, to wit, the endless stream of questions about Undefined Behavior in expressions.

So.

For the built-in C++ prefix operator,

++x

increments x and produces (as the expression's result) x as an lvalue, while

x++

increments x and produces (as the expression's result) the original value of x.

In particular, for x++ there is no no time ordering implied for the increment and production of original value of x. The compiler is free to emit machine code that produces the original value of x, e.g. it might be present in some register, and that delays the increment until the end of the expression (next sequence point).

Folks who incorrectly believe the increment must come first, and there are many, often conclude from that certain expressions must have well defined effect, when they actually have Undefined Behavior.

Whim answered 15/12, 2010 at 1:4 Comment(15)
@Sa'me Smd: "lvalue" is essentially a reference to an object that has storage. it's terminology stemming from early C, where an assignment needed an lvalue on the left side.Whim
Hm, I goofed in the final paragraph. I'll edit this later. It's complex, so so some standard-quoting and concrete examples also needed. Sorry...Whim
The first is a prefix increment, not postfix increment.Toffey
@wilhemtell: thanks. I must have been writing that with head switched off! Also final para is silly. Perhaps also next to final para. I'll fix that typo straight away, but need more coffee first for the rest! :-)Whim
You're right about the mechanics but I think you're wrong to say others and incorrect on the conceptual level. The mechanics are just practicalities of trying to implement the concept. 'Post' means after - conceptually, the increment is done afterwards. The whole concept of 'sequence' as in 'sequence point' implies an order, and the UB comes from misunderstanding how sequence points work, not from 'misunderstanding' the meaning of 'pre' and 'post'.Fleming
@sje397: in this context, pre and post refer to prefix and postfix operators, i.e. the order of symbols in the source code, not a time order of events. however, historically i believe that the C operators reflected similar machine code instructions.Whim
So what would an expression like (i++ > 0) && someProperty(myArray[i]) do? Like if i=5, would it be calling someProperty with myArray[5] or myArray[6]?Collayer
@AJMansfield: In C++03 terms the built-in && introduces a sequence point (C++03 §1.9/18). In C++11 terms the left hand operand expression of the built-in && is sequenced before the right hand operand expression (C++11 §5.14/2). This means that if the call is made, it's made with i value 6.Whim
@Cheers and hth. - Alf one other question, what about other operators? x++ + y(x)? or the equivalent with ++x instead? If I had access to a c++ environment right now I'd probably just try it and see, but unfortunately, I don't...Collayer
@AJMansfield: The && and || are unique in providing short-circuit evaluation (and hence sequence points). The ternary choice operator is a bit like that, in that it guarantees that the choice not taken is not evaluated. But for arithmetic operators you just get Undefined Behavior when you both modify and use a variable in the same expression. I think, but not sure, that this is so also for all other operators. It is anyway the best assumption, and it's not good to write code that relies on some subtle special case that few if any programmers know about. ;-)Whim
And that is the same reason why "++x" is allowed to be on the left hand side of the simple assignment operator "=" while the expression "x++", which doesn't produce a "lvalue", is not. Am I correct?Kao
Do expressions like i++ || foo(i) really produce undefined behaviour (of the nasal demon variety) as your second paragraph seems to imply, or merely unspecified behaviour? Spec quotes backing up your claim here would help.Matthia
@MarkAmery: In C++03 the normative text said undefined behavior, while the examples said unspecified behavior. So it's fair to say that the committe was a bit unclear on which it should be, and Andrew Koenig, then secretary, failed to catch that. But formally it's always been real undefined behavior, nasal demons & the full package.Whim
It's a C operator, not a C++ operator. C++ stole it from C.Marlea
@Marlea It's an operator, present in both C and C++, among other languagesCoelom
F
29
int i, x;

i = 2;
x = ++i;
// now i = 3, x = 3

i = 2;
x = i++; 
// now i = 3, x = 2

'Post' means after - that is, the increment is done after the variable is read. 'Pre' means before - so the variable value is incremented first, then used in the expression.

Fleming answered 15/12, 2010 at 0:39 Comment(5)
"the increment is done after the variable is read". I used to think I understand post- and prefix increment, but now you got me confused!Toffey
Why is that confusing? We're talking about the concept of 'pre' and 'post' increment. Those prefixes do mean before and after.Fleming
The "pre" and "post" in "preincrement" and "postincrement" refer to the position of the operator with respect to the operand. They do not imply any temporal ordering between when the increment occurs with respect to when the variable is read.Footcandle
@James: I understand your point - but to illustrate, imagine how confusing it would be if the function of the operators was reversed. I know that technically, there is no implication of temporal ordering, but there is definitely a conceptual mapping of the post increment to the idea of 'incrementing after use'.Fleming
@Fleming why for example int a = 5; cout << a++; prints only 5 instead of 6 according to your example?Desiredesirea
T
20

The difference between the postfix increment, x++, and the prefix increment, ++x, is precisely in how the two operators evaluate their operands. The postfix increment conceptually copies the operand in memory, increments the original operand and finally yields the value of the copy. I think this is best illustrated by implementing the operator in code:

int operator ++ (int& n)  // postfix increment
{
    int tmp = n;
    n = n + 1;
    return tmp;
}

The above code will not compile because you can't re-define operators for primitive types. The compiler also can't tell here we're defining a postfix operator rather than prefix, but let's pretend this is correct and valid C++. You can see that the postfix operator indeed acts on its operand, but it returns the old value prior to the increment, so the result of the expression x++ is the value prior to the increment. x, however, is incremented.

The prefix increment increments its operand as well, but it yields the value of the operand after the increment:

int& operator ++ (int& n)
{
    n = n + 1;
    return n;
}

This means that the expression ++x evaluates to the value of x after the increment.

It's easy to think that the expression ++x is therefore equivalent to the assignmnet (x=x+1). This is not precisely so, however, because an increment is an operation that can mean different things in different contexts. In the case of a simple primitive integer, indeed ++x is substitutable for (x=x+1). But in the case of a class-type, such as an iterator of a linked list, a prefix increment of the iterator most definitely does not mean "adding one to the object".

Toffey answered 15/12, 2010 at 1:33 Comment(1)
The prefix increment does not yield the value, but a reference to the operand (even in the shown code). See type of the return value 'int&'. 'n' is also of type 'int&'.Drumstick
A
17

No one has answered the question: Why is this concept confusing?

As an undergrad Computer Science major it took me awhile to understand this because of the way I read the code.

The following is not correct!


x = y++

X is equal to y post increment. Which would logically seem to mean X is equal to the value of Y after the increment operation is done. Post meaning after.

or

x = ++y
X is equal to y pre-increment. Which would logically seem to mean X is equal to the value of Y before the increment operation is done. Pre meaning before.


The way it works is actually the opposite. This concept is confusing because the language is misleading. In this case we cannot use the words to define the behavior.
x=++y is actually read as X is equal to the value of Y after the increment.
x=y++ is actually read as X is equal to the value of Y before the increment.

The words pre and post are backwards with respect to semantics of English. They only mean where the ++ is in relation Y. Nothing more.

Personally, if I had the choice I would switch the meanings of ++y and y++. This is just an example of a idiom that I had to learn.

If there is a method to this madness I'd like to know in simple terms.

Thanks for reading.

Agonic answered 18/12, 2013 at 0:32 Comment(5)
"If there is a method to this madness I'd like to know in simple terms." - I think of it as this: PRE increment (y=++x): increment x first THEN assign to y. And for POST increment (y=x++): Assign to y THEN increment x. So think of pre & post as "when does x get incremented" rather than "what version of x does y get". That's my "method to the madness" and it makes perfect sense, IMO ;-)Bellaude
"If there is a method to this madness I'd like to know in simple terms." well, of course there is. preincrement means 'the operator comes pre a.k.a. before the operand, so the increment comes before the operand is returned to the caller, so the value they get includes the increment.' postincrement means 'the operator comes post a.k.a. after the operand, so the increment comes after (a copy of) the operand is returned to the caller, so the value they get does not include the increment.'Engrain
++y is preincrement because the ++ is used as a prefix, y++ is postincrement because ++ is used as a postfix (or 'suffix'). Not contrary to the English language at all.Enchantress
"The words pre and post are backwards with respect to semantics of English." I don't agree with that. "Pre" and "post" are modifying "increment", and accurately describe when the increment conceptually occurs. "Pre-increment" conceptually increments before producing a value. "Post-increment" conceptually increments after producing a value. So with pre-increment, you get the incremented value. With post-increment, you get the original value.Saldana
Talking about language: In "Pre-Increment" pre can be a preposition and increment an (language) object, or pre can be a prefix specifying, which kind of increment one is talking about. The second reading would fit to the actual working of the operators. But I agree it can be confusing.Drumstick
A
8

It's pretty simple. Both will increment the value of a variable. The following two lines are equal:

x++;
++x;

The difference is if you are using the value of a variable being incremented:

x = y++;
x = ++y;

Here, both lines increment the value of y by one. However, the first one assigns the value of y before the increment to x, and the second one assigns the value of y after the increment to x.

So there's only a difference when the increment is also being used as an expression. The post-increment increments after returning the value. The pre-increment increments before.

Aboral answered 15/12, 2010 at 0:41 Comment(8)
The two lines are not equal at all. -1Toffey
wilhemtell: Thanks for adding absolutely nothing to the discussion. Good job.Aboral
@JonathanWood what's the type of x? There you have it. The two lines are not equal. Do I add anything to the discussion now?Toffey
@JamesMcNellis no, the first two statements have the same effect unless x is of a class-type period.Toffey
@wilhelmtell: Ok, right. Even with consistent operator overloads, you still end up copying the object when you postincrement.Footcandle
@JamesMcNellis you will end up calling two different functions, to begin with.Toffey
@wilhelmtell: If the overloads are consistent (which they should be), then the effect of the statements x++; and ++x; is the same. Yes, you call different functions, but they should do the same thing. That's what I was trying to get at.Footcandle
@JonathanWood Thanks for the lucid answer. The distinction between usage of increment in an expression and as a standalone operation is the reason most people get confused. Your answer clearly explains thisArginine
C
5
int i = 1;
int j = 1;

int k = i++; // post increment
int l = ++j; // pre increment

std::cout << k; // prints 1
std::cout << l; // prints 2

Post increment implies the value i is incremented after it has been assigned to k. However, pre increment implies the value j is incremented before it is assigned to l.

The same applies for decrement.

Chicle answered 15/12, 2010 at 0:43 Comment(1)
Thumbs up for explaining with an exampleArginine
P
2

Post-increment:

int x, y, z;

x = 1;
y = x++; //this means: y is assigned the x value first, then increase the value of x by 1. Thus y is 1;
z = x; //the value of x in this line and the rest is 2 because it was increased by 1 in the above line. Thus z is 2.

Pre-increment:

int x, y, z;

x = 1;
y = ++x; //this means: increase the value of x by 1 first, then assign the value of x to y. The value of x in this line and the rest is 2. Thus y is 2.
z = x; //the value of x in this line is 2 as stated above. Thus z is 2.
Peninsula answered 21/4, 2020 at 2:23 Comment(0)
E
2

Already good answers here, but as usual there seems to be some general lack of clarity in simply remembering which way round these work. I suppose this arises because semantically resolving the nomenclature is not entirely straightforward. For example, you may be aware that "pre-" means "before". But does the pre-increment ++i return the value of i before the increment, or does it increment i before returning a value?

I find it much easier to visually follow the expression through from left to right:

        ++                    i 
-------------------------------------------------->
    Increment i   Then supply the value of i


             i                      ++
-------------------------------------------------->
    Supply the value of i    Then increment i

Of course, as Alf points out in the accepted answer, this may not reflect when the 'real i' is updated, but it is a convenient way of thinking about what gets supplied to the expression.

Euphonious answered 12/12, 2022 at 1:28 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Sashenka
O
1

Since we now have inline javascript snippets I might as well add an interactive example of pre and pos increment. It's not C++ but the concept stays the same.

let A = 1;
let B = 1;

console.log('A++ === 2', A++ === 2);
console.log('++B === 2', ++B === 2);
Oleson answered 13/2, 2019 at 23:23 Comment(0)
A
0

From the C99 standard (C++ should be the same, barring strange overloading)

6.5.2.4 Postfix increment and decrement operators

Constraints

1 The operand of the postfix increment or decrement operator shall have qualified or unqualified real or pointer type and shall be a modifiable lvalue.

Semantics

2 The result of the postfix ++ operator is the value of the operand. After the result is obtained, the value of the operand is incremented. (That is, the value 1 of the appropriate type is added to it.) See the discussions of additive operators and compound assignment for information on constraints, types, and conversions and the effects of operations on pointers. The side effect of updating the stored value of the operand shall occur between the previous and the next sequence point.

3 The postfix -- operator is analogous to the postfix ++ operator, except that the value of the operand is decremented (that is, the value 1 of the appropriate type is subtracted from it).

6.5.3.1 Prefix increment and decrement operators

Constraints

1 The operand of the prefix increment or decrement operator shall have qualified or unqualified real or pointer type and shall be a modifiable lvalue.

Semantics

2 The value of the operand of the prefix ++ operator is incremented. The result is the new value of the operand after incrementation. The expression ++E is equivalent to (E+=1). See the discussions of additive operators and compound assignment for information on constraints, types, side effects, and conversions and the effects of operations on pointers.

3 The prefix -- operator is analogous to the prefix ++ operator, except that the value of the operand is decremented.

Andria answered 15/12, 2010 at 1:25 Comment(3)
Posting a large block of text from the ISO Standard without any comment or explanation is not really helpful, especially when the text is not entirely self-contained (from this text, what is a sequence point? what is an lvalue? how can this lvalue be qualified or unqualified? where are "the discussions of additive operators and compound assignment"?). Also, assuming that C++ is the same is generally A Bad Idea. There are many small but important differences between the two languages, even in supposedly simple things like operator behavior.Footcandle
I am sorry but posting a part of the standard from a different language isn't particular helpful. Most of the time the increment operators in c++ are used on class types, which makes this more confusing than helpful.Benumb
The OP does not mention c++. I found this answer while studying c. Upvoted (because this is the correct answer for me).Annapolis
S
0

Post increment(a++)

If int b = a++,then this means

int b = a;

a = a+1;

Here we add 1 to the value. The value is returned before the increment is made,

For eg a = 1; b = a++;

Then b=1 and a=2

Pre-increment (++a)

If int b = ++a; then this means

a=a+1;

int b=a ;

Pre-increment: This will add 1 to the main value. The value will be returned after the increment is made, For a = 1; b = ++a; Then b=2 and a=2.

Siren answered 27/4, 2019 at 13:35 Comment(0)
R
-1
#include<stdio.h>
void main(){
char arr[] ="abcd";
char *p=arr,*q=arr;
char k,temp;
temp = *p++; /* here first it assigns value present in address which
is hold by p and then p points to next address.*/
k = ++*q;/*here increments the value present in address which is 
hold by q and assigns to k and also stores the incremented value in the same 
address location. that why *q will get 'h'.*/
printf("k is %c\n",k); //output: k is h
printf("temp is %c\n",temp);//output: temp is g
printf("*p is %c\n",*p);//output: *p is e
printf("*q is %c",*q);//output: *q is h
}

Post and Pre Increment with Pointers

Rosalbarosalee answered 24/7, 2021 at 5:7 Comment(0)
D
-4

The pre increment is before increment value ++ e.g.:

(++v) or 1 + v

The post increment is after increment the value ++ e.g.:

(rmv++) or rmv + 1

Program:

int rmv = 10, vivek = 10;
cout << "rmv++ = " << rmv++ << endl; // the value is 10
cout << "++vivek = " << ++vivek; // the value is 11
Donndonna answered 14/10, 2014 at 10:12 Comment(1)
first increment the value is pre increment and next step increment the value is post incrementDonndonna
E
-6

You should also be aware that the behaviour of postincrement/decrement operators is different in C/C++ and Java.

Given

  int a=1;

in C/C++ the expression

 a++ + a++ + a++

evaluates to 3, while in Java it evaluates to 6. Guess why...

This example is even more confusing:

cout << a++ + a++ + a++ << "<->" << a++ + a++ ;

prints 9<->2 !! This is because the above expression is equivalent to:

operator<<( 
  operator<<( 
    operator<<( cout, a++ + a++ ), 
    "<->"
  ), 
  a++ + a++ + a++ 
)
Earthbound answered 29/5, 2013 at 10:11 Comment(4)
This is due probably to what the C99 standard says: "The side effect of updating the stored value of the operand shall occur between the previous and the next sequence point."Bartender
I tried this with C and C++ compilers. It also evaluates to 6. With what compiler did you get 3?Tarratarradiddle
This is undefined behavior when using the pre/post increment operators twice in one expression.Larger
The statement "in C/C++ the expression a++ + a++ + a++ evaluates to 3" is simply wrong. As @Larger noted, it results in undefined behavior.Cannot

© 2022 - 2024 — McMap. All rights reserved.