相关疑难解决方法(0)

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

鉴于以下计划:

#include <cmath>

int main()
{
    std::abs(0u) ;
}
Run Code Online (Sandbox Code Playgroud)

gcc并且clang不同意这是否是不正确的.使用gcclibstdc++代码建立无错误或警告(见直播),同时采用clanglibc++它生成以下错误(见直播):

error: call to 'abs' is ambiguous
std::abs(0u) ;
^~~~~~~~
Run Code Online (Sandbox Code Playgroud)

哪个结果是正确的?应该abs(0u)是暧昧与否?


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

c++ cmath language-lawyer c++11

16
推荐指数
1
解决办法
1971
查看次数

如何避免std :: abs的意外结果?

我遇到了一些不同的例子,std::abs可以给出意想不到的结果:

  1. 这个问题(在std :: abs函数上)指出<cstdlib>为整数类型<cmath>提供重载,同时为浮点类型提供重载.未能包含正确的标头会给出未定义的行为,允许编译器静默接受
  2. C++ 缺陷报告2735指出C++ 11和C++ 14标准在技术上要求std::abs(short)返回a double,尽管大多数编译器忽略相关的措辞并返回int.这个问题的解决方案表明在C++ 17中改变了措辞,因此std::abs(short)返回一个int
  3. 这个问题的答案(我什么时候使用fabs以及何时使用std :: abs?)指出依赖std::abs可能会导致难以发现的错误,因为(在现代C++中)引入的头文件std::abs是允许引入一个全局abs函数(可能有也可能没有相同的重载),并且很容易意外使用abs而不是std::abs

我所知道的修复是:

  1. 避免未定义的行为:包括<cstdlib>评估std::abs([integral type])<cmath>评估时std::abs([floating point type])
  2. 两种选择:
    • 使用C++ 17或pre-(C++ 11)
    • 解决std::abs(short)可能返回intdouble依赖于编译器符合C++ 11/C++ 14标准的事实
  3. 两种选择:
    • 传递gcc标志,–Wconversion以便调用abs(2.0)在编译时触发警告
    • 使用一个技巧(改编自nm的答案(使用cmath时禁用math.h废话))使全局变得abs模棱两可

特技:

namespace neveruse{ …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer

11
推荐指数
1
解决办法
314
查看次数

标签 统计

c++ ×2

language-lawyer ×2

c++11 ×1

cmath ×1