Ваше предположение верно. Операнды для многих операторов в C ++ (например, двоичные арифметические операции и операторы сравнения) подвергаются обычным арифметическим преобразованиям. В C ++ 17 обычные арифметические преобразования определены в [expr] / 11 . Я не собираюсь цитировать весь абзац здесь, потому что он довольно большой (вы можете просто щелкнуть ссылку), но для целочисленных типов обычные арифметические преобразования сводятся к применяемым интегральным продвижениям, а затем к некоторому более эффективному продвижению в смысле что если типы двух операндов после начальных интегральных повышений не совпадают, меньший тип преобразуется в больший из двух. Интегральные продвижения в основном означают, что любой тип, меньший int
, будет повышен до int
или unsigned int
, в зависимости от того, какое из двух значений может представлять все возможные значения исходного типа, что в основном и является причиной поведения в вашем пример.
Как вы уже выяснили, в вашем коде обычные арифметические преобразования происходят в a = a + 1;
и, что наиболее заметно, в состоянии вашего if
if (a != b + 1)
…
, где они вызывают повышение b
до int
, в результате чего b + 1
будет иметь тип int
, а a
- int
и !=
, таким образом, происходит со значениями типа int
, что делает условие истинным, а не ложным & hellip;