Целые числа со знаком в C представляют числа. Если aи bявляются переменными целочисленных типов со знаком, стандарт никогда не потребует, чтобы компилятор сохранял выражение a+=bво aчто-либо, кроме арифметической суммы их соответствующих значений. Чтобы быть уверенным, что если арифметическая сумма не поместится a, процессор, возможно, не сможет поместить ее туда, но стандарт не потребует от компилятора усекать или переносить значение, или делать что-либо еще в этом отношении, если значения превышают пределы для их типов. Обратите внимание, что, хотя стандарт не требует этого, реализациям C разрешено перехватывать арифметические переполнения со знаковыми значениями.
Целые числа без знака в C ведут себя как абстрактные алгебраические кольца целых чисел, которые являются конгруэнтными по модулю некоторой степени двух, за исключением случаев, когда требуется преобразование или операции с большими типами. Преобразование целого числа любого размера в 32-разрядный тип без знака приведет к члену, соответствующему вещам, которые соответствуют этому целочисленному модулю 4 294 967 296. Причина, по которой вычитание 3 из 2 дает 4 294 967 295, состоит в том, что добавление чего-то равного 3 к чему-то равному 4 294 967 295 даст что-то равное 2.
Абстрактные типы алгебраических колец часто очень удобны; к сожалению, C использует подпись как решающий фактор того, должен ли тип вести себя как кольцо. Хуже того, значения без знака обрабатываются как числа, а не как члены кольца при преобразовании в более крупные типы, а значения без знака меньше, чем intпреобразуются в числа, когда над ними выполняется любая арифметика. Если vэто uint32_tчто равняется 4,294,967,294, то v*=v;должен сделать v=4. К сожалению, если intесть 64 бита, то неясно, что v*=v;может сделать.
Учитывая стандарт как таковой, я бы предложил использовать беззнаковые типы в ситуациях, когда нужно поведение, связанное с алгебраическими кольцами, и со знаковыми типами, когда нужно представлять числа. К сожалению, C провел различия так же, как и он, но они такие, какие есть.