Confusion in how C++ process these simple lines [closed] - c++

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
cout << string_1 << string_2 << string_3;
The line above is processed from left to right, first the operator "<<" operates on "cout" and "string_1", which returns an ostream object which is later used to operate on "string_2", and so on to "string_3".
a = b = 5;
In the line above, the code is processed from right to left. First the operator "=" operates on "b" and "5", which returns an int object to operate with "a" on the next "=" operator.
I might be wrong on how these lines are processed.
Please help me understand why the compiler is changing the order of operations in both cases.

This is a wise design decision.
Because you intuitively expect
cout<< string_1 << string_2 << string_3;
to emit the three strings in that order, and you expect
a = b = 5;
to assign 5 to both a and b (rather than performing a= b; b= 5;)

The fundamental reason behind this difference in processing order is operator precedence1.
Precedence and associativity determine how the operands are grouped in an expression.
So there are 2 important points to keep in mind here:
Operands of operators with higher precedence group more tightly than
operands of operators at lower precedence.
Associativity determines how to group operands with the same precedence.
Lets consider some examples to clear this up.
Example 1
Consider the expression 3+4*5+2.
Now the value(result) of this expression depends upon how the subexpressions are grouped.
In this example, multiplication and division have the same precedence as each other but they have higher precedence than addition. Thus, using Point 1 above, operands to muliplication and division group before operands to addition.
Also, the arithmetic operators are left associative which means operands of operators at the same precedence group left to right. This is what associativity meant in point 2 above.
Now, using these two facts the expression 3+4*5+2 is equivalent to:
((3+(4*5))+2)
which will result in a value of 25.
Example 2
Consider the expression cin >> x >> y;
In this example, the IO operators are left associative which means they group left to right. This is why we are able to combine IO operations in a single expression as above. This also means that the above expression is equivalent to writing:
((std::cin >> x) >> y);
Example 3
Lets come back to your example expression cout << string_1 << string_2 << string_3
As i said in example 2, IO operators are left associative which means they group left to right. Again, this means the above expression is equivalent to writing:
(((cout << string_1) << string_2) << string_3)
Example 4
Consider the expression a = b = 5
In this case, the assignment operator is right associative which means they group right to left. Thus the above expression is equivalent to writing:
(a = (b = 5))
This means 2 things:
the rightmost assignment b = 5 is the operand of the leftmost assignment operator.
because assignment returns its left-hand operand, the result of the rightmost assignment(which will be b in this case) is assigned to a.
1 Precedence specifies how the operands are grouped. It says nothing about the order
in which the operands are evaluated. There is no concept of left-to-right or right-to-left evaluation in C++.

As #UnholySheep posted in a comment:
Because that's how the operator associativity is defined: https://en.cppreference.com/w/cpp/language/operator_precedence

Related

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;

Use of <<++ and >>++ operators in C++ [duplicate]

This question already has answers here:
What is the "-->" operator in C++?
(29 answers)
Closed 4 years ago.
I have encountered <<++ and >>++ operators many time in`C++, but I don't understand what they are. What is the specific meaning and use of these operators, and how are they different from right shift and left shift operator?
C++ compilers ignore whitespace unless in certain situations such as string literals.
<<++ and >>++ is really just a bit-shift operatior << or >>, followed by an increment operator ++.
Consider this code:
a <<++ b is equivalent to
a<<++b because the spaces are ignored in this context, and then equivalent to
a << ++b (a left shifted by a pre-incremented b)
a << (++b) due to operator precedence. Bit shift operators have lower precedence than incrementation.
There are two separate operators in both cases: left shift (<<), right shift (>>) and increment operator (++).
You can rewrite the following:
a >>++ b
as:
a >> (++b)

Why does putting parentheses around a list of comma separated values change the assignment? [duplicate]

This question already has answers here:
What does a comma separated list of values, enclosed in parenthesis mean in C? a = (1, 2, 3); [duplicate]
(6 answers)
How does the Comma Operator work
(9 answers)
Closed 9 years ago.
Please consider following code,
int i;
i = 1,2,3,4,5;
printf("First time i = %d\n",i);
i = (1,2,3,4,5);
printf("Second time i = %d\n",i);
Output:
First time i = 1
Second time i = 5
Why do the parentheses make the comma operator take last value and without parentheses it takes first value?
Thanks in advance.
First one is equivalent to (i = 1),2,3,4,5; which means the commas have no effect. When used with parentheses it returns the last value in the "comma delimited list"
This is all due to operator precedence, which you can view a table about here
This is due to the operator precedence and the order of evaluation. = binds harder than , and from that we can figure out that the below two expressions are the same:
i = 1,2,3,4,5 /* <- same as -> */ (i = 1),(2),(3),(4),(5)
side-note: the comma operator is the "weakest" operator of them all
Why does the comma operator yield the last value of our list?
To put it simple this operator evaluate the first operand only to discard it and move on to the next one, it binds left-to-right which means that it will start from the left, and continue walking towards the right.
Where can I read more about this topic?
cppreference.com - C++ Operator Precedence
swansontec.com - C Language Operator Precedence
Assignment has higher precedence than comma , hence the result you get in the first case. You can find the entire operator precedence table here .
Why parenthesis makes comma operator to take last value and without parenthesis it takes first value?
Because parenthesis is used to override the precedence. The first case is implicitly equivalent to :
(i = 1),2,3,4,5;
Comma evaluates from left to right and the rightmost value is the value of the entire expression. Read the documentation here.
The comma operator has left-to-right associativity. Two expressions separated by a comma are evaluated left to right. The left operand is always evaluated, and all side effects are completed before the right operand is evaluated.
Because = has a higher precedence than , (which has the lowest), the first is the same as
(i = 1),2,3,4,5;
which assigns 1 to i (i = 1) then evaluating the expressions 2, 3, 4, and 5 through the comma operators (the whole expression actually results in 5, which is not used). In the second one,
(1,2,3,4,5)
is parenthesized, therefore it will be first evaluated before =. It results in 5 (the right-most expression; this is the behavior of the comma operator) which is then assigned to i.
i = (1,2,3,4,5);
| |
\---------\--- results in 5 then is assigned to i
See operator precedence Wikipedia article.

How is this Precedence operators working?

I know this is silly question but I don't know which step I'm missing to count so can't understand why the output is that of this code.
int i=2;
int c;
c = 2 * - ++ i << 1;
cout<< c;
I have trouble to understanding this line in this code:
c = 2 * - ++ i <<1;
I'm getting result -12. But I'm unable to get it how is precedence of operator is working here?
Have a look at the C++ Operator Precedence table.
The ++i is being evaluated, yielding 3.
The unary - is being evaluated, yielding -3.
The multiplication is being done1, yielding -6.
The bit shift is evaluated (shifting left by 1 is effectively multiplying by two) yielding -12.
The result -12 is being assigned to the variable c.
If you used parentheses to see what operator precedence was doing, you'd get
c = ((2 * (-(++i))) << 1);
Plus that expression is a bit misleading due to the weird spacing between operators. It would be better to write it c = 2 * -++i << 1;
1 Note that this is not the unary *, which dereferences a pointer. This is the multiplication operator, which is a binary operator.
Operator precedence defined the grouping between the operators and their operands. In your example the grouping is as follows
c = ((2 * (-(++i))) << 1);
That's how "precedence of operator is working here" and that's the only thing it does.
The result of this expression is -6 shifted one bit to the left. This happens to be -12 on your platform.
According to your comment in another answer, you mistakenly believe that operator precedence somehow controls what is executed "first" and what is executed "next". This is totally incorrect. Operator precedence has absolutely nothing to do with the order of execution. The only thing operator precedence does, once again, is define the grouping between the operators and their operands. No more, no less.
The order of execution is a totally different thing entirely independent from operator precedence. In fact, C++ language does not define any "order of execution" for expressions containing no sequence points inside (the above one included).

Expression evaluation in C/C++ doesnt follow BODMAS rule?

When a expression is evaluated in C/C++, does it follow BODMAS [Bracket open Division Multiply Addition Substraction] rule? If not then how they are evaluated?
EDIT: More clearly, If the following expression is evaluated according to BODMAS rule,
(5 + 3)/8*9
First what is in brackets is processed.
8/8*9.
Then Division is done.
1*9
And then multiplication and so on.
There are far more operators than that. You can find a precedence tables for C++ and C.
But yes, you'll find it respects that. (Though I'm not sure it's exactly what you've said...)
There are two answers to this question.
One is that C++ does follow standard mathematical precedence rules, which you refer to as BODMAS. You can see the order in which C++ associates all its operators here.
However, if any of the expressions involved in the operation have side effects, then C++ is not guaranteed to evaluate them in what one might consider to be standard mathematical order. That's sort of an advanced topic, however.
Other people have given you links to operator precedence lists. These are well and good. However, if you need to look at an operator precedence table to determine what your code tells computers to do, please take pity on your code's maintainers (including future you) and just use parentheses. It makes your intention much clearer and saves time and heartache in the long run.
C++: http://msdn.microsoft.com/en-us/library/126fe14k.aspx
C#: http://msdn.microsoft.com/en-us/library/aa691323(VS.71).aspx
C applies the operators in arithmetic expressions in a precise sequence determined by the following rules of operator precedence, which are generally the same as those in algebra:
Operators in expressions contained within pairs of parentheses are evaluated first. Parentheses are said to be at the “highest level of precedence.” In cases of nested, or embedded, parentheses, such as
( ( a + b ) + c )
the operators in the innermost pair of parentheses are applied first.
Multiplication, division and remainder operations are applied next. If an expression contains several multiplication, division and remainder operations, evaluation proceeds from left to right. Multiplication, division and remainder are said to be on the same level of precedence.
Addition and subtraction operations are evaluated next. If an expression contains several addition and subtraction operations, evaluation proceeds from left to right. Addition and subtraction also have the same level of precedence, which is lower than the precedence of the multiplication, division and remainder operations.
The assignment operator (=) is evaluated last.
I found an expression that doesn’t follow “BODMAS”. Here is my c program for your reference
#include <stdio.h>
int main() {
int a = 6;
int b = 4;
int c = 2;
int result;
result = a - b + c; // 4
printf("%d \n", result);
result = a + b / c; // 8
printf("%d \n", result);
result = (a + b) / c; // 5
printf("%d \n", result);
return 0;
}