[英]Size of a bitfield member?
有誰知道如何提取位域成員的大小。 下面的代碼自然給了我一個整數的大小,但我如何找出mybits.one
有多少位或字節? 我試過sizeof(test.one)
但顯然行不通。 我意識到這是位的度量:
#include <iostream>
using namespace std;
int main()
{
struct mybits {
unsigned int one:15;
};
mybits test;
test.one = 455;
cout << test.one << endl;
cout << "The size of test.one is: " << sizeof(test) << endl;
}
C++ 標准草案規定sizeof 不應應用於第5.3.3
節Sizeof第1節中的位字段。 如果您可以控制源,那么使用枚舉聽起來更簡單和整潔:
struct mybits
{
enum bitFieldSizes
{
field1 = 15,
field2 = 2,
field3 = 4,
field4 = 8,
field5 = 31
};
unsigned int one : field1 ;
unsigned int two : field2 ;
unsigned int three : field3 ;
unsigned int four : field4 ;
unsigned int five : field5 ;
};
如果您無法控制源代碼,則可以使用 bit hacks 來獲取位域的大小,而std::bitset則可以更輕松:
#include <iostream>
#include <bitset>
struct mybits
{
unsigned int one : 15 ;
unsigned int two : 2 ;
unsigned int three : 4 ;
unsigned int four : 8 ;
unsigned int five : 31 ;
};
int main()
{
mybits mb1 ;
mb1.one = ~0 ;
mb1.two = ~0 ;
mb1.three = ~0 ;
mb1.four = ~0 ;
mb1.five = ~0 ;
std::bitset<sizeof(unsigned int)*8> b1(mb1.one);
std::bitset<sizeof(unsigned int)*8> b2(mb1.two);
std::bitset<sizeof(unsigned int)*8> b3(mb1.three);
std::bitset<sizeof(unsigned int)*8> b4(mb1.four);
std::bitset<sizeof(unsigned int)*8> b5(mb1.five);
std::cout << b1 << ":" << b1.count() << std::endl ;
std::cout << b2 << ":" << b2.count() << std::endl ;
std::cout << b3 << ":" << b3.count() << std::endl ;
std::cout << b4 << ":" << b4.count() << std::endl ;
std::cout << b5 << ":" << b5.count() << std::endl ;
}
產生以下輸出:
00000000000000000111111111111111:15
00000000000000000000000000000011:2
00000000000000000000000000001111:4
00000000000000000000000011111111:8
01111111111111111111111111111111:31
運行時解決方案,這個討論的想法: http : //social.msdn.microsoft.com/Forums/en-US/7e4f01b6-2e93-4acc-ac6a-b994702e7b66/finding-size-of-bitfield
#include <iostream>
using namespace std;
int BitCount(unsigned int value)
{
int result = 0;
while(value)
{
value &= (value - 1);
++result;
}
return result;
}
int main()
{
struct mybits {
unsigned int one:15;
};
mybits test;
test.one = ~0;
cout << BitCount(test.one) << endl;
return 0;
}
打印 15。
由於填充,無法使用 sizeof 運算符查看位字段中的位數。
唯一的方法是打開定義結構的標題,並查找它。
沒有辦法獲得這些信息(除了自己閱讀聲明)。 根據標准[C++11]expr.sizeof§1
,在位域上調用sizeof
是非法的:
sizeof 運算符不應應用於...指定位字段的左值。
使用constexpr
編譯時解決方案:
struct S
{
unsigned int a : 4;
unsigned int b : 28;
};
#define GET_BIT_FIELD_WIDTH(T, f) \
[]() constexpr -> unsigned int \
{ \
T t{}; \
t.f = ~0; \
unsigned int bitCount = 0; \
while (t.f != 0) \
{ \
t.f >>= 1; \
++bitCount; \
} \
return bitCount; \
}()
int main()
{
constexpr auto a = GET_BIT_FIELD_WIDTH(S, a);
constexpr auto b = GET_BIT_FIELD_WIDTH(S, b);
static_assert(a == 4);
static_assert(b == 28);
}
我認為它不會調用任何未定義的行為,但它確實會調用一些實現定義的行為:
這是一個有點棘手的通用版本:
#include <iostream>
#include <limits>
#include <bitset>
#include <cstring>
using namespace std;
template <class T>
T umaxof()
{
T t;
memset(&t, 0xFF, sizeof(T));
return t;
}
template <class T>
size_t bitsof(const T& umax)
{
return bitset<sizeof(T)*8>(umax).count();
}
int main()
{
struct A
{
uint32_t bf1:19;
uint32_t bf2:1;
};
cout << bitsof(umaxof<A>().bf1) << "\n";
cout << bitsof(umaxof<A>().bf2) << "\n";
return 0;
}
可以在https://ideone.com/v4BiBH上試用
注意:僅適用於無符號位字段。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.