Остерегайтесь, я говорю о ::abs()
, а не std::abs()
Согласно сайту cplusplus.com, abs
должен вести себя по-другому для версии stdlib.
h C, если вы включили <cmath>
Вот выдержка из этой страницы (которая касается ::abs
, а не std::abs
):
double abs (double x);
float abs (float x);
long double abs (long double x);
Compute absolute value
/*
Returns the absolute value of x: |x|.
These convenience abs overloads are exclusive of C++. In C, abs is only declared
in <cstdlib> (and operates on int values).
The additional overloads are provided in this header (<cmath>) for the integral types:
These overloads effectively cast x to a double before calculations
(defined for T being any integral type).
*/
Действительно???
Я был укушен этим при переносе программы на новую платформу, так как здесь различаются разные компиляторы и стандартные библиотеки.
Вот моя примерная программа:
#include <iostream>
//#include <stdlib.h>//Necessary inclusion compil under linux
//You can include either cmath or math.h, the result is the same
//#include <cmath>
#include <math.h>
int main(int argc, const char * argv[])
{
double x = -1.5;
double ax = std::abs(x);
std::cout << "x=" << x << " ax=" << ax << std::endl;
return 0;
}
И вот результат в MSVC 2010:
- В MSVC 2010 не выдается предупреждение о компиляции, и программа будет скомпилирована, даже если вы не включаете ни math.h, ни
stdlib.h
: кажется, чтоmath.h
иstdlib.h
всегда включены независимо от того, что вы делаете - Выход программы:
x=-1.5 ax=1.5
(по-видимому, правильный в соответствии с эталоном)
Теперь вот результат под OSX:
- Отсутствует предупреждение о компиляции, даже с флагом
-Wall
(двойное наложение не сигнализируется)! Результат будет таким же, если вы заменитеg++
наllvm-g++
. Вложениеmath.h
илиcmath
не требуется для компиляции. - Выход программы:
x=-1.5 ax=1
И, наконец, результат под Linux:
- Программа не будет компилироваться, если
stdlib.h
не будет включен (наконец, один компилятор, который не включаетstdlib
автоматически). Предупреждение о компиляции не выбрано для двойного → int cast. - Выход программы:
x=-1.5 ax=1
Здесь нет явного победителя. Я знаю, что очевидным ответом является "от std::abs
до ::abs
", но мне интересно:
- Является ли сайт cplusplus.com здесь, когда говорится, что
abs
должен автоматически предоставлять двойную версию за пределами пространства именstd
? - Не все ли компилятор и их стандартные библиотеки здесь, кроме MSVC (хотя он включает в себя
math.h
молча)?