Postfix and prefix increment [duplicate] - c++

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Undefined behavior and sequence points
(5 answers)
Closed 9 years ago.
Why the output of next code is 2 1 2?
#include "iostream"
int main(int argc, const char *argv[])
{
int i = 0;
std::cout << i << std::endl << i++ << std::endl << ++i << std::endl;
return 0;
}
Because first i is equal 2 but not zero, it means that the whole like of cout is evaluated first
and then printed (not part by part). If so, then first value should be 1, but not 2, because i++ should increment i after printing. Could you clarify?
EDIT:
The output of next code is 2 2 0.
#include "iostream"
int main(int argc, const char *argv[])
{
int i = 0;
std::cout << i << std::endl << ++i << std::endl << i++ << std::endl;
return 0;
}
why?

There is no sense reasoning in the output of your code because as it stands your program exhibits Undefined Behavior.
Per paragraph 1.9/15 of the C++11 Standard:
The value computations of the operands of an operator are sequenced before the value computation of the result of the operator. If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.
Because there is no sequence point separating both mutations of i, Undefined Behavior ensues. Your compiler might not output anything, and the program might output differently on different compilers. But arguing about the output is unnecessary in this context.
If you separate the statements, the result will then come out as expected:
std::cout << i << std::endl; // 0
std::cout << i++ << std::endl; // 0
std::cout << ++i << std::endl; // 2

the evalution goes from right to left.
i = 0
++i -> i = 1
i++ -> i = 1, post incrementation, a copy occurs. then i = 2
i -> i = 2
As all this occurs before being send to cout, the value of i is 2, and the middle one have been copied and its value is 1.

Please tell me if I don't understand your question clearly:
cout << i++;
is the equivalent of
cout << i;
i+=1;
while cout << ++i
is the equivalent of
i += 1;
cout << i;
in otherwords any time you use i++, post-increment it returns the current value then changes while ++i means increment first then return the new value. It has nothing to do with cout

Related

Postfix in C++ not behaving like I'd expect [duplicate]

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 3 years ago.
I understand the basic differences between prefix/postfix notation for decrement/increment operators in C++. However, there is something going on in the next example that stumps me.
The code I shared below prints the following.
5*4**3***4****2*****1
But I would have guessed it would print this.
5*4**4***3****2*****1
How is this happening? Is something going on with pushing/popping to/from the stack?
int var = 5;
cout << var-- << '*'; //prints 5 and then decrements to 4.
cout << var << "**"; //The value of var (now 4)
//is printed to the console.
//The next line prints 3***4****.
//I would have guessed it prints 4***3****.
cout << var-- << "***" << var-- << "****";
//No matter what the above line prints,
//the value of var after the above lines is 2, so...
cout << var-- << "*****" << var << endl; //...Print 2, decrement to 1
//and then 1 is finally printed.
Welcome to the strange world of undefined behaviour. Calling an increment or decrement operator twice on the same variable, in the same statement, is undefined behaviour, so don't do it :)
#include <iostream>
int main()
{
int i = 1;
// should this print 9, 10, or 12? Compilers will vary...
std::cout << (++i + ++i + ++i) << std::endl;
return 0;
}
The problem in this line:
cout << var-- << "***" << var-- << "****";
is undefined behaviour because you using post-decrement twice in a single statement.

Why is the value of i == 0 in this C++ code? [duplicate]

This question already has answers here:
Has C++ standard changed with respect to the use of indeterminate values and undefined behavior in C++14?
(1 answer)
Does initialization entail lvalue-to-rvalue conversion? Is `int x = x;` UB?
(4 answers)
Closed 6 years ago.
I am confused about the following code:
#include <iostream>
int i = 1;
int main()
{
int i = i;
std::cout << "i: " << i << "\n";
return 0;
}
Output:
i: 0
I had expected running the above code would print 1. Can someone please explain the reason for this strange behavior?
You are initializing i with itself. The both i's in int i = i; are the inner one not the outer one. This is undefined behavior and you may get 0 or anything may happen.
This is the right way if you want to assign the outer i to the inner i.
#include <iostream>
int i = 1;
int main()
{
int i = ::i;
std::cout << "i: " << i << "\n";
return 0;
}
Live Demo
BTW, You should carefully read all the compiler warnings. If you did you could see the problem yourself:
warning 'i' is used uninitialized in this function

c++ strange std::cout behaviour using pointers [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the correct answer for cout << c++ << c;?
I just ouputted text, when I suddenly noticed.
#include <iostream>
int main()
{
int array[] = {1,2,3,4};
int *p = array;
std::cout << *p << "___" << *(p++) << "\n";
// output is 1__1. Strange, but I used brackets! it should be at
// first incremented, not clear.
p = array;
std::cout << *p << "___" << *(++p) << "\n";
// output is 2_2 fine, why first number was affected? I didn't intend
// to increment it, but it was incremented
p=array;
std::cout << *p << "___" << *(p + 1) << "\n";
// output is 1_2 - as it was expected
p = array;
return 0;
}
Such behaviour is strange for me, why is it so?
You are causing undefined behaviour, so anything can happen and there's no point in speculating about why.
The expression
std::cout<<*p<<"___"<<*(p++)<<"\n"
Is one example: the order of evaluation of all the things between << is unspecified, so *p and *(p++) are unsequenced with respect to each other (i.e. the compiler is not required do do either one first). You are not allowed to modify a variable and then use it without the modification and usage being sequenced, and so this causes undefined behaviour.
The same thing applies to all the other places in that program where a variable is modified and used unsequenced separately in the same expression.

Is this example causing an undefined behaviour? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Undefined Behavior and Sequence Points
The variable i is changed twice, but is the next example going to cause an undefined behaviour?
#include <iostream>
int main()
{
int i = 5;
std::cout << "before i=" << i << std::endl;
++ i %= 4;
std::cout << "after i=" << i << std::endl;
}
The output I get is :
before i=5
after i=2
Yes, it's undefined. There is no sequence point on assignment, % or ++ And you cannot change a variable more than once within a sequence point.
A compiler could evaluate this as:
++i;
i = i % 4;
or
i = i % 4;
++i;
(or something else)

operator << : std::cout << i << (i << 1);

I use the stream operator << and the bit shifting operator << in one line.
I am a bit confused, why does code A) not produce the same output than code B)?
A)
int i = 4;
std::cout << i << " " << (i << 1) << std::endl; //4 8
B)
myint m = 4;
std::cout << m << " " << (m << 1) << std::endl; //8 8
class myint:
class myint {
int i;
public:
myint(int ii) {
i = ii;
}
inline myint operator <<(int n){
i = i << n;
return *this;
}
inline operator int(){
return i;
}
};
thanks in advance
Oops
Your second example is undefined behavior.
You have defined the << operator on your myint class as if it were actually <<=. When you execute i << 1, the value in i is not modified, but when you execute m << 1, the value in m is modified.
In C++, it is undefined behavior to both read and write (or write more than once) to a variable without an intervening sequence point, which function calls and operators are not, with respect to their arguments. It is nondeterministic whether the code
std::cout << m << " " << (m << 1) << std::endl;
will output the first m before or after m is updated by m << 1. In fact, your code may do something totally bizarre, or crash. Undefined behavior can lead to literally anything, so avoid it.
One of the proper ways to define the << operator for myint is:
myint operator<< (int n) const
{
return myint(this->i << n);
}
(the this-> is not strictly necessary, just my style when I overload operators)
Because int << X returns a new int. myint << X modifies the current myint. Your myint << operator should be fixed to do the former.
The reason you're getting 8 for the first is that apparently m << 1 is called first in your implementation. The implementation is free to do them in any order.
Your << operator is in fact a <<= operator. If you replace the line with
std::cout << i << " " << (i <<= 1) << std::endl; //8 8
you should get 8 8.
since m is a myInt your second example could be rewritten as:
std::cout << m << " " << (m.operator<<( 1)) << std::endl;
The order of evaluation for the subexpressions m and (m.operator<<( 1)) is unspecified, so there's no saying which "m" you'll get for the 1'st expression that m is used in (which is a simple m expression). So you might get a result of "4 8" or you might get "8 8".
Note that the statement doesn't result in undefined behavior because there are sequence points (at least one function call) between when m is modified and when it's 'read'. But the order of evaluation of the subexpressions is unspecified, so while the compiler has to produce a result (it can't crash - at least not legitimately), there's no saying which of the two possible results it should produce.
So the statement is about as useful as one that has undefined behavior, which is to say it's not very useful.
Well (m << 1) is evaluated before m and therefore m holds 8 already, as in your operator<< you overwrite your own value.
This is wrong behaviour on your side, the operator<< should be const and not change your object.
Because the << operator of myint modifies its lhs. So after evaluating m << 1, m will actually have the value 8 (while i << 1 only returns 8, but does not make i equal to 8). Since it is not specified whether m<<1 executes before cout << m (because it's not specified in which order the arguments of a function or operator are evaluated), it is not specified whether the output will be 8 8 or 4 8.
The C++ language does not define the order of evaluation of operators. It only defines their associativity.
Since your results depend on when the operator<< function is evaluated within the expression, the results are undefined.
Algebraic operator $ functions should always be const and return a new object:
inline myint operator <<(int n) const { // ensure that "this" doesn't change
return i << n; // implicit conversion: call myint::myint(int)
}