Postfix and prefix increment that causes an error - c++

Why does that code does not compile due to an error:
#include <iostream>
using namespace std;
int main()
{
int i = 0;
cout << ++(i++) << " " << i << endl;
return 0;
}
While that code does compile:
#include <iostream>
using namespace std;
int main()
{
int i = 0;
cout << (++i)++ << " " << i << endl;
return 0;
}
I do not understand that. From my point of view it would be pretty reasonable for the first chunk to compile. The expression ++(i++) would just mean take i, increment it and output, then increment it again.
I am not asking about an undefined behavior in int overflow. I do not know about r and l value at all at the time of writing the question and I do not care why is ++i considered an l-value, but i++ is not.

This is because the post increment and pre increment operators return values with different types. Result of post increment is a so-called 'rvalue', meaning it can not be modified. But pre-increment needs a modifiable value to increment it!
On the other hand, result of pre-increment is an lvalue, meaning that it can be safely modified by the post increment.
And the reason for above rules is the fact that post-increment needs to return a value of the object as it was before increment was applied. By the way, this is why in general case post-incrememts are considered to be more expensive than pre-increments when used on non-builtin objects.

Shortly speaking the difference is that in C++ you may use any even number of pluses (restricted only by the compiler limits) for the prefix increment operator like this
++++++++++++++++i;
and only two pluses for the post increment operator
i++;
The postfix increment operator returns a value (The C++ Standard, 5.2.6 Increment and decrement)
1 The value of a postfix ++ expression is the value of its
operand. [ Note: the value obtained is a copy of the original value
—end note ]
While the prefix increment operator returns its operand after increment (The C++ Standard ,5.3.2 Increment and decrement)
1 ...The result is the updated operand; it is an lvalue...
Opposite to C++ in C you also can apply only two pluses to an object using the prefix increment operator.:) Thus the C compiler will issue an error for such an expression like this
++++++++++++++++i;

When you compile it with clang you get error message that says it all.
<source>:8:13: error: expression is not assignable
cout << ++(i++) << " " << i << endl;
Maybe it is good to start with ++ operator. In fact it is shorthand for i = i + 1. Now if we look at postfix version i++, it says in standard that it returns copy of original value and as side efect it increments original value.
So from (i++) you get rvalue and are trying to assign to it and as we know you can't assign to rvalue.

Related

Post-increment vs Assignment in C++ operation precedence table

I stumbled upon https://en.cppreference.com/w/cpp/language/operator_precedence
On the chart, I see that post-increment operator (++) is way above assignment operator (=).
However, I know that
int a[] = {10,20};
int* b = &a[0];
*(b++) = 5;
cout << a[0] << endl; // 5
cout << a[1] << endl; // 20
cout << *b << endl; // 20, now points to a[1]
I always take it for grant that post-increment happens after the assignment operator. However, if I follow the operation precedence chart, then isn't post-increment suppose to happen before = operation? Isn't the answer suppose to be a={10, 5} rather than a={5, 20}?
"Precedence" is misleading. It has little to do in general with evaluation order (what happens first), but instead determines what is the operand of each operator for the purpose of evaluation. But let's examine your example.
*(b++) = 5;
This means that 5 is to be assigned to the lvalue on the left. And since C++17, we know that 5 is evaluated entirely before *(b++). Prior to that, they could be evaluated in any order.
Now, b++ has the meaning of "increment b, but evaluate to its previous value". So b++ may cause the increment to happen prior to the assignment taking place, yes, but the value of (b++) is the address before the increment happened. And that is why b is updated to point at the next element, while modifying the current one, in one expression.
Post increment (b++) increments b, then returns the previous value of b.
Pre increment (++b) increments b, then returns the new value of b.
To get the behavior you're expecting, change from post-increment to pre-increment.
For example:
#include <iostream>
int main() {
int a[] = {10, 20};
int *b = &a[0];
*(++b) = 5;
std::cout << a[0] << std::endl;
std::cout << a[1] << std::endl;
std::cout << *b << std::endl;
}
Yields the following output:
10
5
5
Table is Correct. And there is no confusion for the result.
Just remember the fact that post increment(PI) or decrement(DI), perform +1 or -1 update after the current statement containing PI or DI.
*(b++) = 5;
1st b++ will take place first as it is in parentheses. but b didn't move next yet. As compiler always remember in post operations that it would perform it after the current statement. so it is like:
*b = 5; // a[0]=5; compiler remembered b=b+1; to be executed.
so now b = b+1;
hence b is now pointing at a[1];

Why changed value does not take effect on a pass-by-reference variable during executing insertion operator chain [duplicate]

Hi all I stumbled upon this piece of code today and I am confused as to what exactly happens and more particular in what order :
Code :
#include <iostream>
bool foo(double & m)
{
m = 1.0;
return true;
}
int main()
{
double test = 0.0;
std::cout << "Value of test is : \t" << test << "\tReturn value of function is : " << foo(test) << "\tValue of test : " << test << std::endl;
return 0;
}
The output is :
Value of test is : 1 Return value of function is : 1 Value of test : 0
Seeing this I would assume that somehow the right most argument is printed before the call to the function. So this is right to left evaluation?? During debugging though it seems that the function is called prior to the output which is what I would expect. I am using Win7 and MSVS 2010. Any help is appreciated!
The evaluation order of elements in an expression is unspecified (except some very particular cases, such as the && and || operators and the ternary operator, which introduce sequence points); so, it's not guaranteed that test will be evaluated before or after foo(test) (which modifies it).
If your code relies on a particular order of evaluation the simplest method to obtain it is to split your expression in several separated statements.
The answer to this question changed in C++17.
Evaluation of overloaded operators are now sequenced in the same way as for built-in operators (C++17 [over.match.oper]/2).
Furthermore, the <<, >> and subscripting operators now have the left operand sequenced before the right, and the postfix-expression of a function call is sequenced before evaluation of the arguments.
(The other binary operators retain their previous sequencing, e.g. + is still unsequenced).
So the code in the question must now output Value of test is : 0 Return value of function is : 1 Value of test : 1. But the advice "Don't do this" is still reasonable, given that it will take some time for everybody to update to C++17.
Order of evaluation is unspecified. It is not left-to-right, right-to-left, or anything else.
Don't do this.
The order of evaluation is unspecified, see http://en.wikipedia.org/wiki/Sequence_point
This is the same situation as the example with the operator+ example:
Consider two functions f() and g(). In C and C++, the + operator is not associated with a sequence point, and therefore in the expression f()+g() it is possible that either f() or g() will be executed first.
the c++ reference explains very well why that should never be done (is causing an UB or undefined behaviour)
https://en.cppreference.com/w/cpp/language/operator_incdec
#include <iostream>
int main()
{
int n1 = 1;
int n2 = ++n1;
int n3 = ++ ++n1;
int n4 = n1++;
// int n5 = n1++ ++; // error
// int n6 = n1 + ++n1; // undefined behavior
std::cout << "n1 = " << n1 << '\n'
<< "n2 = " << n2 << '\n'
<< "n3 = " << n3 << '\n'
<< "n4 = " << n4 << '\n';
}
Notes
Because of the side-effects involved, built-in increment and decrement
operators must be used with care to avoid undefined behavior due to
violations of sequencing rules.
and in the section related to sequencing rules you can read the following:
Undefined behavior:
1) If a side effect on a scalar object is unsequenced relative to another side effect on the same scalar object, the behavior is undefined.
i = ++i + 2; // undefined behavior until C++11
i = i++ + 2; // undefined behavior until C++17
f(i = -2, i = -2); // undefined behavior until C++17
f(++i, ++i); // undefined behavior until C++17, unspecified after C++17
i = ++i + i++; // undefined behavior
2) If a side effect on a scalar object is unsequenced relative to a value computation using the value of the same scalar object, the behavior is undefined.
cout << i << i++; // undefined behavior until C++17
a[i] = i++; // undefined behavior until C++17
n = ++i + i; // undefined behavior

Static variable in C++ value is not getting updated even when incrementing in function [duplicate]

Hi all I stumbled upon this piece of code today and I am confused as to what exactly happens and more particular in what order :
Code :
#include <iostream>
bool foo(double & m)
{
m = 1.0;
return true;
}
int main()
{
double test = 0.0;
std::cout << "Value of test is : \t" << test << "\tReturn value of function is : " << foo(test) << "\tValue of test : " << test << std::endl;
return 0;
}
The output is :
Value of test is : 1 Return value of function is : 1 Value of test : 0
Seeing this I would assume that somehow the right most argument is printed before the call to the function. So this is right to left evaluation?? During debugging though it seems that the function is called prior to the output which is what I would expect. I am using Win7 and MSVS 2010. Any help is appreciated!
The evaluation order of elements in an expression is unspecified (except some very particular cases, such as the && and || operators and the ternary operator, which introduce sequence points); so, it's not guaranteed that test will be evaluated before or after foo(test) (which modifies it).
If your code relies on a particular order of evaluation the simplest method to obtain it is to split your expression in several separated statements.
The answer to this question changed in C++17.
Evaluation of overloaded operators are now sequenced in the same way as for built-in operators (C++17 [over.match.oper]/2).
Furthermore, the <<, >> and subscripting operators now have the left operand sequenced before the right, and the postfix-expression of a function call is sequenced before evaluation of the arguments.
(The other binary operators retain their previous sequencing, e.g. + is still unsequenced).
So the code in the question must now output Value of test is : 0 Return value of function is : 1 Value of test : 1. But the advice "Don't do this" is still reasonable, given that it will take some time for everybody to update to C++17.
Order of evaluation is unspecified. It is not left-to-right, right-to-left, or anything else.
Don't do this.
The order of evaluation is unspecified, see http://en.wikipedia.org/wiki/Sequence_point
This is the same situation as the example with the operator+ example:
Consider two functions f() and g(). In C and C++, the + operator is not associated with a sequence point, and therefore in the expression f()+g() it is possible that either f() or g() will be executed first.
the c++ reference explains very well why that should never be done (is causing an UB or undefined behaviour)
https://en.cppreference.com/w/cpp/language/operator_incdec
#include <iostream>
int main()
{
int n1 = 1;
int n2 = ++n1;
int n3 = ++ ++n1;
int n4 = n1++;
// int n5 = n1++ ++; // error
// int n6 = n1 + ++n1; // undefined behavior
std::cout << "n1 = " << n1 << '\n'
<< "n2 = " << n2 << '\n'
<< "n3 = " << n3 << '\n'
<< "n4 = " << n4 << '\n';
}
Notes
Because of the side-effects involved, built-in increment and decrement
operators must be used with care to avoid undefined behavior due to
violations of sequencing rules.
and in the section related to sequencing rules you can read the following:
Undefined behavior:
1) If a side effect on a scalar object is unsequenced relative to another side effect on the same scalar object, the behavior is undefined.
i = ++i + 2; // undefined behavior until C++11
i = i++ + 2; // undefined behavior until C++17
f(i = -2, i = -2); // undefined behavior until C++17
f(++i, ++i); // undefined behavior until C++17, unspecified after C++17
i = ++i + i++; // undefined behavior
2) If a side effect on a scalar object is unsequenced relative to a value computation using the value of the same scalar object, the behavior is undefined.
cout << i << i++; // undefined behavior until C++17
a[i] = i++; // undefined behavior until C++17
n = ++i + i; // undefined behavior

Why doesn't *ptr++ change the value of the pointee, but (*ptr)++ does?

I was writing this program
int x = 10;
int *yptr;
yptr = &x;
cout << "The address yptr points to = " << yptr;
cout << "The contents yptr points to =" << *yptr ;
(*yptr)++ ;
cout << "After increment, the contents are: " << *yptr;
cout << "The value of x is = " << x ;
Value increased of x from 10 to 11.
But when I write
*yptr ++ ;
Value did not increase, why?
In C++ language the grouping between operators and their operands is defined by the grammar. For convenience, this grouping is often expressed in simplified linear form called operator precedence. In C++ postfix operators have higher precedence than prefix/unary ones. So, in your case *yptr++ stands for *(yptr++), since postfix ++ has higher precedence than unary *. The ++ operator is applied directly to yptr and * is applied to the result of yptr++.
When you added the extra (), you completely changed the expression and re-grouped the operators and operands. In (*yptr)++ you forcefully associated the * with yptr. Now, * operator is applied directly to yptr and ++ is applied to the result of *yptr. Hence the change in the behavior.
In other words, the answer to your "why?" question is: because you explicitly asked the compiler make that change. The original expression was equivalent to *(yptr++) and you changed it to (*yptr)++. These are two completely different expressions with completely different meanings.
P.S. Note that the sequencing rules of C++ language does not generally allow one to describe the behavior of built-in operators in therms of what is evaluated "first" and want is evaluated "next". It is tempting to describe behavior of these expressions in therms of "++ works first, * works next", but in general case such description are incorrect and will only lead to further confusion down the road.
When you write (*yptr)++ first (*yptr) is fetched because () has higher precedence than ++, which is 10 and then ++ operator is applied, resulting 11. When you write *y ++;, first y++ is evaluated as ++ has higher precedence. That means the address is increased, then the content is fetched for * operator instead of incrementing the content. Learn operator precedence
(*ptr)++ increment the value that saved into ptr.
Like this
int *ptr;
*ptr =1;
(*ptr)++;
std::cout<< *ptr; //out put will be 2
BUT
*ptr++ increment the address of the usually for char pointer variables.
Like this
char *ptr = "Hello";
while(*ptr++)
std::cout<<*ptr; //out put will be ello

C++ Output evaluation order with embedded function calls

I'm a TA for an intro C++ class. The following question was asked on a test last week:
What is the output from the following program:
int myFunc(int &x) {
int temp = x * x * x;
x += 1;
return temp;
}
int main() {
int x = 2;
cout << myFunc(x) << endl << myFunc(x) << endl << myFunc(x) << endl;
}
The answer, to me and all my colleagues, is obviously:
8
27
64
But now several students have pointed out that when they run this in certain environments they actually get the opposite:
64
27
8
When I run it in my linux environment using gcc I get what I would expect. Using MinGW on my Windows machine I get what they're talking about.
It seems to be evaluating the last call to myFunc first, then the second call and then the first, then once it has all the results it outputs them in the normal order, starting with the first. But because the calls were made out of order the numbers are opposite.
It seems to me to be a compiler optimization, choosing to evaluate the function calls in the opposite order, but I don't really know why. My question is: are my assumptions correct? Is that what's going on in the background? Or is there something totally different? Also, I don't really understand why there would be a benefit to evaluating the functions backwards and then evaluating output forward. Output would have to be forward because of the way ostream works, but it seems like evaluation of the functions should be forward as well.
Thanks for your help!
The C++ standard does not define what order the subexpressions of a full expression are evaluated, except for certain operators which introduce an order (the comma operator, ternary operator, short-circuiting logical operators), and the fact that the expressions which make up the arguments/operands of a function/operator are all evaluated before the function/operator itself.
GCC is not obliged to explain to you (or me) why it wants to order them as it does. It might be a performance optimisation, it might be because the compiler code came out a few lines shorter and simpler that way, it might be because one of the mingw coders personally hates you, and wants to ensure that if you make assumptions that aren't guaranteed by the standard, your code goes wrong. Welcome to the world of open standards :-)
Edit to add: litb makes a point below about (un)defined behavior. The standard says that if you modify a variable multiple times in an expression, and if there exists a valid order of evaluation for that expression, such that the variable is modified multiple times without a sequence point in between, then the expression has undefined behavior. That doesn't apply here, because the variable is modified in the call to the function, and there's a sequence point at the start of any function call (even if the compiler inlines it). However, if you'd manually inlined the code:
std::cout << pow(x++,3) << endl << pow(x++,3) << endl << pow(x++,3) << endl;
Then that would be undefined behavior. In this code, it is valid for the compiler to evaluate all three "x++" subexpressions, then the three calls to pow, then start on the various calls to operator<<. Because this order is valid and has no sequence points separating the modification of x, the results are completely undefined. In your code snippet, only the order of execution is unspecified.
Exactly why does this have unspecified behaviour.
When I first looked at this example I felt that the behaviour was well defined because this expression is actually short hand for a set of function calls.
Consider this more basic example:
cout << f1() << f2();
This is expanded to a sequence of function calls, where the kind of calls depend on the operators being members or non-members:
// Option 1: Both are members
cout.operator<<(f1 ()).operator<< (f2 ());
// Option 2: Both are non members
operator<< ( operator<<(cout, f1 ()), f2 () );
// Option 3: First is a member, second non-member
operator<< ( cout.operator<<(f1 ()), f2 () );
// Option 4: First is a non-member, second is a member
cout.operator<<(f1 ()).operator<< (f2 ());
At the lowest level these will generate almost identical code so I will refer only to the first option from now.
There is a guarantee in the standard that the compiler must evaluate the arguments to each function call before the body of the function is entered. In this case, cout.operator<<(f1()) must be evaluated before operator<<(f2()) is, since the result of cout.operator<<(f1()) is required to call the other operator.
The unspecified behaviour kicks in because although the calls to the operators must be ordered there is no such requirement on their arguments. Therefore, the resulting order can be one of:
f2()
f1()
cout.operator<<(f1())
cout.operator<<(f1()).operator<<(f2());
Or:
f1()
f2()
cout.operator<<(f1())
cout.operator<<(f1()).operator<<(f2());
Or finally:
f1()
cout.operator<<(f1())
f2()
cout.operator<<(f1()).operator<<(f2());
The order in which function call parameters is evaluated is unspecified. In short, you shouldn't use arguments that have side-effects that affect the meaning and result of the statement.
Yeah, the order of evaluation of functional arguments is "Unspecified" according to the Standards.
Hence the outputs differ on different platforms
As has already been stated, you've wandered into the haunted forest of undefined behavior. To get what is expected every time you can either remove the side effects:
int myFunc(int &x) {
int temp = x * x * x;
return temp;
}
int main() {
int x = 2;
cout << myFunc(x) << endl << myFunc(x+1) << endl << myFunc(x+2) << endl;
//Note that you can't use the increment operator (++) here. It has
//side-effects so it will have the same problem
}
or break the function calls up into separate statements:
int myFunc(int &x) {
int temp = x * x * x;
x += 1;
return temp;
}
int main() {
int x = 2;
cout << myFunc(x) << endl;
cout << myFunc(x) << endl;
cout << myFunc(x) << endl;
}
The second version is probably better for a test, since it forces them to consider the side effects.
And this is why, every time you write a function with a side-effect, God kills a kitten!