avatar
Миша пишет код
@misha_writes_code
16.10.2023 18:29
Миша пишет код Медиафайл
Правильный ответ: UB
(А значит может вывестись что угодно, даже "you stink" из ответа)

Причем не просто какое-то тайное неопределенное поведение, а переполнение signed int, будь он неладен.

Но в чем же дело? У нас же тут даже нет нигде интов

Весь прикол заключается в integer promotion. При операциях с типами, которые меньше инта и значения которых могут быть представлены интом, происходит promotion типа до int и операция выполняется в целых знаковых числах. А после этого происходит coercion обратно в исходный тип.

В нашем случае unsigned short - 2 байта, int - 4 байта. И значения [0, 65535] спокойно помещаются в int. Поэтому происходит promotion и данное умножение происходит в целых знаковых числах.

А 45'000 * 50'000 = 2'250'000'000 > INT_MAX = 2'147'483'647, поэтому происходит переполнения знакового числа, что является неопределенным поведением или UB.

Как не ошибиться?

В данном случае нам может помочь UB санитайзер:

clang -fsanitize=undefined code.c && ./a.out

Выдаст ошибку при запуске:
runtime error: signed integer overflow: 45000 * 50000 cannot be represented in type 'int'.

Больше по теме в статье
👍 4
🔥 1
13 253

Обсуждение 13

Обсуждение не доступно в веб-версии. Чтобы написать комментарий, перейдите в приложение Telegram.

Обсудить в Telegram