int main()
{
int a=1;
int b=2;
int c=a+++b;
cout<<"c"<<c<<endl;
}
c's value turns out to be 3. While, it gives me an error for c=a++b. What is happening here? Why does c=a+++b work?
A key part of why a+++b "works", and a++b doesn't is the way the C and C++ language parsing is defined. It is what is called a 'greedy' parser. It will combine as many elements as possible to produce a valid token.
So, given that it's a greedy parser, a++b becomes a++ b, which is not valid. a+++b becomes a++ + b, which is syntactically valid - whether that is what you WANT is another matter. If you want to write a + +b, then you need spaces to separate the tokens.
Have a look at the C++ operator precedence.
(++) post-increment has the highest precedence, sou you end up with (a++) + b.
Looks like a is post increment then added to b with bad spacing. For example a++ + b. The variable a is evaluated then incremented. That being said a++b is invalid syntax.
Related
#include <iostream>
using namespace std;
int main()
{
int arr[3] = { 10, 20, 30 };
cout << arr[-2] << endl;
cout << -2[arr] << endl;
return 0;
}
Output:
4196160
-30
Here arr[-2] is out of range and invalid, causing undefined behavior.
But -2[arr] evaluates to -30. Why?
Isn't arr[-2] equivalent to -2[arr]?
-2[arr] is parsed as -(2[arr]). In C (and in C++, ignoring overloading), the definition of X[Y] is *(X+Y) (see more discussion of this in this question), which means that 2[arr] is equal to arr[2].
The compiler parses this expression
-2
like
unary_minus decimal_integer_literal
That is definitions of integer literals do not include signs.
In turn the expression
2[arr]
is parsed by the compiler as a postfix expression.
Postfix expressions have higher precedence than unary expressions. Thus this expression
-2[arr]
is equivalent to
- ( 2[arr] )
So the unary minus is applied to the lvalue returned by the postfix expression 2[arr].
On the other hand if you wrote
int n = -2;
and then
n[arr]
then this expression would be equivalent to
arr[-2]
-2[arr] is equivalent to -(2[arr]), which is equivalent to -arr[2]. However, (-2)[arr] is equivalent to arr[-2].
This is because E1[E2] is identical to (*((E1)+(E2)))
The underlying problem is with operator precedence. In C++ the [], ie the Subscript operator hold more precedence (somewhat akin to preferance) than the - unary_minus operator.
So when one writes,
arr[-2]
The compiler first executes arr[] then - , but the unary_minus is enclosed within the bounds of the [-2] so the expression is decomposed together.
In the,
-2[arr]
The same thing happens but, the compiler executes 2[] first the n the - operator so it ends up being
-(2[arr]) not (-2)[arr]
Your understanding of the concept that,
arr[i] i[arr] and *(i+arr) are all the same is correct. They are all equivalent expressions.
If you want to write in that way, write it as (-2)[arr]. You will get the same value for sure.
Check this out for future referance :http://en.cppreference.com/w/cpp/language/operator_precedence
Does spaces have any meaning in these expressions:
assume:
int a = 1;
int b = 2;
1)
int c = a++ +b;
Or,
2)
int c = a+ ++b;
When I run these two in visual studio, I get different results. Is that the correct behavior, and what does the spec says?
In general, what should be evaluated first, post-increment or pre-increment?
Edit: I should say that
c =a+++b;
Does not compile on visual studio. But I think it should. The postfix++ seems to be evaluated first.
Is that the correct behavior
Yes, it is.
Postfix ++ first returns the current value, then increments it. so int c = a++ +b means compute the value of c as the sum between current a(take the current a value, and only after taking it, increment a) and b;
Prefix ++ first increments the current value, then returns the value already incremented, so in this case, int c = a+ ++b means compute c as the sum between a and the return of the next expression, ++b, which means b is first incremented, then returned.
In general, what should be evaluated first, post-increment or
pre-increment?
In this example, it is not about which gets evaluated first, it is about what each does - postfix first returns the value, then increments it; prefix first increments the value, then returns it.
Hth
Maybe it helps to understand the general architecture of how programs are parsed.
In a nutshell, there are two stages to parsing a program (C++ or others): lexer and parser.
The lexer takes the text input and maps it to a sequence of symbols. This is when spaces are handled because they tell where the symbols are. Spaces really matter at some places (like between int and c, to not confuse with the symbol intc) but not others (like between a and ++ because there is no ambiguity to separate them).
The first example:
int c = a++ +b;
gives the following symbols, each on its own row (implementations may do this in slightly different ways of course):
int
c
=
a
++
+
b
;
While in the other case:
int c = a+ ++b;
the symbols are instead:
int
c
=
a
+
++
b
;
The parser then builds a tree (Abstract Syntax Tree, AST) out of the symbols and according to some grammar. In particular, according to the C++ grammar, + as an addition has a lower precedence than the unary ++ operator (regardless of postfix or prefix). This means that the first example is semantically the same as (a++) + b while the second is like a+ (++b).
For your examples, the ASTs will be different, because the spaces already lead to a different output at the lexer phase.
Note that spaces are not required between ++ and +, so a+++b would theoretically be fine, but this is not recommended for readability. So, some spaces are important for technical reasons while others are important for us users to read the code.
Yes they should be different; the behaviour is correct.
There are a few possible sources for your confusion.
This question is not about "spaces in operators". You have different operators. If you were to remove the space, you would have a different question. See What is i+++ increment in c++
It's also not about "what should be evaluated first, post-increment or pre-increment". It's about understanding the difference between post-increment and pre-increment.
Both increment the variable to which they apply.
But the post-increment expression returns the value from before the increment.
Whereas the pre-increment expression returns the value after the increment.
I.e.
//Given:
int a = 1;
int b = 2;
//Post-increment
int c = a++ +b; =>
1 + 2; (and a == 2) =>
3;
//Pre-increment
int c = a+ ++b; =>
1 + 3; (and b == 3) =>
4;
Another thing that might be causing confusion. You wrote: a++ +b;. And you may be assuming that +b is the unary + operator. This would be an incorrect assumption because you have both left and right operands making that + a binary additive operator (as in x + y).
Final possible confusion. You may be wondering why:
in a++ +b the ++ is a post-increment operator applied to a.
whereas in a+ ++b it's a pre-increment operator applied to b.
The reason is that ++ has higher precedence than the binary additive +. And in both cases it would be impossible to apply ++ to +.
When I run this program I get output as 2
#include<iostream.h>
#include<conio.h>
void main(){
clrscr();
int a = 10;
int c = a-- - --a;
cout<<c;
getch();
}
... but when I just modify it to
#include<iostream.h>
#include<conio.h>
void main(){
clrscr();
int a = 10,c;
c = a-- - --a;
cout<<c;
getch();
}
... I get output 0. WHY? In java both the of them gave output as 2. Whats wrong with C++?
Explain :(
Nothing wrong with C++, but there's something wrong in how you're using it.
The expression a-- - --a has undefined behavior in C++, and anything can happen.
The cleanest solution is to not write code like that (I wouldn't do it even if it were legal).
To elaborate a bit on Luchian's answer. In C++, the order in which sub-expressions are evaluated inside an expression is not specified. This means that in the following expression:
int c = a-- - --a;
there are two equally valid evaluation orders.
Evaluate a-- first (returns 10), then --a (returns 8), then
substract (returns 2).
Evaluate --a first (returns 9), then
a-- (returns 9), then substract (returns 0).
This is meant to improve optimisation oportunities for compilers. Naturally, this means that in C++ it is a mistake to use expressions that depend on evaluation order, because there is no way to know which order the compiler will select. The trade-off between efficiency and error avoidance is different in C++ and in Java.
So I know that C++ has an Operator Precedence and that
int x = ++i + i++;
is undefined because pre++ and post++ are at the same level and thus there is no way to tell which one will get calculated first. But what I was wondering is if
int i = 1/2/3;
is undefined. The reason I ask is because there are multiple ways to look at that (1/2)/3 OR 1/(2/3).
My guess is that it is a undefined behavior but I would like to confirm it.
If you look at the C++ operator precedence and associativity, you'll see that the division operator is Left-to-right associative, which means this will be evaluated as (1/2)/3, since:
Operators that are in the same cell (there may be several rows of operators listed in a cell) are evaluated with the same precedence, in the given direction. For example, the expression a=b=c is parsed as a=(b=c), and not as (a=b)=c because of right-to-left associativity.
In your example the compiler is free to evaluate "1" "2" and "3" in any order it likes, and then apply the divisions left to right.
It's the same for the i++ + i++ example. It can evaluate the i++'s in any order and that's where the problem lies.
It's not that the function's precedence isn't defined, it's that the order of evaluation of its arguments is.
The first code snippet is undefined behaviour because variable i is being modified multiple times inbetween sequence points.
The second code snippet is defined behaviour and is equivalent to:
int i = (1 / 2) / 3;
as operator / has left-to-right associativity.
It is defined, it goes from left to right:
#include <iostream>
using namespace std;
int main (int argc, char *argv[]) {
int i = 16/2/2/2;
cout<<i<<endl;
return 0;
}
print "2" instead of 1 or 16.
It might be saying that it is undefined because you have chosen an int, which is the set of whole numbers.
Try a double or float which include fractions.
The following code has me confused
int a=2,b=5,c;
c=a+++b;
printf("%d,%d,%d",a,b,c);
I expected the output to be 3,5,8, mainly because a++ means 2 +1 which equals 3, and 3 + 5 equals 8, so I expected 3,5,8. It turns out that the result is 3,5,7. Can someone explain why this is the case?
It's parsed as c = a++ + b, and a++ means post-increment, i.e. increment after taking the value of a to compute a + b == 2 + 5.
Please, never write code like this.
Maximal Munch Rule applies to such expression, according to which, the expression is parsed as:
c = a++ + b;
That is, a is post-incremented (a++) and so the current value of a (before post-increment) is taken for + operation with b.
a++ is post incrementing, i.e. the expression takes the value of a and then adds 1.
c = ++a + b would do what you expect.
This is an example of bad programming style.
It is quite unreadable, however it post increments a so it sums the current value of a to b and afterwards increments a!
a++ gets evaluated after the expression.
c = ++a + b; would give you what you thought.
The post increment operator, a++, changes tge value of a after the value of a is evaluated in the expression. Since the original value of a is 2, that's what's used to compute c; the value of a is changed to reflect the new value after the ++ is evaluated.
a++ + b ..it gives the result 7 and after the expression value of a is update to 3 because of the post increment operator
According to Longest Match rule it is parsed as a++ + +b during lexical analysis phase of compiler. Hence the resultant output.
Here c= a+++b; means c= (a++) +b; i.e post increment.
In a++, changes will occur in the next step in which it is printing a, b and c.
In ++a, i.e prefix-increment the changes will occur in the same step and it will give an output of 8.