Это зависит от типа P1->OUT
и системы. Результат 1 << 1
имеет тип int
.
Я рассматриваю общий случай int n;
вместо 1 << 1
In
P1->OUT &= ~(uint8_t)(n);
операнд будет снова расширен до int
перед ~
(целочисленным повышением), а ~
будет применен к int
. В результате будут установлены все старшие биты 8 ... k. Если P1->OUT
имеет ширину 8 битов, это нормально, но если у него больше битов, результат не тот, который вы ожидаете.
Этот вариант еще хуже:
P1->OUT &= (uint8_t)(~(n));
Операнд ~
будет снова применен к int
и , которые будут преобразованы в uint8_t
. теперь, если ~n
на самом деле отрицательный (установлен бит знака) - а в случае ~(1 << 1)
он будет отрицательным - это будет хорошо в реализациях с двумя дополнениями, но полностью неверно в дополнении 1и реализации со знаком и величиной, потому что битовые представления не будут одинаковыми.
Правильный способ переворота битов - всегда использовать unsigned int или более широкое дополнение к двум. число:
P1->OUT &= ~(1U << n);
или
P1->OUT &= (~(1U << n)) & 0xFF;
, чтобы избежать арифметических преобразований и целочисленных повышений, когда-либо производящих числа со знаком.