Post-increment and Pre-increment concept? - c++

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

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 they are many, often conclude from that certain expressions must have well defined effect, when they actually have Undefined Behavior.

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.

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".

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.

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.

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.

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.

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);

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.

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.

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.

#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

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

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++
)

Related

What is the result of a dereferenced post incremented pointer being assigned to another dereferenced post incremented pointer in c++?

I encountered code similiar to the following in a c++, and I am unsure exactly what it does.
*x++ = *y++;
x and y are references to uint32s.
I understand that ++ is the post-increment operator, and * dereferences, but am still unsure of exactly what this does.
C++ Standard - 7.6.1.6 Increment and decrement expr.post.incr
Your expression *x++ = *y++; applies the postfix operator ++ to each of the pointers x and y after the assignment from *x = *y; occurs. Essentially the value of each operand is its value before any increment is applied. The increment is applied after the value computation.
The standard language is:
1 The value of a postfix ++ expression is the value of its operand.
[Note 1: The value obtained is a copy of the original value. — end
note]
The operand shall be a modifiable lvalue. ... The value of the operand
object is modified
(defns.access) by adding 1 to
it. The value computation of the ++ expression is sequenced before the
modification of the operand object. ...
2 The operand of postfix -- is decremented analogously to the
postfix ++ operator.
7.6.1.6 Increment and decrement - expr.post.incr
The equivalent section in the C-Standard is 6.5.2.4 Postfix increment and decrement operators
Let me know if you have any further questions.

Operator precedence of postfix increment

I made a silly mistake of doing *p++; thinking that p would be dereferenced first and then the value pointed by p would get incremented. So I found that this is more akin to:
*(p++);
Because the postfix ++ increment operator has higher precedence than the * dereference operator.
But now that I'm thinking in terms of operator precedence, I find that postfix++ is higher than for example the equality == operator, but in:
int a = 0;
if (0 == a++) // Condition is true
And the same goes for ! logical NOT:
int a = 0;
if (!a++) // Condition is true, a is incremented after the condition check
// even if it's higher precedence than !
So there must be more to it from what I've seen.
I've heard about the right-to-left and clockwise/spiral rule, but every time I've tried to grasp it it escaped my understanding.
I don't want a full explanation on the evaluation order, as I can struggle through that with my own reading. But am I at least right that it's not just a matter of operator precedence? For example the answer that *p++ is evaluated the way it is because the postfix++ operator is of higher precedence is only half right or part of the answer?
Link to answer
Your claim, Condition is true, a is incremented after the condition check even if it's higher precedence than !, is wrong.
It is not necessary that a will be incremented after the condition check. It can happen anytime. The only certainty is that in expression !a++, old value of a will be used for ! operator.
Operator precedence will help in grouping operands. Operand in !a++ will be grouped as ! (a++). This grouping doesn't mean that a will be incremented before ! operator is applied to the result fo a++.
p++ means increment p and return it's original value, it has to be evaluated before any other operator that uses its value. If you think of increment as a function it might be easier to understand:
int inc(int& v)
{
int value = v;
v++;
return value;
}
int a = 0;
if (inc(a) == 0)

Behaviour of arr[i] = i++ and i = i + 1 statements in C and C++

In the C and C++ languages, the arr[i] = i++; statement invokes undefined behavior. Why does the statement i = i + 1; not invoke undefined behavior?
Since this was originally tagged with c and c++ and not any specific version(s), the below answer is a generic answer to the problem. However, please note for c++, C++17 onwards, the behaviour has changed. Please see this answer by Barry to know more.
For the statement
arr[i] = i++;
the value of i is used in both the operands, RHS(right-hand-side) and LHS(left-hand-side), and in one of the cases, the value is being modified (as a side effect of post ++) where there's no sequence point in between to determine which value of i should be considered. You can also check this canonical answer for more on this.
On the other hand, for i = i + 1, the value of i is used only in RHS, the computed result is stored in LHS, in other words, there's no ambiguity. We can write the same statement as i++, which
reads the value of i
Increments it by 1
stores it back to i
in a well-defined sequence. Hence, no issues.
Note that this will change in C++17. In C++17, arr[i] = i++ does not invoke undefined behavior. This is due to the following change in [expr.ass]:
In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression. The right operand is sequenced before the left operand.
That is, we do i++ then we do arr[i] then we perform the assignment. The now well-defined ordering is:
auto src = i++;
auto& dst = arr[i];
dst = src;
For C99, we have:
6.5 Expressions
Between the previous and next sequence point an object shall have its stored value
modified at most once by the evaluation of an expression. Furthermore, the prior value
shall be read only to determine the value to be stored.
In arr[i] = i++, the value of i is only modified once. But arr[i] also reads from i, and this value is not used to determine the new value of i. That's why it has undefined behavior.
On the other hand, in i = i + 1 we read i in order to compute i + 1, which is used as the new value of i. Therefore this expression is fine.
arr[i] = i++;
implies that
right hand expression is evaluated before assignment
subscript operator is evaluated before assignment
but contains ambiguity regarding the order of right hand expression evaluation and subscript operator evaluation, compiler is free to treat it as
auto & val{arr[i]};
i++;
auto const rval{i};
val = rval;
or as
i++;
auto & val{arr[i]};
auto const rval{i};
val = rval;
or as (same result as above)
i++;
auto const rval{i};
auto & val{arr[i]};
val = rval;
Which may produce unpredictable result, while
i = i + 1;
dos not have any ambiguity, right hand expression is evaluated before assignment:
auto const rval{i + 1};
auto & val{i};
val = rval;
or (same result as above)
auto & val{i};
auto const rval{i + 1};
val = rval;
In your example a [i] = i++, if i = 3 for example, do you think a [i] is evaluated first, or i++? In one case, the value 3 would be stored in a [3], in the other case, it would be stored in a [4]. It's obvious that we have a problem here. No sane person would dare writing that code unless they found a guarantee what exactly will happen here. (Java gives that guarantee).
What would you think could be a problem with i = i + 1? The language must read i first to calculate i+1, then store that result. There is nothing here that could be wrong. Same with a [i] = i+1. Evaluating i+1, unlike i++, doesn't change i. So if i = 3, the number 4 must be stored in a [3].
Various languages have various rules to fix the problem with a [i] = i++. Java defines what happens: Expressions are evaluated left to right including their side effects. C defines it as undefined behaviour. C++ doesn't make it undefined behaviour but just unspecified. It says that either a[i] or i++ is evaluated first, and the other one next, but it doesn't say which one. So unlike C where anything can happen, C++ defines that only one of two things can happen. Obviously that's one thing too many to be acceptable in your code.

why does if(++x=++y) works and if(x++=++y) does not work?

when i am executing this program:
#include<iostream>
using namespace std;
int main(){
int x=5,y=9;
if(++x=y++){
cout<<"Works "<<x;
}
else{
cout<<"No";
}
return 0;
}
it works fine and the output is: Works 9
but if i execute:
#include<iostream>
using namespace std;
int main(){
int x=5,y=9;
if(x++=y++){
cout<<"Works "<<x;
}
else{
cout<<"No";
}
return 0;
}
it states:
In function 'int main()':
6:11: error: lvalue required as left operand of assignment
if(x++=y++){
Because x++ isn't an lvalue.
More specifically, x++ increments x, then returns a temporary with the original value of x. A temporary object can't (casts of dubious legality aside) be used on the left hand side of an assignment, so it is not an lvalue.
++x increments x and returns a reference to x (with its new value). You can then assign directly to it if you choose, so it is an lvalue.
However, it is possible you actually meant to compare the two expressions for equality, rather than do an assignment. In which case, you need to use == rather than =.
You have to remember that the suffix increment operator returns the old value, before the increment.
This value is a very temporary value, and as all other temporary values it is not an "lvalue", i.e. it is not something that can be assigned to.
The prefix increment operator does its increment operation, and then return a reference to the new value. For ++x it returns a reference to x. It is an "lvalue".
The same of course goes for the decrement (--) operator.
There are many sources all over the Internet that will help you understand the difference between "lvalues" and "rvalues" (temporaries).
x++ returns x, and then increments x. On the other hand, ++x increments x, and then returns it.
The second case makes sense; x is being returned, and you can do whatever. The first case makes no sense at all; x++ isn't a value. In fact, once you get back the value, x is no longer that value.
As everybody else has explained, the value of x++ is a temporary containing the old value of x, and temporaries cannot be assigned to. The compiler therefor rejects the code as not conforming to the grammar of C++.
The problem you have is that the first example is also wrong. Although ++x is grammatically an lvalue, if you put it on the left hand side of an assignment operator, you are both incrementing x and assigning to x, and it's not clear what you meant to happen. C++89 and C have the concept of sequence points, and if you modify the same variable twice without an intervening sequence point - the behaviour of the program is not defined (anything can happen - including replacing the whole function with return, or a segfault).
C++11 introduced a different terminology which I am not familiar with, but the effect in this case is the same - your first example is undefined behaviour.
Add some brackets according to operator precedence to see what is going on:
(++x) = (y++)
This increments x, increments y and assigns y-1 (previous value of y before the increment) to x (y++ evaluates to y, since it is a post-increment here)
(x++)=(y++)
This here isn't a valid statement, since x++ doesn't have an lvalue.
See also: Why is ++i considered an l-value, but i++ is not?

C++ : How is this statement parsed?

I have been trying to learn the associativity of operators in C++ and I have come across a code segment :
int a = 10;
int C = a++ + ++a + ++a +a;
I have also studied that ++a is right to left associative and a++ is left to right associative. Also + is left to right associative. But I don't understand how to apply this knowledge in this problem.
I am confused that how this statement will be parsed by my compiler?
I am also puzzled that since putting spaces don't matter much why does removing spaces like :
int C = a+++++a+++a+a; //error: lvalue required as increment operand
generate an error?
Please help me understand this concept.
Thanks!
First of all space does matter- It helps compiler to resolve ambiguity.
Whenever there is an expression, compiler parse it from right to left. It looks for all the post increment operators first and then pre increment operators as later has lower precedence than the former. So any modification done by pre-increment operator will be applied to the whole expression and then changes of post-increment will be applied in the next expression.
Explanation
++a first increments the value of a and then returns lvalue referring to a, so if a is used then it will be the incremented value.
In your case there are total two ++a, thus the value of a will be incremented to 12 and thus assigned to a. so all the a in your expression will be holding the value 12 giving you the value of c=48.
a++ first returns an rvalue whose value is a, that is the old value, and then increments a at an unspecified time before the next full expression.
In your case if you use value of a after the expression it will be 13 as in the previous expression there was only one a++.
For eg.
int a = 10;
int C = a++ + ++a + ++a +a; // Here a=12 and the post increment effect will be applied in the next expression
int B = a + a; // Here a=13 the effect of previous post increment.
Regarding Error
With no space in expression, compiler will get confused when it will parse expression and thus dosent have any value to do the assignment.
PS: lvalue is a value that can be the target of an assignment.
In C/C++ the pre-increment (decrement) and the post-increment (decrement) operators require an L-value expression as operand. Providing an R-value or a const qualified variable results in compilation error.
Putting aside the fact that it would result in UB (as no sequence points between these multiple increments of the same variable)
a+++++a+++a+a
is parsed (as parser is greedy) as
((a++)++) + (a++) + a + a
and (a++)++ is illegal when a is a built-in type as int.