Почему у нас нет данных, размер которых составляет 4 бита?
Кто сказал, что? В Intel 4004 CPU были 4-битные регистры и 4-разрядные операнды памяти. 4-битные типы данных являются естественными для этого ЦП, поскольку они поддерживаются напрямую.
Intel 8051 CPU может управлять отдельными битами памяти напрямую, и поэтому вы можете иметь на нем 1-битные переменные.
Это всего лишь два примера процессоров, где типы данных могут быть очень маленькими, меньше, чем теперь вездесущие 8-битные байты.
Почему мы не можем сделать их, если мы так склонны?
Мы можем. Вы можете либо сделать CPU с прямой поддержкой 4-битных типов данных, либо вы можете имитировать 4-битные переменные как части более крупных переменных.
Вы можете упаковать 2 4-битные переменные в 8-разрядный байт. Проблема с этим подходом заключается в том, что вам нужно использовать дополнительные инструкции для извлечения 4 битов из 8-битных регистров или мест памяти (для этого вам требуется инструкция shift и mask (AND
)), и вам также понадобится больше инструкций по правильному сохранению 4 (бит 8 бит, очистить старое значение в 4-битной половине (с маской/AND
), сдвинуть новое значение, объединить его с остальными и сохранить обратно). Очевидно, это негативно повлияет на размер кода вашей программы и ее скорость.Кроме того, 4-битные переменные не очень полезны, поскольку они могут хранить так мало информации. По этим причинам моделирование меньших типов не очень популярно.
Я видел бит-поля, но я слышал, что они не переносимы и, возможно, тоже не используются?
Используются. Они существуют именно потому, что в некоторых (но не во всех) приложениях они очень полезны. Если у вас много коротких переменных, может оказаться выгодным упаковать несколько из них в байтовое или машинное слово и таким образом сократить количество отходов памяти.
Они не являются полностью неспортивными. Они имеют ограниченную переносимость в C и C++, потому что языковые стандарты не определяют точное расположение и расположение бит-полей в более крупных типах данных. Это сделано намеренно, чтобы позволить авторам компилятора наиболее эффективно использовать функции ЦП при работе с битовыми полями.
6.7.2.1 Structure and union specifiers
clause 10
стандарта C с 1999 года говорит, что это:
Реализация может выделить любой адресуемый блок хранения достаточно большой, чтобы держать битовое. Если остается достаточно места, бит-поле, которое сразу следует за другим битовым полем в структуре, должно быть упаковано в соседние биты того же блока. Если недостаточно места, то будет ли бит-поле, которое не подходит, помещается в следующий блок или перекрывает смежные единицы, определяется реализацией. Порядок распределения бит-полей внутри единицы (от высокого порядка до младшего или низкого порядка) определяется реализацией. Выравнивание адресного блока хранения не указывается.
Я думаю, что это результат того, как машина интерпретирует топоним значение местоположения долота. (big-endian, little-endian)
Да, это часть причины. Но это никоим образом не характерно для бит-полей. У этой проблемы также есть обычные, небитовые типы.
Мы также не можем сделать бит-поле, подобное этому, которое больше любого примитивного типа. Так почему же ограничения? Это можно сделать в сборке?
Если ваш C (или C++) -компилятор (или интерпретатор) может имитировать типы, которые больше, чем те, которые поддерживаются ЦП, могут иметь даже 256-битные битовые поля.
Но опять же, если самый большой тип процессора, поддерживаемый напрямую, является 32-разрядным, это будет означать, что использование более крупных типов (будь то бит-полей или нет), таких как 128-битные, приведет к большему количеству кода и некоторой производительности поскольку одна команда CPU (или только пара из них) не сможет манипулировать такими большими значениями данных. Для выполнения этих дополнительных инструкций вам потребуется больше инструкций и больше времени.
Да, это можно сделать в сборке. Все, что можно сделать в сборке, пока вы готовы написать код и заставить его работать. :)
Мы можем, не проблема. причина, по которой мы не являемся, потому что это непрактично. В вычислительном мире использовались 9-битные байт-байты 36-битных слов или двойных слов, все были восьмеричными людьми, которые считались в единицах из 3 бит, как обычно, сейчас в единицах из четырех бит, hex. x86 и другие аналогичные старые архитектуры выполняли бы 4-битную математику, BCD, с 4-битным переносным битом и т. д.это просто не практично. Мир действительно не байт, основанный либо на наименьших единицах памяти, которые чаще всего видны на 64 бита, а на 32 бита. байты являются иллюзией по большей части ... –
Вы используете 64 или 32-битные регистры и шины данных все время, имея возможность просто не смотреть на другие 24 или 16 или любые битовые полосы. Битвые поля в C 1) настолько плохие, что вы никогда не должны их использовать 2) иллюзия. он просто создает код, который вы могли бы написать себе, переместиться и замаскировать, чтобы притворяться, что есть такая вещь, как 1-битная переменная. Даже символы и шорты на C - это иллюзия на многих процессорах, которые мы используем, например битовые поля, которые создают дополнительные инструкции для превращения большего регистра в нечто меньшее. или наоборот. –