Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why did GCC break code that calls abs function with short argument?

Tags:

c++

#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.

like image 505
nadder Avatar asked Feb 18 '18 18:02

nadder


1 Answers

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:

  1. 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.

  2. 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.

  3. 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.

like image 169
Ben Voigt Avatar answered Nov 15 '22 07:11

Ben Voigt