vak: (Default)
[personal profile] vak
Сложить два целых числа, вернуть целое. Породить исключение в случае арифметического переполнения.
int add(int a, int b);
Удивительно, сколько народу обламывается на этой задачке.

Date: 2020-08-02 22:13 (UTC)
waqur: (Default)
From: [personal profile] waqur
Не понял, где будет сигнал? На касте или на сложении? Так каст между signed/unsigned int — это бесплатно, это просто реинтерпретация битов в регистре, а сложение двух unsigned int это всегда определённое поведение, даже при переполнении.

Date: 2020-08-02 22:25 (UTC)
archaicos: Шарж (Default)
From: [personal profile] archaicos
Сигнал может быть на преобразовании из unsigned в signed (что каст, что присвоение – один хер/каст). Оно может быть не бесплатное. Я уже упомянул implementation-defined.

Date: 2020-08-02 22:34 (UTC)
waqur: (Default)
From: [personal profile] waqur
Да, вижу в C99 возможность словить сигнал при целочисленном преобразовании типов (6.3.1.3). Никогда с таким не сталкивался, но очень интересно, спасибо.

Наверное, каст можно обойти с помощью union. Или с помощью memcpy.
Edited Date: 2020-08-02 22:44 (UTC)

Date: 2020-08-02 22:58 (UTC)
archaicos: Шарж (Default)
From: [personal profile] archaicos
Приведение типов через union можно в принципе (т.е. не всегда) делать только в C. В C++ этого делать нельзя никогда.
memcpy() – самый надёжный способ, но если только в типе нету зарезервированных значений, т.н. trap representation (в целых обычно нет, но могут быть). А то после memcpy() при использовании результата может бяка вылезти.

Date: 2020-08-03 08:20 (UTC)
waqur: (Default)
From: [personal profile] waqur
В принципе, рассуждения о платформах, где каст из unsigned int в int может вызвать сигнал — это такой же религиозный пуризм, как и рассуждения о платформах, где sizeof(intmax_t)=sizeof(char), где байт содержит не 8 бит, где бинарное представление nullptr не совпадает с бинарным представлением ((size_t)0U), или где отрицательные целые числа представлены не в виде двоичного дополнения, или о таких платформах, где каст целочисленных типов совпадающей размерности через union это UB. Очень интересно, но чистая философия, сродни теологическим дискуссиям о количестве ангелов на кончике иглы.

Поэтому на проде вместо извращений с memcpy() и надежд на оптимизатор, я оставил бы каст, т.к. если найдётся платформа, где этот каст сломается, то проблемы будут абсолютно у всех и абсолютно везде, а не только у меня.
Edited Date: 2020-08-03 08:29 (UTC)