Consider the following code which prints the ascending order of 3
integers.
#include <iostream>
using namespace std;
int main() {
int a, b, c;
cin >> a >> b >> c;
int mn = a, mx = a;
if (b > mx)
mx = b;
if (c > mx)
mx = c;
if (b < mn)
mn = b;
if (c < mn)
mn = c;
int mid = (a b c) - (mn mx);
cout << mn << " " << mid << " " << mx << "\n";
}
Let's assume -10^9 <= a, b, c <= 10^9. So there's no overflow when reading them.
The expression (a b c)
should cause overflow when (a b c)
> INT_MAX
, however the mid
variable print correct results. I tried to print "a b c" in a separate line, it printed some negative value (clearly it's an overflow). My question is: Does the compiler make optimization when the result of expression fits in integer data type?
CodePudding user response:
It is true that a signed integer overflow can occur here, which is undefined behavior. But undefined behavior means that "anything can happen".
And here "anything can happen" means "2's complement arithmetic". Which works out the correct answer.
Does the compiler make optimization when the result of expression fits in integer data type?
No special optimizations are needed. The compiled code simply uses integer addition and subtraction that gets carried out using the rules for 2's complement arithmetic. The underlying hardware does not generate an exception for signed integer overflow, the addition simply wraps around, using 2's complement arithmetic.
The addition wraps around, and the subtraction wraps back to where it came from. Everyone lives happily ever after.