Целочисленное переполнение и неопределенное поведение - PullRequest
14 голосов
/ 16 октября 2010

Есть много вопросов об обнаружении целочисленного переполнения ДО фактического сложения / вычитания из-за возможного undefined behavior.Итак, мой вопрос

Почему он будет производить это undefined behavior во-первых?

Я могу думать о 2 причинах:

1) Процессор, который генерирует исключениев этом случае.Конечно, его можно отключить, и, скорее всего, хорошо написанная ЭЛТ сделает это.

2) Процессор, который использует другие двоичные представления чисел (дополнение 1 к основанию 10?).В этом случае неопределенное поведение проявится как другой результат (но не приведет к падению!).Ну, мы могли бы жить с этим.

Итак, почему кто-то должен избегать причинения этого?Я что-то упустил?

Ответы [ 4 ]

11 голосов
/ 16 октября 2010

В то время как историческая причина подписанного переполнения была задана как неопределенное поведение, вероятно, это были поддельные устаревшие представления (дополняющие / знаковые) и прерывания переполнения, современная причина, по которой он остается неопределенным, - оптимизация. Как намекал J-16 SDiZ, тот факт, что переполнение со знаком является неопределенным поведением, позволяет компилятору оптимизировать некоторые условные выражения, чья алгебраическая истина (но не обязательно истина уровня представления) уже установлена ​​предыдущей ветвью. Это также может позволить компилятору алгебраически упростить некоторые выражения (особенно те, которые включают умножение или деление) способами, которые могут дать результаты, отличные от первоначально написанного порядка вычисления, если подвыражение содержит переполнение, поскольку компилятору разрешено предполагать, что переполнение не происходит с операндами, которые вы ему дали.

Другим огромным примером неопределенного поведения с целью разрешения оптимизации являются правила наложения имен.

11 голосов
/ 16 октября 2010

Хотя большинство современных процессоров используют дополнение 2, а целочисленное переполнение приводит к предсказуемому переходу по модулю, это ни в коем случае не является универсальным - чтобы язык был достаточно общим, чтобы его можно было использовать в широком диапазоне архитектур лучше указать, что целочисленное переполнение равно UB.

4 голосов
/ 16 октября 2010

Биты undefined behavior в спецификации включают некоторую оптимизацию компилятора. Например:

if (a > 0 && b > 0) {
    if ( a + b <= 0 ) {
       // this branch may be optimized out by compiler
    } else {
       // this branch will always run
    }
}

Современные компиляторы C не так просты, они занимаются угадыванием и оптимизацией.

0 голосов
/ 16 октября 2010

Я думаю, что ваше предположение 1) что это может быть отключено для любого данного процессора, было ложным по крайней мере на одной важной исторической архитектуре, CDC, если моя память верна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...