Простая задачка на Си++
2020-08-02 04:29Сложить два целых числа, вернуть целое. Породить исключение в случае арифметического переполнения.
Удивительно, сколько народу обламывается на этой задачке.int add(int a, int b);

no subject
Date: 2020-08-02 18:38 (UTC)no subject
Date: 2020-08-02 19:34 (UTC)int sum = a + b;
в
int sum = (int)(((unsigned int)a) + ((unsigned int)b));
а всё остальное оставить как есть.
no subject
Date: 2020-08-02 20:30 (UTC)no subject
Date: 2020-08-02 22:13 (UTC)no subject
Date: 2020-08-02 22:25 (UTC)no subject
Date: 2020-08-02 22:34 (UTC)Наверное, каст можно обойти с помощью union. Или с помощью memcpy.
no subject
Date: 2020-08-02 22:58 (UTC)memcpy() – самый надёжный способ, но если только в типе нету зарезервированных значений, т.н. trap representation (в целых обычно нет, но могут быть). А то после memcpy() при использовании результата может бяка вылезти.
no subject
Date: 2020-08-03 08:20 (UTC)Поэтому на проде вместо извращений с memcpy() и надежд на оптимизатор, я оставил бы каст, т.к. если найдётся платформа, где этот каст сломается, то проблемы будут абсолютно у всех и абсолютно везде, а не только у меня.
no subject
Date: 2020-08-02 20:25 (UTC)Вопрос в том, как убедиться в отсутствии UB. Обложить testcase-ами не поможет, ибо UB как в приведённом примере может не отличаться от ожидаемого поведения.
no subject
Date: 2020-08-02 20:44 (UTC)Но в частности есть т.н. UndefinedBehaviorSanitizer. Есть ещё немножко таких.
Преобразование unsigned int в signed int в случае переполнения даёт или implementation-defined число или implementation-defined signal.
Ну и там ещё нужно не забывать про представление чисел со знаком, коих три варианта, т.е. возможны два разных диапазона в одном и том же числе битов.
no subject
Date: 2020-08-02 22:49 (UTC)Поскольку компилятора стандарта C++ нет, это мне напоминает историю с фальшивой банкнотой. Если никто её не может отличить от настоящей, значит её можно считать настоящей.
no subject
Date: 2020-08-02 23:15 (UTC)