Почему `abs ()` реализован по-другому? - PullRequest
60 голосов
/ 30 апреля 2019

За последние несколько недель в моем коде была супер расстраивающая ошибка. Мой код будет работать точно так же, как и ожидалось на моем компьютере, но как только я отправлю его на сервер HPC, он даст странные результаты.

Я сводил это к следующему: на моем компьютере (iMac) функция abs() работает с числами с плавающей запятой, но на сервере abs() усекает ее до целого числа.

Пример:

Сервер

abs(-1.1341234) = 1

Мой Mac

abs(-1.1341234) = 1.1341234

Теперь я знаю, что могу это исправить, используя fabs(), вопрос не в этом. Я посмотрел версии gcc на любой машине, и это вывод:

Сервер

g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/apps/software/GCCcore/5.4.0/libexec/gcc/x86_64-unknown-linux-gnu/5.4.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../configure --enable-languages=c,c++,fortran --enable-lto --enable-checking=release --disable-multilib --enable-shared=yes --enable-static=yes --enable-threads=posix --enable-gold=default --enable-plugins --enable-ld --with-plugin-ld=ld.gold --prefix=/apps/software/GCCcore/5.4.0 --with-local-prefix=/apps/software/GCCcore/5.4.0 --enable-bootstrap --with-isl=/dev/shm/GCCcore/5.4.0/dummy-/gcc-5.4.0/stage2_stuff
Thread model: posix
gcc version 5.4.0 (GCC) 

Мой Mac

g++ -v
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/c++/4.2.1
Apple LLVM version 10.0.1 (clang-1001.0.46.3)
Target: x86_64-apple-darwin18.5.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

Итак, мой вопрос, почему abs() дает разные результаты между gcc и clang? Эта проблема буквально стоила мне 3 недели прогресса, так что, как вы можете себе представить, я сейчас немного солен ...

1 Ответ

89 голосов
/ 30 апреля 2019

Вы должны использовать std::abs, что имеет перегрузки для примитивных типов.

В одном случае вы переходите на версию C ++ и старую версию C (которая преобразуетего параметры для целочисленных типов) в другом.

Чего следует избегать: (1) using namespace std; ( вот почему ) и (2) не имеет соответствующих #include s длявведите функциональность, которая вам нужна. Не полагайтесь на реализации стандартной библиотеки C ++, чтобы неявно включать файлы для вас.

Некоторые компиляторы будут предупреждать вас о преобразовании с потерями, если вы установите соответствующий уровень предупреждения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...