Я предполагаю, что вы пишете (uint64_t)-1
вместо -1ULL
, потому что не хотите делать предположения о размере unsigned long long
? Если так, то это хорошо. Однако есть альтернатива, которая еще не упоминалась (и на самом деле не отвечает на ваш вопрос), но может избавить вас от беспокойства, обходя вопрос:
Альтернатива
Хорошая привычка — всегда использовать UINT64_C(x)
вместо (uint64_t)x
. Это макрос, определенный в <stdint.h>
, который автоматически добавляет U
, UL
или ULL
по мере необходимости. Таким образом, UINT64_C(-1)
преобразуется в -1U
, -1UL
или -1ULL
, в зависимости от вашей цели. Это гарантированно всегда работает правильно.
Опасности приведения типов
Обратите внимание, что (uint64_t)x
на самом деле вообще не работает корректно. Например,
(uint64_t)2147483648 // RISKY
генерирует предупреждение на некоторых компиляторах, потому что значение 2147483648 (2^31) слишком велико для 32-битного целого числа, а следующее даже отдаленно не работает:
(uint64_t)1000000000000000000 // RISKY
Однако, если вместо этого вы используете UINT64_C()
, то все золото:
UINT64_C(2147483648) // GOOD
UINT64_C(1000000000000000000) // GOOD
UINT64_C(-1) // GOOD
Заметки:
- Суффикс
_C
означает «постоянный».
- В
<stdint.h>
есть также 8-, 16- и 32-битные версии для значений со знаком и без знака.
- Для особого случая –1 вы также можете просто написать
UINT64_MAX
.
person
Todd Lehman
schedule
08.08.2015