2013-09-10 3 views
3

Каждая книга, которую я искал, каждый учебник в Интернете и каждый q & a на SO говорит, что битполы должны быть целыми. Почему это?Почему битовые поля должны быть целыми?

+2

Задайте себе противоположный вопрос. Каждая книга, которую я искал, каждый учебник в Интернете говорит о том, что битовые поля не могут быть типами с плавающей точкой, строками или сложными объектами. Почему это? –

+1

Что это значит иметь бит-поле с плавающей запятой? –

+0

@ JonathanLeffler Я знаю, что это должно быть очевидно, но я не знаю. Просто не понимаю. – zubergu

ответ

4

Давайте спросим обратный вопрос:

  • Какие типы, кроме целочисленного типа может быть немного поле?

Давайте рассмотрим варианты:

  1. void: не значение - не будет работать.
  2. Указатели: но указатели на машине фиксированного размера; вы не можете использовать 13 бит указателя и ожидать, что это будет означать что угодно.
  3. Структуры, союзы: но тогда вы не имеете дело с простыми полями.
  4. Это оставляет float или double, но это тщательно разработанные форматы, и вы не можете просто использовать 13 бит из double (или float) и ожидать, что это будет означать что угодно.

Итак, после того, как вы прошли через опцию, вы остались с различными типами целым: char, short, int, long, long long (в подписанных и неподписанных формах), и _Bool. Из этих вариантов, стандарт определяет, что вы можете использовать _Bool, unsigned int, signed int и 'просто' int:

ISO/IEC 9899: 2011 §6.7.2.1 Структура и объединение спецификаторов типа

¶ 5 Битовое поле должно иметь тип, который является квалифицированной или неквалифицированной версией _Bool, signed int, unsigned int или некоторым другим определенным для реализации типом. Определено, являются ли атомарные типы разрешенными реализациями .

Поведение «обычный» int является реализация определена: он может быть знаком или без знака (примерно как «обычная» char может быть знаком или без знака). Итак, комментарий jxh верен; Я небрежно цитировал слишком много типов (но я перефразировал вещи так, что это не так вводит в заблуждение).

Обратите внимание, что большая часть поведения бит-полей определяется реализацией; за пределами обозначений очень мало, что указано в стандарте.

+0

По какой-то причине он является стандартным для '_Bool',' int' и 'unsigned int'. Все остальные определяются реализацией. – jxh

+0

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

+0

C99 обеспечивает поддержку шестнадцатеричных констант для указания значений с плавающей запятой, но это концепция исходного кода; было бы трудно справиться с ними во время выполнения (вам, вероятно, придется использовать 'snprintf()' и 'sscanf()'). Я не уверен, где следует перечислять '_Complex'; он может быть составным, как структуры и союзы. Я также не упоминал массивы, но массивы имеют базовый тип, и нет смысла пытаться манипулировать массивами битов, потому что на самом деле нет типа бит C. И т. Д. Вы правы; как только вы переходите через альтернативы, довольно очевидно, что целые числа являются единственным реальным вариантом. –

0

Это как раз то, как определены битовые поля, они могут принимать только определенные (определенные) целые типы и интерпретироваться как целые значения.

С.11 § 6.7.2.1 ¶ 5:

битовое поле должно иметь тип, который является Quali фи-й издом или unquali версии изда из _Bool, signed int, unsigned int, или какого-либо других конкретной реализации, определяемого типа. Реализация - это определение того, разрешены ли атомные типы.

С.11 § 6.7.2.1 ¶ 10:

битовое поле интерпретируется как наличие знака или без знака целого числа типа, состоящий из Специфического ред числа бит. Если значение 0 или 1 сохраняется в бит-поле с ненулевой шириной типа _Bool, значение бит-поля должно сравниваться с сохраненным значением; a _Bool бит-поле имеет семантику _Bool.

Если вам интересно, как используется бит-поле, битовые поля обычно используются для создания меньшего типа, чем на основе. И, как следует из названия, ожидается, что «переменные» этого типа будут полезны для манипуляции бит. И битовые операции традиционно и интуитивно выполняются с целыми типами.

+0

Да, это всего лишь тавтология. Это целое число, потому что спецификация говорит о его целых числах. –

+0

@RobertHarvey: Я полагаю, что это так, но есть ли другой ответ, который не предполагает спекуляции? – jxh

+0

@RobertHarvey +1 для поиска хорошего места для использования «тавтологии».Тем не менее, разумно и убедительно (и утешительно) иногда ссылаться на стандарт, не так ли? – ryyker

3

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

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

В качестве примера, можно легко хранить 32 бита в целое число, и извлекать их, как так (с-подобный псевдокод):

int GetBit(int field, int position) 
{ 
    return field & 1 << position; 
} 

Если возвращаемое значение равно либо 1, либо 0, хранятся в одном целое число.

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

+0

Номера с плавающей запятой также имеют знаковый бит! –

+0

Итак? ............ –

+0

@CarlNorum - Остальные атрибуты плавающих точек, которые затруднят работу. Не будет ли утяжеление каждой позиции проблемой? – ryyker

1

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

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

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