私のプロジェクトに、これを含むサードパーティ ライブラリのヘッダーが含まれているとします。
struct foo {
signed int x:4;
};
ビットフィールドの幅が常に 4 であると仮定せずに、実装定義の動作に依存せずに、どのように member に格納できる最大値を決定できますx
か?
私のプロジェクトに、これを含むサードパーティ ライブラリのヘッダーが含まれているとします。
struct foo {
signed int x:4;
};
ビットフィールドの幅が常に 4 であると仮定せずに、実装定義の動作に依存せずに、どのように member に格納できる最大値を決定できますx
か?
ビットフィールドのサイズは で計算できないためsizeof
、次のことが役立ちます。
#include <stdio.h>
struct foo {
signed int x: 4;
};
#define BIT(n) (1l << (n))
#define BIT_MASK(len) (BIT(len) - 1)
int main(void)
{
struct foo f = {0};
long i = 0;
while (f.x >= 0) {
f.x = BIT_MASK(++i);
}
printf("bits=%ld max=%ld\n", i, BIT_MASK(i));
return 0;
}
左シフトまでf.x
は負です。
編集:
上記のコードは実装定義です。これを確認してください。これは機能すると思います (ただし、BIG ENDIAN を処理する必要があります)。
#include <stdio.h>
#include <string.h>
struct foo {
signed int x: 4;
};
#define BIT(n) (1l << (n))
#define BIT_MASK(len) (BIT(len) - 1)
int main(void)
{
long x, i = 0;
struct foo f;
f.x = -1;
memcpy(&x, &f, sizeof(f));
while (1) {
if (!(x & BIT(++i))) break;
}
printf("bits=%ld max=%ld\n", i, BIT_MASK(i));
return 0;
}
ご覧のとおり、 2^(n-1)-1を超えていません( で動作しますlong
)