Reputation: 412
The following code when compiled and run using g++ outputs 22
.
#include <iostream>
int main(){
int a = 5;
int c = ++a + ++a + ++a;
std::cout << c << std::endl;
return 0;
}
Floats also evaluate to the same value.
Whereas the following integer wrapper class outputs 24
#include <iostream>
class Int{
public:
int data;
Int( int value ) : data(value){}
Int& operator++(){
++data;
return *this;
}
Int operator+( const Int& b ){
return Int( data + b.data );
}
};
int main(){
Int a = 5;
Int c = ++a + ++a + ++a;
std::cout << c.data << std::endl;
return 0;
}
I am unable to understand why is there a difference in the outputs.
Could someone explain me in detail whats going on here?
Apart from this when both codes are compiled using clang
the first code outputs 21
while the second code outputs 22
.
PS : I know i shouldn't be using such an expression but my question is why are classes behaving differently than primitive types. Shouldn't they both parse to the same syntax tree and get evaluated in the same order. Even though the behaviour is undefined but for the same compiler, shouldn't they both behave in a similar manner
Upvotes: 0
Views: 165
Reputation: 1247
Both int c = ++a + ++a + ++a;
and Int c = ++a + ++a + ++a;
result in undefined behavior.
You should avoid coding like that.
See https://en.cppreference.com/w/cpp/language/operator_incdec#Example,
and see the Undefined behaviour section of cppreference.com's Order of evaluation page:
Undefined behavior
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
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
Here you can run your code with different compilers
Evaluation order on Visual C++
Evaluation order on Zapcc and GCC
Spoiler: Visual C++ behaves in the same way for primitive types and classes
On rextester you can try also Clang and GCC, but I can't add these links below the others without the editor telling me that there is some non-formatted code (which there isn't)
Evaluation order on Clang
Evaluation order on GCC
Upvotes: 4