Я столкнулся с несколькими различными примерами способов, с помощью которых std::abs
может дать неожиданные результаты:
- Этот вопрос (В функции std :: abs) указывает, что
<cstdlib>
обеспечивает перегрузки для интегральных типов, в то время как<cmath>
обеспечивает перегрузки для типов с плавающей точкой. Неспособность включить правильный заголовок дает неопределенное поведение, которое компилятору разрешено молча принимать - C++ Отчет о дефектах 2735 указывает на то, что стандартам C++ 11 и C++ 14 технически требуется, чтобы
std::abs(short)
возвращалdouble
, хотя большинство компиляторов игнорируют соответствующую формулировку и возвращаютint
. Решение этой проблемы указывает, что в C++ 17 была изменена формулировка, так чтоstd::abs(short)
возвращаетint
- Ответы на этот вопрос (когда я использую fabs и когда достаточно использовать std :: abs?), Обратите внимание, что использование
std::abs
может привести к ошибкам, затрудняющим поиск, поскольку (в современных C++ ) заголовкам, которые вводятstd::abs
, разрешено вводить глобальнуюabs
функцию (которая может иметь или не иметь одинаковые перегрузки), и легко случайно использоватьabs
вместоstd::abs
Исправления, о которых я знаю, являются:
- Избегайте неопределенного поведения:
<cstdlib>
если оцениваетеstd::abs([integral type])
и<cmath>
если оцениваетеstd::abs([floating point type])
- Два варианта:
- Используйте C++ 17 или pre- (C++ 11)
- Обходитесь с тем, что
std::abs(short)
может возвращатьint
илиdouble
зависимости от соответствия компилятора стандарту C++ 11/C++ 14
- Два варианта:
- Передайте gcc
–Wconversion
чтобы вызовы типаabs(2.0)
вызывают предупреждение при компиляции - Используйте трюк (адаптированный из nm ответ на (отключить math.h дерьмо при работе с cmath)), чтобы сделать глобальный
abs
двусмысленным
- Передайте gcc
Уловка:
namespace neveruse{
int abs(int);
}
using namespace neveruse;
Вопрос: Есть ли причина предпочесть одно из решений для выпуска 3 над другим? Устанавливает ли какое-либо из этих исправлений другие потенциальные проблемы, которые мне необходимо соблюдать?