2016-07-05 4 views
6

Я столкнулся со многими комментариями по различным вопросам относительно битовых полей, утверждая, что битовые поля не переносятся, но я никогда не мог найти источник, объясняющий, почему именно.Почему и как биты C++ не переносятся?

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

Так что мой вопрос: Что это такое, что делает битпоны не переносимыми?

+1

В каком контексте они назывались «небезопасными»? Добавить ссылку? – anatolyg

+6

Я думаю, что в большинстве случаев люди злоупотребляют битовыми полями, чтобы извлекать фрагменты других типов данных на суббайтных уровнях, которые совершенно не переносятся. – user2357112

+0

@anatolyg [комментарий Лундина] (http://stackoverflow.com/questions/35934375/bitfields-in-c-programming-language/35935493#comment59526628_35934375) на [этот вопрос] (http://stackoverflow.com/questions/ 35934375/битовая-в-с-язык программирования/35935493). Конечно, я не видел, чтобы их обвиняли в том, что они «небезопасны», поскольку у меня есть «не переносные», но все же. – Pharap

ответ

2

Бит-поля не переносятся в том смысле, что порядок бит не задан. Таким образом, бит в индексе 0 с компилятором вполне может быть последним битом с другим компилятором.

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

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

Ссылка, на которую указывает @Pharap, содержит экстракт (C++ 14) норма, связанная с этим не указанным порядком: is-there-a-portable-alternative-to-c-bitfields

+2

Этот макет битового поля определяется реализацией. * Не * делает битовые поля не переносимыми. Это код, предполагающий конкретный макет, который не переносится. – 4386427

+0

@ 4386427: общая * причина * для использования битовых полей - это получение желаемого макета, например. опционные биты в аргументе функции OS API. Проблема заключается в том, что не все компиляторы могут давать один и тот же результат (иначе говоря, стандарт не предоставляет разумных гарантий для наиболее распространенного варианта использования). В конце концов, кто-то ввернул, но не обязательно оригинальный программист. –

+0

@ 4386427 Языковая конструкция не переносима или не переносима. Он поддерживается или нет компилятором. Говоря о переносимости, мы всегда говорим о * использовании * этих конструкций. Я не думал, что нужно уточнить это. – fjardon

8

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

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

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

Бит-поля строятся на обычных целых типах, поэтому они имеют те же проблемы с контентом и целыми размерами. Но у них есть even more реализация указанного поведения.

  • Все о фактических деталях распределения битовых полей в объекте класса

    • Например, на некоторых платформах, битовые поля не Straddle байт, на других они делают
    • Кроме того, на некоторых платформах битовые поля упаковываются слева направо, другие справа налево
  • Независимо от того, r, short, int, long и long long бит, которые явно не подписаны или не обозначены, подписаны или без знака.

В отличие от байтов, это не так просто, чтобы преобразовать «все о фактических деталях распределения» в канонической форме.

Кроме того, в то время как endianness является специфической архитектурой процессора, данные о поле бит специфичны для реализации компилятора. Таким образом, битовые поля не переносятся для связи даже между отдельными процессами на одном компьютере, если мы не можем гарантировать, что они были скомпилированы с использованием того же (версии) компилятора.


TL; бит битовых полей не является переносным способом связи между компьютерами. Целые числа тоже не являются, но их не-переносимость легко обойти.

Смежные вопросы