abs против std :: abs, что говорит ссылка?

Осторожно, я говорю о ::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 флаг (удвоение к int не сигнализируется)! Результат тот же, если заменить g++ от llvm-g++, Включение math.h или же cmath не требуется для компиляции.
  • Выход программы: x=-1.5 ax=1

И наконец результат под Linux:

  • Программа не будет компилироваться, если stdlib.h не включен (наконец, один компилятор, который не включает stdlib автоматически). Предупреждение о компиляции не выводится при приведении типа double -> int.
  • Выход программы: x=-1.5 ax=1

Нет явного победителя здесь. Я знаю, что очевидный ответ «предпочитаю std::abs в ::abs«, но мне интересно

  • Является ли сайт cplusplus.com прямо здесь, когда он говорит, что abs должен автоматически предоставить двойную версию за пределами std Пространство имен?
  • Все ли компиляторы и их стандартные библиотеки ошибочны здесь, кроме MSVC (хотя он включает math.h тихо)?

20

Решение

Официальные ссылки говорят … это беспорядок. Пре-С ++ 11 и С11:

  • Официально, в том числе <cmath> ничего не ввел в ::;
    все функции были в std::, Практически только
    export был менее уважаем, и разные компиляторы сделали очень
    разные вещи. Если вы включили <cmath>, ты использовал std::
    везде, или то, что вы получили, варьируется от компилятора к компилятору.

  • C не предоставил никаких перегрузок: abs взял int, и был
    объявлено в <stdlib.h>, fabs взял double, и был
    объявлено в <math.h>,

  • Если вы включили <math.h> в С ++ не понятно что ты
    получил, но так как ни один из разработчиков, казалось, не заботился о
    стандарт в любом случае (см. первый пункт выше) …

Грубо говоря, либо ты включил <cmath>и с префиксом
все использует с std::или вы включили <math.h>, а также
используемый fabs если вы хотели поддержку с плавающей запятой (и
различные суффиксы для типов, отличных от int или же double).

C ++ 11 и C11 добавили несколько новых поворотов:

  • <cmath> теперь разрешено (но не обязательно) вводить
    символы в :: также. Еще одна вещь, которая может варьироваться
    в зависимости от реализации. (Целью здесь было сделать
    существующие реализации соответствуют.)

  • C имеет новый заголовок, <tgmath.h>, который использует магию компилятора для
    сделать функции в <math.h> вести себя так, как будто они
    перегружен как в C ++. (Так что это не относится к abs, но только
    в fabs.) Этот заголовок был не был добавлен в C ++, для
    очевидная причина того, что C ++ не нуждается в магии компилятора для
    этот.

В общем, ситуация стала немного хуже, и мой
Рекомендации выше все еще остаются Включить либо <math.h> а также
<stdlib.h>и использовать abs/fabs и их производные (например,
labs, fabsfи т. д.) исключительно или включают <cmath>, а также
использование std::abs исключительно. Что-нибудь еще, и вы столкнетесь с
проблемы переносимости.

28

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector