2013-04-03 3 views
1

следующего кода:Integer в операциях

UINT32 dword = 4294967295; 

if(dword + 1 != 0) // condition 

В таких операциях есть ли гарантия, что самый большой (весь) регистр (по архитектуре доклада доступен) всегда используется? и выше условие будет всегда истинно в режиме 64 бит, а false для 32-битного режима?

+0

Я считаю, что стандарт указывает, что происходит с переполнением целых чисел, хотя я не помню специфику. Конечно, UINT32 будет иметь одинаковый размер как на 32, так и на 64-битных архитектурах, поэтому вы ожидаете, что он будет действовать одинаково. –

+0

@MarkRansom: Неподписанные переполнения. Подписанное переполнение имеет неопределенное поведение. –

ответ

3

Это будет зависеть от типа UINT32 на самом деле.

Если это тип без знака (как и следовало ожидать), то результаты будут гарантированно уменьшается по модулю наибольшее значение, которое может быть представлено + 1, поэтому следующий код:

if (std::numeric_limits<T>::is_unsigned) 
    assert(std::numeric_limits<T>::max()+1==0); 

... должны добиться успеха. OTOH, основанный на имени, мы обычно ожидаем, что это будет 32-разрядный тип независимо от реализации, размер регистра и т. Д., Поэтому мы ожидаем получить тот же результат независимо.

Редактировать: [извините, пришлось остановиться и накормить ребенка в течение нескольких минут] Я должен добавить более подробно. Хотя мы можем надеяться, что это практически невозможно на практике, вполне возможно, что UINT32 действительно может быть (скажем) 16-битным unsigned short. Для обсуждения предположим, что int - 32 бита.

В этом случае dword+1 будет включать в себя математику между unsigned short и int (неявный тип 1). В этом случае, dword фактически будет инициализирован до 65535. Затем, когда вы сделали добавление, что 65535 будет повышен до 32-битной int и 1 добавлены как int, так что результат будет 65536.

По крайней мере теоретически, такая же основная вещь может произойти, если UINT32 был неподписанным 32-битным типом (как и следовало ожидать), но int был 64-разрядным типом. Опять же, dword будет продвигаться до int, прежде чем делать математику, поэтому математика будет выполнена в 64-битных количествах, а не в 32-битных, поэтому (опять же) результат не обернется до 0.

+0

Использование 'std :: numeric_limits :: is_unisgned' делает мой код запахом фиолетового: P –

+0

« уменьшено по модулю наибольшее значение, которое может быть представлено »* плюс один * –

+0

@KeithThompson: Ой, совершенно верно. Спасибо. –

Смежные вопросы