C 中是否有 sizeof() 的位等效项?
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。
更新:
如果对于位域没有与 sizeof() 等效的语言,那么最有效的计算方法是什么 - 在运行时!想象一下,您有依赖于此的循环,并且您不希望它们在更改位字段的大小时中断 - 并且没有公平的作弊行为并将位字段大小和循环长度设置为宏。 ;-)
Sizeof() doesn't work when applied to bitfields:
# 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
...obviously, since it can't return a floating point partial size or something. However, it brought up an interesting question. Is there an equivalent, in C, that will tell you the number of bits in a variable/type? Ideally, it would also work for regular types as well, like char and int, in addition to bitfields.
Update:
If there's no language equivalent of sizeof() for bitfields, what is the most efficient way of calculating it - at runtime! Imagine you have loops that depend on this, and you don't want them to break if you change the size of the bitfield - and no fair cheating and making the bitfield size and the loop length a macro. ;-)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您无法确定 C 中位字段的大小。但是,您可以使用
中找到的
。以位为单位的大小就是CHAR_BIT
值找出其他类型的位大小;CHAR_BIT * sizeof(type)
。不要假设 C 字节是一个八位字节,它至少 8 位。实际机器有 16 位甚至 32 位字节。
关于您的编辑:
我想说,根据定义,位字段
int a: n;
的大小为 n 位。放入结构体中时的额外填充位属于该结构体,而不属于位字段。我的建议:不要使用位字段,而是使用
unsigned char
(数组)并使用位掩码。这样,很多行为(溢出、无填充)就得到了很好的定义。You cannot determine the size of bit-fields in C. You can, however, find out the size in bits of other types by using the value of
CHAR_BIT
, found in<limits.h>
. The size in bits is simplyCHAR_BIT * sizeof(type)
.Do not assume that a C byte is an octet, it is at least 8 bit. There are actual machines with 16 or even 32 bit bytes.
Concerning your edit:
I would say a bit-field
int a: n;
has a size of n bits by definition. The extra padding bits when put in a struct belong to the struct and not to the bit-field.My advice: Don't use bit-fields but use (arrays of)
unsigned char
and work with bitmasks. That way a lot of behaviour (overflow, no padding) is well defined.使用 sizeof() 不可能找到位域的大小。参考 C99:
6.5.3.4 The sizeof 运算符
,sizeof() 显然不支持位域6.7.2.1 结构和联合说明符
这里澄清了 bit-字段不是独立成员。否则,您可以尝试分配给位字段成员-1u(设置了所有位的值),然后找到最高有效位的索引。例如(未经测试):
man ffs
了解更多。It is impossible to find a size of bit-field using sizeof(). Refer to C99:
6.5.3.4 The sizeof operator
, bit-field is clearly not supported by sizeof()6.7.2.1 Structure and union specifiers
here it is clarified that bit-field isn't self standing member.Otherwise, you can try to assign to the bit-field member -1u (value with all bits set) and then find the index of the most significant bit. E.g. (untested):
man ffs
for more.我实现了这个解决方案[1]
$ gcc bitfieldtest.cpp && ./a.输出
偏移(宽度): r=0(5) g=5(6) b=11(5)
[1] https://twitter.com/suarezvictor/status/1477697986243272706
更新:
我确认这在编译时已解决:
汇编器输出:
I implemented this solution[1]
$ gcc bitfieldtest.cpp && ./a.out
offset(width): r=0(5) g=5(6) b=11(5)
[1] https://twitter.com/suarezvictor/status/1477697986243272706
UPDATE:
I confirmed this is solved at compile time:
Assembler output:
使用一组#define 语句来指定结构定义中的位宽,然后在打印或其他操作时使用相同的#define。
尽管您的位域大小定义确实弄乱了全局名称空间,但您会得到相同的“定义一次,使用多次”:
Use a set of #define statements to specify the bitwidths in the definition of the structure, and then use the same #define when printing, or whatever.
You get the same 'define once, use many times', albeit you do have the bitfield size definitions cluttering up your global name space: