簡體   English   中英

"C 中是否存在與 sizeof() 等效的位?"

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM