Давайте начнем с самой интересной (и наименее очевидной) части: gcc логически лает с -Wlogical-not-parentheses
.Что это значит?
C имеет два разных оператора, которые имеют похожие символы (но отличаются по поведению и предназначены для совершенно разных целей) - &
, который является побитовым AND, и &&
, который являетсялогическое И.К сожалению, это привело к опечаткам, точно так же, как ввод =
, когда вы имели в виду ==
, может вызвать проблемы, поэтому некоторые компиляторы (GCC) решили предупредить людей о «&
без использования скобок в качестве условия» (хотяэто совершенно законно), чтобы уменьшить риск опечаток.
Сейчас ...
Вы показываете код, который использует &
(и не показывает код, который использует &&
).Это означает, что some_state
не является логическим значением и является числом.Более конкретно, это означает, что каждый бит в some_state
может быть полностью независимым и не связанным.
Для примера давайте представим, что мы реализуем игру Pacman и нам нужен хороший компактный способ хранения картыдля каждого уровня.Мы решаем, что каждая плитка на карте может быть стеной или нет, может быть собранной точкой или нет, может быть пилюлей или нет, и может быть вишня или нет.Кто-то предполагает, что это может быть массив байтов, например (если предположить, что карта имеет ширину 30 плиток и высоту 20 плиток):
#define IS_WALL 0x01
#define HAS_DOT 0x02
#define HAS_POWER_PILL 0x04
#define HAS_CHERRY 0x08
uint8_t level1_map[20][30] = { ..... };
Если мы хотим знать, безопасно ли перемещать плиткув (без стены) мы могли бы сделать это:
if( level1_map[y][x] & IS_WALL == 0) {
С другой стороны, если мы хотим знать, является ли плитка стеной, мы могли бы сделать любое из следующих действий:
if( level1_map[y][x] & IS_WALL != 0) {
if( !level1_map[y][x] & IS_WALL == 0) {
if( level1_map[y][x] & IS_WALL == IS_WALL) {
..потому что не имеет значения, какой это.
Конечно (чтобы избежать опечаток) GCC может (или не может) предупреждать о некоторых из них.