使用abs()避免编译器问题

时间:2012-01-30 15:41:09

标签: c++

使用double函数的std::abs()变体而不使用std和g ++ 4.6.1时,没有给出警告或错误。

#include <algorithm>
#include <cmath>

double foobar(double a)
{
     return abs(a);
}

此版本的g ++似乎通过double中的一个包含将abs() algorithm变体引入全局命名空间。这似乎是标准现在允许的(参见此question),但不是必需的。

如果我使用不将double abs()变体引入全局命名空间(例如g ++ 4.2)的编译器编译上述代码,则会报告以下错误:

warning: passing 'double' for argument 1 to 'int abs(int)'

如何强制g ++ 4.6.1和其他将函数拉入全局命名空间的编译器发出警告,以便在与其他编译器一起使用时可以防止错误?

2 个答案:

答案 0 :(得分:8)

您正在使用的函数实际上是abs的整数版本,GCC会隐式转换为整数。

这可以通过一个简单的测试程序来验证:

#include <iostream>
#include <cmath>

int main()
{
    double a = -5.4321;
    double b = std::abs(a);
    double c = abs(a);

    std::cout << "a = " << a << ", b = " << b << ", c = " << c << '\n';
}

输出是:

a = -5.4321, b = 5.4321, c = 5

要获得有关此内容的警告,请使用-Wconversion标志来g ++。实际上,该选项的GCC文档明确提到当参数为abs时调用double。可以找到所有警告选项here

答案 1 :(得分:0)

请注意,您无需显式#include <cmath><iostream>也会造成损坏(也许还有其他标头)。另外,请注意,-Wall不会给您任何警告。

#include <iostream>

int main() {
  std::cout << abs(.5) << std::endl;
  std::cout << typeid(decltype(abs)).name() << std::endl;
}

提供输出

0
FiiE

打开

gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04)