operator << : std::cout << i << (i << 1); - c++

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)
}

Related

Ambiguity when using << >> operators

The << and >> operators have two meanings in C++, bit-shifting and stream operations. How does the compiler resolve this ambiguity when the meaning isn't obvious from context? Take this line for example:
std::cout << 1 << 2 << std::endl;
Would the output be 12, as if the second << were treated as a stream insertion, or 4, as if the second << were treated as a bit shift?
operator >> and operator << have left to right associativity. That means that with the addition of some parentheses, the actual expression is
((std::cout << 1) << 2) << std::endl;
and here you can see that with each call, the stream object, or the return of the stream expression, is used as the left hand side of each expression. That means all of the values will inserted into the stream.
There is no ambiguity, because compilers interprets the expression from left to right, so this:
std::cout << 1 << 2 << std::endl;
is equivalent to:
((std::cout << 1) << 2) << std::endl;
Consider that << has left-to-right associativity (see here) and that
std::cout << 1 << 2 << std::endl;
can be thought of as the short way of writing:
std::cout.operator<<(1).operator<<(2).operator<<(std::endl);
In other words: There is no ambiguity.
PS: Also consider that the "problem" you see is not only about two meanings of <<. The operator can be overloaded to have any meaning for a custom type. Nevertheless std::cout << custom_object_1 << custom_object_2; calls std::ostream& operator<<(std::ostream&,const custom_type&). For example: https://godbolt.org/z/fn3PTz.

Operator precedence with cout and pointers

Confused about the output for the second code snippet. Why is the output different than the first program?
#include <iostream>
using namespace std;
int main() {
int s[5] = {1, 2 , 3, 4, 5};
int *p = s;
int first = *(p++);
int second = *++p;
int third = ++*p;
int fourth = *p++;
cout << "*p++ is " << first << endl
<< "*++p is " << second << endl
<< "++*p is " << third << endl
<< "*p++ is " << fourth << endl;
return 0;
}
output:
*p++ is 1
*++p is 3
++*p is 4
*p++ is 4
https://ideone.com/Qu2uIJ
I expected the output would be the same in the code below:
#include <iostream>
using namespace std;
int main() {
int s[5] = {1, 2 , 3, 4, 5};
int *p = s;
cout << "*p++ is " << *p++ << endl
<< "*++p is " << *++p << endl
<< "++*p is " << ++*p << endl
<< "*p++ is " << *p++ << endl;
return 0;
}
output:
*p++ is 3
*++p is 3
++*p is 3
*p++ is 1
https://ideone.com/nwd7xR
What's going on?
Your statement cout << "*p++ is " << *p++ << endl << ...; is treated as one expression, and C++ is almost free in the order of evaluating the arguments used in expressions. SO it is undefined (behaviour actually) in which order the p++ and ++-statements are evaluated.
In the first approach, evaluation order is according to the variables to which you assign. In the second, C++ is free (and treats it as UB if there is no sequence point in the expression; in your's, there isn't a sequence point).
As per operator precedence, operator << is left to right which occurs in cout object in sequence one after the other and sequence of evaluation of arguments to operator << is unspecified.
Between consecutive "sequence points" an object's value can be
modified only once by an expression.
https://msdn.microsoft.com/en-us/library/azk8zbxd.aspx
The second code snippet attempts to modify the pointer's value multiple times within one sequence.
List of C Sequence Points:
Left operand of the logical-AND operator (&&).
Left operand of the logical-OR operator (||).
Left operand of the comma operator (,)
Function-call operator ()
First operand of the conditional operator aka ternary operator ( ? : )
The end of a full initialization expression (that is, an expression
that is not part of another expression such as the end of an
initialization in a declaration statement).
The expression in an expression statement. Expression statements
consist of an optional expression followed by a semicolon (;). The
expression is evaluated for its side effects and there is a sequence
point following this evaluation.
The controlling expression in a selection (if or switch) statement.
The controlling expression of a while or do statement.
Each of the three expressions of a for statement.
The expression in a return statement.

how to use shift operator in cout statement as it is overloaded

I am quite new to C++, I know that shift operator in C++ is overloaded. But as how we can do shift operation within printf statement in C can we do similar shift operation in cout statement.
Well, just try it...
#include <iostream>
int main() {
int k = 1;
std::cout << (k << 1) << std::endl; // Correct shifting - notice the parentheses
std::cout << k << 1 << std::endl; // Wrong
return 0;
}
Output:
2
11
What matters here is the type of the variables used for the << operator.
The parentheses causes it to be int << int which is the bitwise shifting. Without the parentheses it will be ostream << int which will write the int to the stream.

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.

Postfix Operator Overloading Order [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Undefined Behavior and Sequence Points
I'm having trouble understanding the order of actions when overloading the postfix operator. Let's examine the two small examples below:
int i = 0;
std::cout << std::endl << "i: " << i;
i = ++i;
std::cout << std::endl << "i: " << i;
i = i++;
std::cout << std::endl << "i: " << i;
MyClass myObject;
std::cout << std::endl << "myObject: " << myObject.getMyValue();
myObject = ++myObject;
std::cout << std::endl << "myObject: " << myObject.getMyValue();
myObject = myObject++;
std::cout << std::endl << "myObject: " << myObject.getMyValue();
Two very different behaviors emerge. The output is as follows:
i: 0
i: 1
i: 2
myObject: 0
myObject: 1
myObject: 1
Different behavior, you see. Here's the outline of my overloaded-operator methods.
MyClass & MyClass::operator++ ()
{
++myValue;
return *this;
}
MyClass MyClass::operator++ (int postfixFlag)
{
MyClass myTemp(*this);
++myValue;
return myTemp;
}
Alright. Prefix makes sense. You increment whatever you need to, then return the same object, now modified, in case of assignment. But postfix is what's tripping me up. It's supposed to assign, then increment. Here we're self assigning. So with the built-in integer type, it makes sense. I assign i's value to itself, then i gets incremented. Fair enough. But let's say MyClass is a recreation of the int. It starts out at 0, gets prefix-incremented, and becomes 1. Then, the key line. myObject = myObject++. That's the same thing as myObject = myObject.operator++(int postfixFlag). It gets called. myTemp gets initialized with the value 1. It's incremented to 2. Then we return the temp. That works, if we're assigning to another object. But here I'm self-assigning, so after the increment to 2, myObject is set equal to the returned temp object initialized with the initial value, and we're back to 1! That makes sense. But it's a fundamentally different behavior.
How do I work around it? How does int do it? How is this method generally written? Do you have any comments about C++ behavior and design relating to this? Etc. I'm a little perplexed right now, since books and online examples always seem to use a variant on the method above.
Thanks for reading, and any input will be appreciated!
As others have said, with int the behaviour is undefined. But I thought I'd try to explain why for your MyClass it is not ever getting to 2.
The trick is that you are taking the following three steps in the postfix version:
Making a copy of this called myTemp (with myValue == 1).
Incrementing this->myValue (so myTemp.myValue == 1; this->myValue == 2).
Returning myTemp (with myValue == 1).
So you are modifying this, but the code that calls myObject++ is never going to see this again. It's only going to look at the value returned, which is a copy of the old myObject.
The code for operator++ is fine. The problem is how you are using it -- you shouldn't be writing the result of a pre-increment or post-increment back to the same variable (behaviour is undefined). Here is some code that might be more instructive:
int i = 0;
std::cout << "i: " << i << std::endl;
int j = ++i;
std::cout << "i: " << i << ", j: " << j << std::endl;
int k = i++;
std::cout << "i: " << i << ", k: " << k << std::endl;
MyClass myObject;
std::cout << "myObject: " << myObject.getMyValue() << std::endl;
MyClass myObject1 = ++myObject;
std::cout << "myObject: " << myObject.getMyValue()
<< ", myObject1: " << myObject1.getMyValue() << std::endl;
MyClass myObject2 = myObject++;
std::cout << "myObject: " << myObject.getMyValue()
<< ", myObject2: " << myObject2.getMyValue() << std::endl;
This prints:
i: 0
i: 1, j: 1
i: 2, k: 1
myObject: 0
myObject: 1, myObject1: 1
myObject: 2, myObject2: 1
I changed your code so that rather than assigning back to itself, it assigns to a fresh variable each time. Note that in both the int and the MyClass cases, the main variable (i/myObject) is incremented both times. However, in the pre-increment case, the fresh variable (j/myObject1) takes on the new value, while in the post-increment case, the fresh variable (k/myObject2) takes on the old value.
Edit: Just answering another part of the question, "How does int do it?" I assume this question means "what does the pre-increment and post-increment code look like in the int class, and how can I make mine the same?" The answer is, there is no "int class". int is a special built-in type in C++ and the compiler treats it specially. These types aren't defined with ordinary C++ code, they are hard-coded into the compiler.
Note: For anyone who wants to try this themselves, here is the code for MyClass that the question didn't include:
class MyClass
{
private:
int myValue;
public:
MyClass() : myValue(0) {}
int getMyValue() { return myValue; }
MyClass& operator++();
MyClass operator++(int postfixFlag);
};