Подтвердить что ты не робот

Существуют ли причины для исключения элементов структуры битового поля?

Я давно знал, что в C есть бит-поля, а иногда я использую их для определения плотно упакованных структур:

typedef struct Message_s {
     unsigned int flag : 1;
     unsigned int channel : 4;
     unsigned int signal : 11;
} Message;

Когда я читаю открытый исходный код, вместо этого я часто нахожу бит-маски и операции смены битов для хранения и извлечения такой информации в ручных бит-полях. Это настолько распространено, что я не думаю, что авторы не знали о синтаксисе битового поля, поэтому я задаюсь вопросом, есть ли причины перебрасывать бит-поля с помощью бит-масок и выполнять операции переключения самостоятельно, вместо того чтобы полагаться на компилятор для генерации код для получения и установки таких битовых полей.

4b9b3361

Ответ 1

Почему другие программисты используют ручные манипуляции вместо битовых полей, чтобы упаковать несколько полей в одно слово?

Этот ответ основан на мнениях, поскольку вопрос достаточно открытый:

  • Многие программисты не знают о наличии битовых полей или не уверены в их переносимости и точной семантике. Некоторые даже не доверяют способности компилятора создавать правильный код. Они предпочитают писать явный код, который они понимают.

    Как прокомментировал Cornstalks, это отношение уходит корнями в реальный жизненный опыт как описано в этой статье.

  • Битовая область памяти - это реализация: если макет памяти должен соответствовать точной спецификации, битовые поля не должны использоваться, и могут потребоваться манипуляции с ручным кодированием.
  • Передача подписанных значений в подписанных типизированных битовых полях определяется реализацией. Если подписанные значения упакованы в ряд битов, может быть более надежно вручную кодировать функции доступа.

Ответ 2

Есть ли причины, чтобы избежать битовых полей?

bitfield-structs имеют некоторые ограничения:

  • Поля бит приводят к не переносимому коду. Кроме того, длина битового поля имеет большую зависимость от размера слова.
  • Чтение (с использованием scanf()) и использование указателей в битовых полях невозможны из-за неадресности.
  • Бит-поля используются для хранения большего количества переменных в меньшем пространстве данных, но заставляют компилятор генерировать дополнительный код для управления этими переменными. Это приводит к увеличению как пространственных, так и временных сложностей.
  • Оператор sizeof() не может применяться к битовым полям, так как sizeof() дает результат в байтах, а не в битах.

Source

Итак, следует ли вам их использовать или нет. Подробнее в Почему bit endianness является проблемой в битполях?


PS: Когда использовать бит-поля в C?

Ответ 3

Нет причин для этого. Битвы полезны и удобны. Они широко используются во встроенных проектах. Некоторые архитектуры (например, ARM) имеют даже специальные инструкции для управления битовыми полями.

Просто сравните код (и напишите остальные функции foo1) https://godbolt.org/g/72b3vY

Ответ 4

Во многих случаях полезно иметь возможность адресовать отдельные группы битов в слове или работать над словом в виде единицы. Стандарт в настоящее время не предусматривает любой практичный и переносимый способ достижения такой функциональности. Если код написан для использования битовых полей, и позже становится необходимым обращаться к нескольким группам как к слову, не было бы хорошего способа удовлетворить это, не перерабатывая весь код с использованием битовых полей или отключая оптимизацию псевдонимов на основе типов, используя функцию punning, и надеясь, что все будет расставлено, как ожидалось.

Использование смен и масок может быть неэлегантным, но до тех пор, пока C не предоставит средство для обработки явно определенной последовательности бит в пределах одного значения lvalue в качестве другого lvalue, это часто лучший способ обеспечить, чтобы код был адаптирован для удовлетворения потребностей.