繁体   English   中英

std :: abs(0u)是不是形成了?

[英]Is std::abs(0u) ill-formed?

鉴于以下计划:

#include <cmath>

int main()
{
    std::abs(0u) ;
}

gccclang不同意这是否是不正确的。 使用带有libstdc++gcc ,代码构建时没有错误或警告( 请参见实时 ),而使用clanglibc++会产生以下错误( 请参见实时 ):

error: call to 'abs' is ambiguous
std::abs(0u) ;
^~~~~~~~

哪个结果是正确的? abs(0u)是否应该含糊不清?


MSalters指出了一个有趣的相关问题: std :: abs的模板版本

看起来libstdc++是正确的,这不是libstdc++错误,虽然我们会看到对于这是否是LWG活动问题2192的缺陷表达了一些疑问。

C ++ 11标准草案第26.8[c.math]11段说:

此外,还应有足够的额外过载来确保:

并包括以下项目:

  1. 否则,如果对应于double参数的任何参数具有double类型或整数类型,则对应于double参数的所有参数都将有效地转换为double。

我们可以看到这个libstdc++ 确实提供了这种情况:

template<typename _Tp>
inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
                                                  double>::__type
abs(_Tp __x)
{ return __builtin_fabs(__x); }

如果llabs不存在 ,还有一个gcc bug报告std :: abs(long long)对std :: abs(double)的解析 ,如果这个实现是正确的并且一个响应说:

[...]根据标准是好的,任何整数都应该无条件地变为双倍。 [...]

错误报告最终导致LWG活跃问题2192:std :: abs(0u)的有效性和返回类型不清楚 ,其中包括:

  1. 在C ++ 11中,来自26.8 [c.math] p11(另见LWG 2086)的附加“足够过载”规则也可以被读取为适用于std :: abs()重载,这可能导致以下内容可能的结论:

该程序

  #include <type_traits> #include <cmath> static_assert(std::is_same<decltype(std::abs(0u)), double>(), "Oops"); int main() { std::abs(0u); // Calls std::abs(double) } 

由于子弹2(“[..]或整数类型[..]”)为26.8 [c.math] p11,所以要求格式良好(注意LWG 2086的当前分辨率不是解决这个问题)。

  1. 由于对重载std :: abs(int)的返回类型的两个冲突要求,任何包括两者的翻译单元都可能是格式错误的。

在我看来,至少第二个结果是不打算的,我个人认为两者都是不幸的[...]还应该注意,相应的“泛型类型函数”规则集在C.25 / C1x中在7.25 p2 + 3仅限于浮点函数和,因此不能应用于abs函数(但对于fabs函数!)。

问题是这是否也适用于abs 这可能是一个缺陷,因为似乎没有办法解释目前的措辞以排除abs

因此,当前的措辞表明libstdc++是符合的,不清楚为什么libc++已经选择了它们当前的实现。 我找不到错误报告,也没有涉及这个主题的讨论,LWG问题没有提到不同的实现。

建议的解决方案会使std::abs(0u)不正确:

如果使用无符号整数类型的参数调用abs(),该参数无法通过整数提升([conv.prom])转换为int,则程序格式错误。 [注意:允许提升为int的参数与C兼容。 - 结束注释]

虽然有些人可能质疑使用无符号类型的abs的概念,Howard Hinnant在报告中指出,使用模板时这种后果可能并不明显,并提供了一个例子:

[...]特别是在我们有模板的C ++中,所涉及的类型在设计时并不总是对程序员很明显。 例如,考虑:

 template <class Int> Int analyze(Int x, Int y) { // ... if (std::abs(x - y) < threshold) { // ... } // ... } 

暂无
暂无

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

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