Так как в первом unsigned int вы ставите -1, но с точки зрения unsigned int это 0xFFFFFFFF (именно так целые отрицательные числа хранятся в компьютере); во втором случае побитовое не совсем не смотрит на «вид» и «преобразует» 0 в 1 и наоборот, поэтому все нули 0 становятся 1 (глядя на биты), поэтому вы получаете 0xFFFFFFFF.
Следующий вопрос: почему сравнение целого без знака с целым числом со знаком не различает их? (численно 4294967295, конечно, не равен -1, хотя их представление в компьютере одинаково). В самом деле, это возможно, но ясно, что C не требует такого различия, и это «естественно», поскольку обработчик не может сделать это самостоятельно (я не уверен, что это последнее предложение всегда правда, ... но это для большинства процессоров): чтобы учесть это различие в asm, вы должны добавить дополнительный код.
С точки зрения C, вы должны решить, следует ли приводить int к unsigned int или со знаком int в unsigned int. Но отрицательное число не может быть преобразовано в беззнаковое, конечно, и, с другой стороны, беззнаковое число может вызвать переполнение (например, для 4294967295 вам нужен 64-битный регистр (или 33-битный регистр!), Чтобы иметь возможность иметь он все равно сможет рассчитать его отрицательное значение) ...
Вероятно, наиболее естественным является избегать странного приведения и разрешать сравнение с процессором, которое в этом случае приводит к 0xFFFFFFFF (-1 на 32-битной) по сравнению с 0xFFFFFFFF (~ 0 на 32-битной), которые то же самое, и больше в общем, одно можно рассматривать как MAXUINT (максимальное целое число без знака, которое может быть сохранено), а другое как -1. (Взгляните на свою машину limits.h
включите, чтобы проверить)