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

Есть ли бит-эквивалент sizeof() в C?

Sizeof() не работает при применении к битовым полям:

# cat p.c
  #include<stdio.h>
  int main( int argc, char **argv )
  {
    struct { unsigned int bitfield : 3; } s;
    fprintf( stdout, "size=%d\n", sizeof(s.bitfield) );
  }
# gcc p.c -o p
  p.c: In function ‘main’:
  p.c:5: error: ‘sizeof’ applied to a bit-field

... очевидно, поскольку он не может вернуть частичный размер с плавающей запятой или что-то еще. Однако это вызвало интересный вопрос. Есть ли эквивалент в C, который укажет вам количество бит в переменной/типе? В идеале он также будет работать и для обычных типов, таких как char и int, в дополнение к битовым полям.

Update:

Если для битовых полей нет языкового эквивалента sizeof(), что является наиболее эффективным способом его вычисления - во время выполнения! Представьте, что у вас есть петли, которые зависят от этого, и вы не хотите, чтобы они ломались, если вы изменили размер битового поля - и не справедливо обманывали и делали размер битового поля и длину цикла макросом.; -)

4b9b3361

Ответ 1

Вы не можете определить размер бит-полей в C. Однако вы можете узнать размер в битах других типов, используя значение CHAR_BIT, найденное в limits.h. Размер в битах - это просто CHAR_BIT * sizeof (type).

Не предполагайте, что байтом C является октет, он не менее 8 бит. Существуют реальные машины с 16 или даже 32-разрядными байтами.

Относительно вашего редактирования: Я бы сказал, что бит-поле int a: n; имеет размер n бит по определению. Дополнительные биты заполнения при вложении в структуру принадлежат структуре, а не битовому полю.

Мой совет: не используйте битовые поля, а используйте (массивы) unsigned char и работайте с битмаксами. Таким образом, хорошо определено поведение (переполнение, отсутствие заполнения).

Ответ 2

Невозможно найти размер битового поля с помощью sizeof(). См. C99:

  • 6.5.3.4 The sizeof operator, бит-поле явно не поддерживается sizeof()
  • 6.7.2.1 Structure and union specifiers здесь поясняется, что битовое поле не является самостоятельным членом.

В противном случае вы можете попытаться назначить члену бит-поля -1u (значение со всеми установленными битами), а затем найти индекс самого значимого бита. Например. (Непроверенные):

s.bitfield = -1u;
num_bits = ffs(s.bitfield+1)-1;

man ffs для более.