Избегание проблем с компилятором с абс()

При использовании варианта 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 и другие компиляторы, которые вытягивают функции в глобальное пространство имен, дать предупреждение, чтобы я мог предотвратить ошибки при использовании с другими компиляторами?

Ответ 1

Используемая вами функция представляет собой целую версию 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. Все варианты предупреждений можно найти здесь.