Насколько мне известно, происходит следующее (пожалуйста, исправьте меня, если я ошибаюсь):
x присваивается значение -1, которое представлено битовой комбинацией 0xff, поскольку символ представлен одним байтом.
1
является целочисленной константой типа int
. -
отрицает это до -1 и остается int
. -1 присваивается char x
. Если это char
является со знаком , тогда x
принимает значение -1. Если это char
равно без знака , x
принимает значение CHAR_MAX
, которое также UCHAR_MAX
. "битовый паттерн 0xff" здесь пока не актуален.
Оператор ~ переводит x в int, то есть он внутренне работает с битовой комбинацией 0xffffffff.
x
повышается до int
(или unsigned
на редких машинах, где CHAR_MAX
== UINT_MAX
- мы будем игнорировать это). int
составляет не менее 16 бит. Значение -1, когда оно закодировано как чрезвычайно общее дополнение 2, является шаблоном со всеми 1 битами. (Возможно другое кодирование - мы тоже это проигнорируем). Если x
имеет значение UCHAR_MAX
, то x
будет иметь битовую комбинацию 00...00 1111 1111
- при условии 8-битового char
. Возможны другие значения ширины - другое, что мы будем игнорировать.
Результат оператора ~ равен 0x00000000 (типа int).
Да, (кроме случаев CHAR_MAX == UINT_MAX
, в этом случае это unsigned
и значение 11 ... 11 0000 0000).
Для выполнения назначения применяются целочисленные повышения (главным образом). Так как в нашем случае операнд справа является int, преобразование не происходит. Операнд с левой стороны преобразуется в int. Результат выполнения задания - 0x00000000.
Здесь нет целочисленных рекламных акций из-за назначения. Акции уже произошли из-за ~
. Произойдет смена типа, назначив int
для char
. Это не продвижение по службе. Результат имеет тип char
. Как часть сужения, значение 0 не вызывает проблем с диапазоном и приводит к значению 0 и типу char
. Значение 11 ... 11 0000 0000 будет проходить через поведение, определенное реализацией, и, скорее всего, приведет к значению 0 и, конечно, к типу char
.
Если бы код был (x =~x) + 0
, то char
(x =~x)
был бы повышен до int
до добавления.
В качестве побочного эффекта левой стороне присвоения присваивается значение 0x00000000. Поскольку x имеет тип char, существует другое неявное преобразование, которое преобразует 0x00000000 в 0x00.
Указано в предыдущем.
Что произойдет, если результат присваивания не может быть сохранен в символе?
Это поведение, определяемое реализацией, значение которого сохраняется. Это может включать (редко) поднятие исключения.
Битовая маскировка и манипулирование лучше всего обрабатываются с использованием беззнаковых типов и математики.