C и C ++ могут работать на разных архитектурах и типах машин. Следовательно, они могут иметь различные представления чисел: дополнение к двум, и дополнение к единице является наиболее распространенным. В общем, вы не должны полагаться на конкретное представление в вашей программе.
Для целочисленных типов без знака (size_t
является одним из них) стандарт C (и, думаю, стандарт C ++ тоже) определяет точные правила переполнения. Короче говоря, если SIZE_MAX
является максимальным значением типа size_t
, то выражение
(size_t) (SIZE_MAX + 1)
гарантированно будет 0
, и, следовательно, вы можете быть уверены, что (size_t) -1
равно SIZE_MAX
. То же самое относится и к другим типам без знака.
Обратите внимание, что вышеизложенное верно:
- для всех типов без знака,
- , даже если базовый компьютер не представляет числа в дополнении к двум . В этом случае компилятор должен убедиться, что идентичность верна.
Кроме того, приведенное выше означает, что вы не можете полагаться на конкретные представления для подписанных типов.
Редактировать : Чтобы ответить на некоторые комментарии:
Допустим, у нас есть фрагмент кода вроде:
int i = -1;
long j = i;
В присвоении j
есть преобразование типов. Предполагая, что int
и long
имеют разные размеры (большинство [все?] 64-битных систем), битовые структуры в ячейках памяти для i
и j
будут разными, потому что они имеют разные размеры , Компилятор гарантирует, что значения из i
и j
равны -1
.
Аналогично, когда мы делаем:
size_t s = (size_t) -1
Идет преобразование типов. -1
имеет тип int
. Он имеет битовую комбинацию, но это не имеет значения для этого примера, потому что когда преобразование в size_t
происходит из-за преобразования, компилятор преобразует значение в соответствии с правилами для типа (size_t
в данном случае). Таким образом, даже если int
и size_t
имеют разные размеры, стандарт гарантирует, что значение, сохраненное в s
выше, будет максимальным значением, которое может принять size_t
.
Если мы сделаем:
long j = LONG_MAX;
int i = j;
Если LONG_MAX
больше INT_MAX
, то значение в i
определяется реализацией (C89, раздел 3.2.1.2).