简短版本是:如何学习c ++字段的单个字段的大小(以位为单位)?
澄清一下我所谈论的领域的一个例子:
struct Test {
unsigned field1 : 4; // takes up 4 bits
unsigned field2 : 8; // 8 bits
unsigned field3 : 1; // 1 bit
unsigned field4 : 3; // 3 bits
unsigned field5 : 16; // 16 more to make it a 32 bit struct
int normal_member; // normal struct variable member, 4 bytes on my system
};
Test t;
t.field1 = 1;
t.field2 = 5;
// etc.
要获得整个Test对象的大小很简单,我们只需说明
sizeof(Test); // returns 8, for 8 bytes total size
我们可以通过
获得一个普通的struct成员sizeof(((Test*)0)->normal_member); // returns 4 (on my system)
我想知道如何获得单个字段的大小,比如Test :: field4。上面的普通struct成员示例不起作用。有任何想法吗?或者有人知道它无法工作的原因吗?我相信sizeof不会有任何帮助,因为它只返回大小的字节数,但如果有人知道,我就是全部的耳朵。
谢谢!
答案 0 :(得分:10)
您可以在运行时计算大小,fwiw,例如:
//instantiate
Test t;
//fill all bits in the field
t.field1 = ~0;
//extract to unsigned integer
unsigned int i = t.field1;
... TODO use contents of i to calculate the bit-width of the field ...
答案 1 :(得分:5)
您无法取sizeof
位域并获取位数。
您最好的选择是使用#define
s或enum
s:
struct Test {
enum Sizes {
sizeof_field1 = 4,
sizeof_field2 = 8,
sizeof_field3 = 1,
sizeof_field4 = 3,
sizeof_field5 = 16,
};
unsigned field1 : sizeof_field1; // takes up 4 bits
unsigned field2 : sizeof_field2; // 8 bits
unsigned field3 : sizeof_field3; // 1 bit
unsigned field4 : sizeof_field4; // 3 bits
unsigned field5 : sizeof_field5; // 16 more to make it a 32 bit struct
int normal_member; // normal struct variable member, 4 bytes on my system
};
printf("%d\n", Test::sizeof_field1); // prints 4
为了保持一致性,我相信您可以将normal_member
移至顶部并使用Sizes
在sizeof(normal_member)
中添加条目。但这会使您的数据顺序混乱。
答案 2 :(得分:3)
答案 3 :(得分:2)
使用ChrisW's idea(很好,顺便说一下),你可以创建一个辅助宏:
#define SIZEOF_BITFIELD(class,member,out) { \
class tmp_; \
tmp_.member = ~0; \
unsigned int tmp2_ = tmp_.member; \
++tmp2_; \
out = log2(tmp2_); \
}
unsigned int log2(unsigned int x) {
// Overflow occured.
if(!x) {
return sizeof(unsigned int) * CHAR_BIT;
}
// Some bit twiddling... Exploiting the fact that floats use base 2 and store the exponent. Assumes 32-bit IEEE.
float f = (float)x;
return (*(unsigned int *)&f >> 23) - 0x7f;
}
用法:
size_t size;
SIZEOF_BITFIELD(Test, field1, size); // Class of the field, field itself, output variable.
printf("%d\n", size); // Prints 4.
我尝试使用模板化功能失败了。但是,我不是模板方面的专家,所以可能仍然可以使用干净的方法(例如sizeof_bitfield(Test::field1)
)。
答案 4 :(得分:1)
这是不可能的
回答评论: 因为类型只是一个int,所以没有'bit'类型。位字段赋值语法只是执行读写的按位代码的简写。
答案 5 :(得分:1)
我认为你不能这样做。如果确实需要大小,我建议您使用#define
(或者,更好的是,如果可能的话,const
变量 - 我不确定这是否合法)如此:
#define TEST_FIELD1_SIZE 4
struct Test {
unsigned field1 : TEST_FIELD1_SIZE;
...
}