简体   繁体   English

为什么GCC打破用短参数调用abs函数的代码?

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

#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. 上面的代码在GCC 4.4.7和7.1及更高版本中工作正常。 It gives an error in GCC 4.5.4 and later releases: 它在GCC 4.5.4及更高版本中出错:

<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? 所以我的问题是为什么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. 这个问题也可以针对Clang,因为它与abs函数有类似的问题。

GCC (and clang) libraries (glibc and libc++, respectively) broke backward compatibility in order to comply with the C++ Standard. GCC(和clang)库(分别是glibc和libc ++)打破了向后兼容性,以符合C ++标准。

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. 如果对应于double参数的任何算术参数具有long double类型,则对应于double参数的所有算术参数都被有效地转换为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. 否则,如果对应于double参数的任何算术参数具有double类型或整数类型 ,则对应于double参数的所有算术参数将被有效地转换为double。

  3. Otherwise, all arithmetic arguments corresponding to double parameters have type float. 否则,对应于double参数的所有算术参数都具有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) . short int是“整数类型”,因此bullet#2启动并导致生成一个调用double abs(double)包装器,这个包装器比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: 对于除了abs之外的每组重载函数,应该有足够的额外过载来确保:

This exception actually is derived from handling of unsigned types but solves your problem as well. 此异常实际上是从处理无符号类型派生的,但也解决了您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM