Подтвердить что ты не робот

Считается ли поведение целых чисел переполнением еще undefined в С++?

Как известно, подписанное целочисленное переполнение - это undefined поведение. Но в документации С++ 11 cstdint есть что-то интересное:

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

См. ссылку

И вот мой вопрос: поскольку в стандарте явно говорится, что для int8_t, int16_t, int32_t и int64_t отрицательные числа являются 2 дополнениями, все еще переполняют эти типы a undefined поведение?

Изменить Я проверил стандарты С++ 11 и C11, и вот что я нашел:

С++ 11, §18.4.1:

Заголовок определяет все функции, типы и макросы так же, как 7.20 в стандарте C.

C11, §7.20.1.1:

Имя typedef intN_t обозначает целочисленный тип со знаком с шириной N, без битов дополнения и представление двойного дополнения. Таким образом, int8_t обозначает такой знаковый целочисленный тип с шириной ровно 8 бит.

4b9b3361

Ответ 1

все еще переполняется этими типами поведение undefined?

Да. В абзаце 5/4 стандарта С++ 11 (в отношении любого выражения вообще):

Если во время оценки выражения результат не определяется математически или нет в диапазоне представляемые значения для своего типа, поведение undefined. [...]

Тот факт, что для этих подписанных типов используется представление с двумя дополнениями, не означает, что при оценке выражений этих типов используется арифметика по модулю 2 ^ n.

В отношении беззнаковой арифметики, с другой стороны, стандарт явно указывает, что (пункт 3.9.1/4):

Беззнаковые целые числа, объявленные unsigned, , должны подчиняться законам арифметики по модулю 2 ^ n, где n - число бит в представлении значений этого конкретного размера целого числа

Это означает, что результат беззнаковой арифметической операции всегда "математически определен", и результат всегда находится в пределах отображаемого диапазона; поэтому 5/4 не применяется. Сноска 46 объясняет это:

46) Это означает, что арифметика без знака не переполняется, потому что результат, который не может быть представлен в результате беззнаковый целочисленный тип уменьшается по модулю число, которое больше, чем наибольшее значение, которое может быть представлено получаемый беззнаковый целочисленный тип.

Ответ 2

Просто потому, что тип определен для использования представления представления 2s, он не следует, что арифметическое переполнение в этом типе становится определенным.

поведение undefined арифметического переполнения подписей используется для включения оптимизаций; например, компилятор может предположить, что если a > b then a + 1 > b также; это не выполняется в беззнаковой арифметике, где вторая проверка должна выполняться из-за возможности, что a + 1 может обернуться вокруг 0. Кроме того, некоторые платформы могут генерировать сигнал ловушки при арифметическом переполнении (см., Например, http://www.gnu.org/software/libc/manual/html_node/Program-Error-Signals.html); стандарт продолжает позволять это происходить.

Ответ 3

Я бы сделал так.

Из стандартной документации (стр. 4 и 5):

1.3.24 undefined поведение

для которого настоящий международный стандарт не предъявляет требований

[Примечание: поведение undefined можно ожидать, когда этот международный Стандарт исключает любое явное определение поведения или когда программа использует ошибочную конструкцию или ошибочные данные. Допустимый undefinedповедение варьируется от полного игнорирования ситуации непредсказуемые результаты, вести себя во время перевода или программы исполнение в документированном виде, характерном для окружающей среды (с выдачей диагностического сообщения или без него), до завершения перевод или исполнение (с выдачей диагностического сообщение). Многие ошибочные программные конструкции не порождают undefinedповедение; они должны быть диагностированы.-- конец примечания]