Есть ли бит-эквивалент 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(), что является наиболее эффективным способом его вычисления - во время выполнения! Представьте, что у вас есть петли, которые зависят от этого, и вы не хотите, чтобы они ломались, если вы изменили размер битового поля - и не справедливо обманывали и делали размер битового поля и длину цикла макросом.; -)
Ответы
Ответ 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
для более.