Должен ли я использовать static_cast или INT64_C для переносимого назначения 64-битной константы?

Назначение 64-битной константы как

int64_t foo = 0x1234LL;

не переносится, потому что long long не обязательно int64_t. В этом сообщении Какой инициализатор подходит для int64_t? обсуждается использование макроса INT64_C() из <stdint.h>, но также возможно используйте static_cast как

int64_t foo = static_cast<int64_t>(0x1234);

?

Какой из них я должен предпочесть и почему, или оба работают хорошо?

Я искал в Интернете и на SO, но не нашел ни одного места, где изучалась бы опция static_cast. Я также провел тесты с использованием sizeof(), чтобы убедиться, что он работает в простых случаях.


person Masked Man    schedule 10.02.2013    source источник
comment
Разве статическое приведение не сделает что-то неправильное, если константа больше 64 бит, ничего не сказав?   -  person Mats Petersson    schedule 10.02.2013


Ответы (1)


Фактически, long long гарантированно будет иметь не менее 64 бит заголовком <climits> ограничений реализации C. Минимальный предел минимальных и максимальных значений для объекта типа long long задается как:

LLONG_MIN   -9223372036854775807 // −(2^63 − 1)
LLONG_MAX   +9223372036854775807 // 2^63 − 1

Это соответствует 64-битному целому числу со знаком. Вы не можете сохранить такой диапазон значений, не имея как минимум 64 информационных битов.

Так что продолжайте и используйте 0x1234LL. Фактически, вы можете так же часто использовать без суффикса, потому что будет выбран первый из следующих типов, который может соответствовать значению:

Suffix | Decimal constants | Octal or hexadecimal constant
-------|-------------------|------------------------------
none   | int               | int
       | long int          | unsigned int
       | long long int     | long int
       |                   | unsigned long int
       |                   | long long int
       |                   | unsigned long long int
...    | ...               | ...
person Joseph Mansfield    schedule 10.02.2013
comment
Спасибо. Что, если long long больше 64 бит, скажем 128 бит? Я не могу вспомнить, что написано в стандарте. Имеет ли назначение более крупный тип меньшему четко определенное поведение? (Конечно, я рассматриваю случай, когда значение умещается в пределах 64 бит.) - person Masked Man; 10.02.2013
comment
@ Deidara-senpai В этом случае, когда тип назначения подписан, результат будет неопределенным, если вы попытаетесь поместить большее целое значение в int64_t. - person Joseph Mansfield; 10.02.2013
comment
Что ж, да, я в курсе, но если значение умещается в пределах 64 бит, то хорошо ли определен результат? - person Masked Man; 10.02.2013
comment
@ Deidara-senpai Может быть, я запутался, но, конечно, присвоить int64_t значение, которое уместится в 64 бита, будет совершенно нормально. - person Joseph Mansfield; 10.02.2013
comment
Хорошо спасибо. Мне всегда сложно вспомнить эти вещи по стандарту. - person Masked Man; 10.02.2013