Это происходит из-за целочисленного продвижения: первое выражение приводит ~bitset
обратно к более короткому типу, в то время как второе выражение использует полное целочисленное значение.
Для целочисленных типов короче int
значение повышается до int
перед выполнением операции, в данном случае, перед применением к ней ~
.
Рассмотрим uint16_t
для примера. Когда вы пишете
uint16_t t = ~bitset;
значение bitset
повышается до int
, поэтому оно становится 0x0000FFFF
на 32-битной платформе. Затем ~
применяется, производя 0xFFFF0000
. Наконец, результат записывается обратно в t
, отсекая старшие биты. Следовательно, t
равно нулю.
С другой стороны, когда вы сравниваете ~bitset
напрямую с нулем, сравнение не выполняется, потому что 0xFFFF0000
не равно нулю.