Предположим, что в реализации C (например, в компиляторе x86 C) USHRT_MAX = 65535
и INT_MAX = 2147483647
. Является ли тогда следующее утверждение корректным?
unsigned short product = USHRT_MAX * USHRT_MAX;
В соответствии со следующим стандартом C99 оба операнда продвигаются до int
(так как int
может представлять все возможные значения unsigned short
), и поэтому результат не является корректным, так как переполнение будет (65535 ^ 2 = 4294836225 > 2147483647
), что означает, что значение product
не определено:
6.3.1.1-1
Если int может представлять все значения исходного типа, это значение равно преобразован в int; в противном случае он преобразуется в unsigned int. Они называются целыми рекламными акциями. (48) Все остальные типы без изменений целыми рекламными акциями.
48) Целые поощрения применяются только: как часть обычного арифметические преобразования, к некоторым выражениям аргументов, к операндов унарных операторов +, - и ~ и обоих операндов операторы сдвига, как указано в их соответствующих подпунктах.
Однако, согласно следующему, результат корректно определен, поскольку вычисления с использованием неподписанных операндов не переполняются:
6.2.5-9
Диапазон неотрицательных значений знакового целочисленного типа является поддиапазоном соответствующего неподписанного целочисленного типа, а также представление одно и то же значение в каждом типе одинаково. (31) Вычисление, включающее неподписанные операнды никогда не могут переполняться, потому что результат, который не может быть представленный результирующим целым типом без знака, уменьшается по модулю число, которое больше, чем наибольшее значение, которое может быть представленный результирующим типом.
Имеет ли переменная product
в вышеупомянутом выражении определенное значение?
EDIT: что должно произойти в следующем случае?
unsigned short lhs = USHRT_MAX;
unsigned short rhs = USHRT_MAX;
unsigned short product = lhs * rhs;