#include <cmath>
#include <cstdlib>
int main()
{
short int k = 11;
switch(std::abs(k)) {
case 44:
return 5;
break;
}
}
The above code works fine in GCC 4.4.7 and 7.1 and later. It gives an error in GCC 4.5.4 and later releases:
<source>: In function 'int main()':
<source>:7:23: error: switch quantity not an integer
So my question is why was this breaking change introduced in GCC?
Or, were the implementors not aware this was a breaking change? If so, how come, how do they test that they do not break existing code?
The question can be aimed at Clang as well since it had similar issues with the abs function.
GCC (and clang) libraries (glibc and libc++, respectively) broke backward compatibility in order to comply with the C++ Standard.
The trouble is caused by this clause:
Moreover, there shall be additional overloads suffcient to ensure:
If any arithmetic argument corresponding to a double parameter has type long double, then all arithmetic arguments corresponding to double parameters are effectively cast to long double.
Otherwise, if any arithmetic argument corresponding to a double parameter has type double or an integer type, then all arithmetic arguments corresponding to double parameters are effectively cast to double.
Otherwise, all arithmetic arguments corresponding to double parameters have type float.
short int
is "an integer type", so bullet #2 kicks in and causes generation of a wrapper which calls double abs(double)
and this wrapper is a better match than int abs(int)
.
Notably, the latest drafts of the Standard have an explicit exception added to this rule:
For each set of overloaded functions within , with the exception of
abs
, there shall be additional overloads suffcient to ensure:
This exception actually is derived from handling of unsigned types but solves your problem as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With