5

短いバージョンは次のとおりです。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

通常の構造体メンバーを取得できます

sizeof(((Test*)0)->normal_member); // returns 4 (on my system)

Test::field4 など、個々のフィールドのサイズを取得する方法を知りたいです。上記の通常の構造体メンバーの例は機能しません。何か案は?または、誰かがそれが機能しない理由を知っていますか? sizeof はサイズをバイト単位で返すだけなので、役に立たないことはかなり確信していますが、それ以外のことを知っている人がいれば、私はすべて耳を傾けます。

ありがとう!

4

6 に答える 6

3

ChrisWのアイデア(ちなみに素晴らしい) を使用して、ヘルパー マクロを作成できます。

#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)

于 2009-02-12T00:54:12.360 に答える