Operator precedence of postfix increment - c++

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)

Related

How a compiler make the defference between prefix and postix operators?

We know ++ and - - can be prefix or postfix and it depends on the position of the operand. for example :
++a prefix because the operand is on the right of the operator.
a++ postfix because the operand is on the left of the operator.
But In complicated expressions things become confusing. for example :
! - -a == ++ ! b I know to solve this i must apply the precedence rule but that depend on how i will consider the type of ++ , a postfix or prefix.
My question how can i decide if an operator a postfix or a prefix and more generaly how can i determine the operand of an unary operator ?
Don't.
Making some assumptions about type, your code should be:
!(-(-a)) == ++(!b)
Note the use of parentheses to obviate the need to even think about precedence.
Except this isn't a valid expression, because you can't increment an rvalue/temporary (assuming you aren't overloading operator! and returning a reference, which would be non-idiomatic and weird).
Also each side of the == should be split off into a variable declaration for clarity.
const bool isItHot = !a;
const bool isItCold = !b; // ignoring your ++ for now
return (isItHot == isItCold);
If you really need a tool to work out the precedence for you, Geordi can do it, or you can work it out from some documentation.

C++ Precedence and Associativity

This piece of code:
int scores[] {1,2,3,4};
int *score_ptr {scores};
//let's say that initial value of score_ptr is 1000
std::cout<<*score_ptr++;
produces the output:
1
As * and ++ have same precedence and then associativity is from right to left shouldn't we apply ++ operator first that is to increase the pointer first and then *(dereference) it?
So accordingly score_ptr will be increased to 1004 and then dereferencing it will give the second element of scores which is 2.
How and why does this give me output of 1 instead of 2?
As * and ++ have same precedence
No, postfix operator++ has higher precedence than operator*; then *score_ptr++ is equivalent to *(score_ptr++). Note that the postfix operator++ would increment the operand and return the original value, then *(score_ptr++) would give the value 1.
The result is prvalue copy of the original value of the operand.
On the other hand prefix operator++ returns incremented value. If you change the code to *++score_ptr (which is equivalent to *(++score_ptr)) then the result would be 2 (which might be what you expected).
The increment will happen first, it has higher precedence, it's equivalent to *(score_ptr++), but it's a post-increment, this means it will only happen after the dereferenced pointer is used, i.e. the expression reaches ;.
If you use
std::cout << *++score_ptr;
Then you have a pre-increment, here it will happen beforehand, the pointer will be incremented before the value is used and the output will be 2. Equivalent to *(++score_ptr).
Note that it's allways a good idea to use parentheses, it will make the code clearer and will avoid missinterpretations.

why parenthesis is unable to change c++ operator precedence in this case?

Here's my simple code:
int main()
{
int x = 5;
cout << (x++) << endl;
return 0;
}
the code above prints 5, not 6, even with the parenthesis, My thought is x = x + 1 be executed first before it is printed out? can anyone explain to me what's going on here? Thank you
edit: i definitely understand ++x guys, my question is about change operator precedence using ()
i definitely understand ++x guys, my question is about change operator precedence using ()
Operator precedence has nothing to do with this.
The misunderstanding probably isn't your fault: you've likely been mistaught. Your teacher(s) told you that an operand with a higher precedence, than some other operand, will be "executed first".
While this is a common explanation in schools, it is not true.
There are three things that can change the meaning of an expression in this sense:
Operator precedence
This is merely a set of rules that tell us, and tell the compiler, which operands go to which operator. Like, in 3 + 5 * 7, do we pass 3+5 to the multiplication operator, or do we pass 5*7 to the addition operator? It's about parsing.
Evaluation order
Each operand then needs to be evaluated to produce a value (e.g. 3+5 becomes 8, or 5*7 becomes 35). The rules on the order in which these evaluations happen are quite complicated in C++, more so than you might expect, but you usually don't have to worry about them unless you're doing crazy things in between sequence points (to borrow pre-C++11 parlance).
(This is the closest you'll get to a notion of "will be executed first".)
The meaning of the operator
This is where you're coming unstuck here. The meaning of the postfix increment operator x++ is "increment x, and evaluate to the old value". Period. Full stop.
It doesn't matter which operator precedence rules led to the expression x++ being evaluated (as opposed to some other interpretation of the symbols in your code): when it's evaluated, whenever it's evaluated, you get the old value for x.
The meaning of the prefix increment operator ++x, however, is "increment x, and evaluate to the new value", and that's the behaviour you want, so that's the code you should write.
Ultimately, what sequence of computer instructions actually produces this behaviour is completely up to the compiler, and can be surprising. You shouldn't worry about it, as long as the program's result is as specified in the standard.
So just forget about this "will be executed first" stuff; it's rubbish.
The expression (x++), with or without parentheses, evaluates to the previous value of x, and has the side-effect of increasing x.
If you want to see the effect of the increase then use the obscure
cout << (x++, x) << endl;
The value of x++ is the value of x before incrementing, no matter how many brackets you put. This has nothing to do with operator precendence, but this is just how post increment is defined.
edit: i definitely understand ++x guys, my question is about change operator precedence using ()
I already mentioned it, but to be clear: The value you see has little to do with operator precedence. With or without brackets ++ comes before <<. Even if this wasnt the case it would not change the value you get from x++. You could change order of the operators if you wrote
(cout << x)++ << endl;
but that would try to call ++ on the stream...
This is because x++ evaluates the value of x (5 in your case) and will increase its value after that....
what you are looking for is the pre-increment, also ++x
That is because, it is unrelated to operator precedence. The post-increment operator ++, as opposed to the pre-increment operator, increments its operand after its evaluation.
So what you see is normal and that behavior cannot be changed by introducing enclosing parenthesis around the variable. If you want the opposite to happen, then you should use the pre-increment operator like the following:
cout << ++x << endl;

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.

Post-increment and Pre-increment concept?

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