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

13 c++

使用不带有g ++ 4.6.1 doublestd::abs()函数变体时std,不会给出警告或错误.

#include <algorithm>
#include <cmath>

double foobar(double a)
{
     return abs(a);
}
Run Code Online (Sandbox Code Playgroud)

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

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

warning: passing 'double' for argument 1 to 'int abs(int)'
Run Code Online (Sandbox Code Playgroud)

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

Som*_*ude 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';
}
Run Code Online (Sandbox Code Playgroud)

输出是:

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

要获得有关此内容的警告,请使用-Wconversiong ++标志.实际上,该选项的GCC文档明确提到了abs当参数为a时的调用double.所有警告选项均可在此处找到.

  • 上面的代码不能用我的g ++版本(4.4.2)编译.但是,如果我添加一个`#include <math.h>`.VC++(VS 2010)调用`abs`的双重版本.(我认为这实际上是原始发布的重点.行为是多种多样的.)形式上,它不应该在C++ 03中编译; 它是否在C++ 11中编译是实现定义的.然而,在实践中,各实现之间总是存在很大的差异. (2认同)