【问题标题】:gcc strange behaviour on abs functiongcc 对 abs 函数的奇怪行为
【发布时间】:2018-12-20 15:08:09
【问题描述】:

我将一些代码从 windows (vs2010) 移植到 gcc

它的一部分看起来像:

double r1 /* = some value */;
double r2 /* = some value */;
double diff = abs(r1-r2);
std::cerr<<  r1 << ", " << r2 << ", " << diff<< std::endl;

它在 gcc (arm-linux-gnueabihf-g++ (Raspbian 6.3.0-18+rpi1+deb9u1) 6.3.0 20170516) 上编译,-Wall -Wextra 没有警告。

结果是:

0.121, 0.0709839, 0
0.015, 0.131958, 0
0.015, 0.00799561, 0
0.21, 0.00799561, 0
0.182, 0.205994, 0
0.015, 0.00799561, 0

在 Windows 上,结果是正确的。 abs 函数存在双重重载。

我不是using namespace std;。似乎在 gcc 下这些重载在全局命名空间中不存在。

我不知道标准到底是什么意思,但我预计至少会在将差异传递给abs 函数时发出关于双->int 转换的警告。

我有什么遗漏吗?为什么我没有收到此警告?

【问题讨论】:

  • 在 C++ 中没有关于隐式转换的警告。对于整数值,abs 没有重载,请考虑使用 fabs(如果您出于某种原因希望避免使用 STL。
  • en.cppreference.com/w/c/numeric/math/abs 您可能想在abs 之前输入std::
  • 很有趣,如果您使用#include &lt;math.h&gt; 而不是&lt;cmath&gt; 它可以正常工作。显然math.h 将所有内容都带入了全局命名空间,而cmath 则选择性地带来了单个重载。呵呵。
  • @bipll 是的,这是错误的,因为使用 vs2010 确实存在过载我得到了错误的结果 - 但主要问题是,为什么 gcc 不会警告转换 - 即使使用 -Wall-Wextra
  • gcc 在可靠警告方面远不如 clang。

标签: c++ gcc


【解决方案1】:

abs 是一个 C 函数,它接受一个整数并返回另一个整数。

您想改用 C++ 版本 std::abs。 Clang 实际上会警告错误(我什至将其变成错误 -Werror=absolute-value),不确定 gcc 是否有类似的标志(不是警告所有转换,仅针对 abs)。

【讨论】:

    【解决方案2】:

    我认为您正在寻找编译器选项-Wfloat-conversion,或者更一般地说,-Wconversion。然后 g++ 给了我这个警告:

     warning: conversion to ‘int’ from ‘double’ may alter its value [-Wfloat-conversion]
         double diff = abs(r1-r2);
    

    -Wall-Wextra 中不包含这两个选项。

    只要转换在您的代码中,它就可以工作,请参阅here.

    【讨论】:

    • 请注意,-Wconversion 是由所有转化触发的,因此会出现很多误报。
    猜你喜欢
    • 2011-12-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-06
    • 1970-01-01
    • 1970-01-01
    • 2017-04-24
    • 2015-02-24
    • 2018-02-20
    相关资源
    最近更新 更多