C++ Precedence and Associativity - c++

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.

Related

Why value in pointer not incrementing when I use increment operator

int a=5; int *p=&a;
I want to increment the value of a so I tried below two methods but why they are giving different values
why a=*(p)++; is giving 5
but a=*(p)+1; is giving 6
In the line a=*(p)++; the () around p don't do anything and the line is parsed as a = (*(p++)); since postfix increment has higher precedence than indirection.
So you are incrementing the pointer, not the variable that the pointer points to. The postfix increment results in the value of the pointer before it was incremented, which you then dereference to give you the current value of a.
Then the line effectively becomes a = a;, doing nothing, except that p now points one-past a.
The line a=*(p)+1; is parsed as a = ((*p) + 1); since indirection has higher precedence than addition. This is effectively a = a + 1;, doing what you want.
There is however no point in using assignment at all. Just write (*p)++; to increment a through the pointer.

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.

Predict the output with pointers

In the code below, I'm confused about the working of 3 line.If anyone explains it ,I will be very grateful.
Thank you.
#include< iostream >
using namespace std;
int main()
{
1. char s[]="abcdef";
2. char *p=s;
3. *p++=*++p;
4. cout<<s;
5. return 0;
}
Before the line *p++=*++p;, p points to the start of the array s.
The ++p in the right hand-side of the line will increment p by one and so it now points to b. Dereferencing it with * will give the value b and so the right hand side evaluates to b.
In the left hand side, since the post-increment operator is used, the value of p will not immediately change. Thus, the value b from the RHS will be set to the same memory location. Because of the post-increment operator, p will point to the character c of the array.
Thus, the char array will remain the same after this line and so abcdef will be printed. p however will point to the character c of the array.
Note that the above is valid only since c++17. From en.cppreference.com/w/cpp/language/eval_order: In every simple assignment expression E1=E2 and every compound assignment expression E1#=E2, every value computation and side-effect of E2 is sequenced before every value computation and side effect of E1

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.