Программа с двумя разными двоичными представлениями для целых чисел со знаком - PullRequest
2 голосов
/ 10 июля 2019

От стандарта для типов данных фиксированной ширины:

[7.20.1.1 Целочисленные типы точной ширины] Имя typedef intN_t обозначает целочисленный тип со знаком с шириной N, без битов заполнения и дополняющее представление двух

Также из стандарта [6.2.6.2 Целочисленные типы] число может быть представлено как знак и величина, дополнение 1 или дополнение 2 .

Таким образом, согласно стандарту мы можем иметь программу с int32_t в представлении дополнения 2 и int с, скажем, представлением дополнения 1. Что будет, если мы сравним их? или выполнить арифметику с ними обоими? Будут иметь место целочисленные правила продвижения, но как компилятор (который не знает двоичное представление машины int) будет составлять результат с учетом двух разных представлений?

Ответы [ 2 ]

3 голосов
/ 10 июля 2019

int32_t не гарантированно существует на данной платформе.Предположительно, если бы у вас была архитектура без дополнения двойки, int32_t не был бы определен.

Начиная с 7.20.1.1 стандарта, описывающего целые числа точной ширины:

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

Имя определения типа uintN_t обозначает целочисленный тип без знака с шириной N и без битов заполнения.Таким образом, uint24_t обозначает такой целочисленный тип без знака с шириной ровно 24 бита.

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

Если по какой-либо причине машина со знакомдолжна была быть создана архитектура -and-magnitude или one -plement и адаптирован для нее компилятор, и этот компилятор решил, что он выберет создание опций с типом точной ширины, при этом автору компилятора придется преобразовать целые числа с точной ширинойк родным целочисленным типам всякий раз, когда они хотят выполнить арифметику над ними, а затем преобразовать обратно для сохранения в переменной.Это может быть особенно проблематично, поскольку дополнение к двум может представлять более широкий диапазон значений, чем знак и величина и дополнение к нему.

tl; dr: компилятор может возможно сделать точную реализациюцелочисленной ширины на платформе, которая не является дополнением к двум, но на самом деле никто не потрудится сделать это, потому что они являются необязательными, а реализация будет довольно неэффективной.

2 голосов
/ 10 июля 2019

Даже если компилятор будет использовать два разных способа представления целых чисел, он все равно будет знать, как их сравнивать или как использовать их в вычислениях.
Это гарантируется тем, что компилятор должен подчиняться соответствующим другим частям стандарта, то есть определяется, каким должно быть результирующее поведение сравнения или вычисления.

Стандарт C оставляет открытыми многие детали реализации, чтобы можно было создавать эффективные компиляторы. Результирующее поведение, однако, определено, и детали реализации, которые, конечно, известны компилятору, не могут это изменить. Два разных целочисленных представления обычно приводят к более сложному методу их совместного использования, т. Е. Поставщики компиляторов, вероятно, избегают этого.

...