[英]Is there a bit-equivalent of sizeof() in 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中位字段的大小。但是,您可以使用limits.h中的CHAR_BIT
值來查找其他類型的位大小。 位大小只是CHAR_BIT
* sizeof(類型)。
不要假設C字節是八位字節,它至少是 8位。 實際的機器有16位甚至32位字節。
關於你的編輯:我會說一個位字段int a: n;
根據定義,其大小為n位。 放入struct時的額外填充位屬於struct而不屬於bit-field。
我的建議:不要使用位字段,而是使用(數組) unsigned char
並使用位掩碼。 這樣很好地定義了很多行為(溢出,沒有填充)。
使用sizeof()找不到位字段的大小是不可能的。 參見C99:
6.5.3.4 The sizeof operator
sizeof()顯然不支持6.5.3.4 The sizeof operator
,位字段 6.7.2.1 Structure and union specifiers
這里的6.7.2.1 Structure and union specifiers
澄清了位字段不是自立6.7.2.1 Structure and union specifiers
成員。 否則,您可以嘗試分配位字段成員-1u(設置了所有位的值),然后找到最高位的索引。 例如(未經測試):
s.bitfield = -1u;
num_bits = ffs(s.bitfield+1)-1;
man ffs
更多。
我實施了這個解決方案[1]
#include <stdio.h>
#define bitoffsetof(t, f) \
({ union { unsigned long long raw; t typ; }; \
raw = 0; ++typ.f; __builtin_ctzll(raw); })
#define bitsizeof(t, f) \
({ union { unsigned long long raw; t typ; }; \
raw = 0; --typ.f; 8*sizeof(raw)-__builtin_clzll(raw)\
-__builtin_ctzll(raw); })
struct RGB565 { unsigned short r:5, g:6, b:5; };
int main()
{
printf("offset(width): r=%d(%d) g=%d(%d) b=%d(%d)\n",
bitoffsetof(RGB565, r), bitsizeof(RGB565, r),
bitoffsetof(RGB565, g), bitsizeof(RGB565, g),
bitoffsetof(RGB565, b), bitsizeof(RGB565, b));
}
$ gcc bitfieldtest.cpp && ./a.out
偏移量(寬度):r=0(5) g=5(6) b=11(5)
[1] https://twitter.com/suarezvictor/status/1477697986243272706
使用一組#define 語句來指定結構定義中的位寬,然后在打印時使用相同的#define 或其他。
您會得到相同的“定義一次,多次使用”,盡管您的位域大小定義會弄亂您的全局名稱空間:
# cat p.c
#include<stdio.h>
int main( int argc, char **argv )
{
#define bitfield_sz 3
struct { unsigned int bitfield : bitfield_sz; } s;
fprintf( stdout, "size=%d\n", bitfield_sz );
}
# gcc p.c -o p
# ./p
size=3
#
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.