Когда компилятор видит smallValue * value
, он должен решить, какой тип данных будет у результата, учитывая типы входных данных signed
(8 бит) и unsigned int
(обычно 16 или 32 бита). Правила C++ гласят, что в этой ситуации результат будет беззнаковым. Поэтому значение smallValue * value
не может быть -500
, как вы ожидаете; вместо этого значение -500
интерпретируется как ПОЛОЖИТЕЛЬНОЕ число.
Кроме того, здесь вы умножаете 8-битное значение на значение, которое обычно является 16- или 32-битным. Правила C++ в этом сценарии гласят, что меньшее значение памяти сначала будет приведено к тому же размеру, что и большее; поэтому в этом случае результат smallValue * value
действительно будет достаточно большим, чтобы хранить число величиной 500
.
Умножение на беззнаковую величину anotherSmallValue
(=1) приводит к другому unsigned
с тем же значением.
Поскольку вы используете auto
, тип возвращаемого значения выводится как unsigned
.
Простое приведение обратно к signed
(путем, например, определения значения test
как int
, а не auto
, в свою очередь обычно возвращает результат всей операции обратно к значению signed
без внутреннего изменения битов; это затем будет правильно отображать -500
, как вы ожидаете; однако, как отмечали другие авторы, это довольно опасно в теории, потому что технически это не гарантирует работу, хотя обычно это будет работать таким образом с сегодняшними компиляторами.
person
Dan Nissenbaum
schedule
05.04.2013
-Werror=sign-conversion
- person abergmeier   schedule 05.04.2013