C был разработан таким образом, чтобы компилятор мог быть написан для генерации кода для любой платформы и вызова языка, который он компилирует, «C».Такая свобода действует в противовес тому, что C является языком для написания кода, который можно использовать на любой платформе.
Любой, кто пишет код для C, должен решить (намеренно или по умолчанию), какие размеры int
он будет поддерживать;в то время как можно написать код на C, который будет работать с любым допустимым размером int
, это требует значительных усилий, и результирующий код часто будет гораздо менее читаемым, чем код, предназначенный для определенного целочисленного размера.Например, если у вас есть переменная x
типа uint32_t
, и вы хотите умножить ее на другую y
, вычисляя мод результата 4294967296, оператор x*=y;
будет работать на платформах, где int
равен 32бит или меньше, или где int
равно 65 битам или больше, но будет вызывать Undefined Behavior
в случаях, когда int
составляет от 33 до 64 бит, и произведение, если операнды рассматривались как целые числа, а не как членыалгебраическое кольцо, которое оборачивает мод 4294967296, будет превышать INT_MAX
.Можно заставить оператор работать независимо от размера int
, переписав его как x*=1u*y;
, но это сделает код менее понятным, и случайное исключение 1u*
из одного из умножений может иметь катастрофические последствия.
В соответствии с настоящими правилами, C достаточно переносим, если код используется только на машинах, чей целочисленный размер соответствует ожиданиям.На машинах, где размер int
не соответствует ожиданиям, код вряд ли будет переносимым, если он не содержит достаточного количества типов приведения к типу, чтобы сделать большинство правил ввода языка не относящимися к делу.