C言語関係掲示板

過去ログ

No.1316 ビットフィールド

[戻る] [ホームページ]
No.17718

ビットフィールド
投稿者---C言語新米(2004/11/02 12:43:20)


typedef struct _mksectinfo{
  union {
UCHAR sectbuf[32];
struct {
UCHAR asic_amod : 1;
UCHAR asic_cmod : 1;
UCHAR asic_alst : 1;
UCHAR asic_fe : 1;
UCHAR asic_acea : 1;
UCHAR asic_ek : 1;
UINT16 asic_acsa : 9;
UINT16 asic_acla : 9;
UCHAR asic_fr : 8;
ULONG asic_ky_h : 32;
ULONG asic_ky_l : 32;

UCHAR acore_acfs : 1;
UCHAR acore_acfe : 1;
UCHAR acore_acea : 1;
UCHAR acore_dmy1 : 1;
UCHAR acore_acen : 1;
UCHAR acore_acec : 1;
UCHAR acore_acbc : 1;
UCHAR acore_hsec : 1;
UCHAR acore_dmy2 : 7;
UCHAR acore_acsa : 9;
UCHAR acore_dmy3 : 7;
UCHAR acore_acla : 9;
UINT32 acore_acns : 24;
UINT16 acore_acid : 16;
UINT32 acore_acfc : 24;

UCHAR micon_acm1 : 8;
UCHAR micon_acm2 : 8;
UCHAR micon_acm3 : 8;
UCHAR micon_acm4 : 8;
UCHAR micon_acm5 : 8;
UCHAR micon_acm6 : 8;
UCHAR micon_acm7 : 8;
}bit;
  }sect;
}ACI_MKSECTINFO;

このビットフィールド定義で UCHAR sectbuf[32]の領域に格納されますでしょうか?
UINT16 asic_acsaはUCHARの配列にまたがってしまうんですが。


No.17720

Re:ビットフィールド
投稿者---επιστημη(2004/11/02 13:13:42)


>このビットフィールド定義で UCHAR sectbuf[32]の領域に格納されますでしょうか?
>UINT16 asic_acsaはUCHARの配列にまたがってしまうんですが。

sizeofの結果はどうなりますか?
# 訊くことじゃない。やってみることだ。



No.17722

Re:ビットフィールド
投稿者---tetrapod(2004/11/02 14:28:22)


bitfield がどんな順に生成されるかは処理系定義 (ISO/IEC14882:1998 9.6) なので
MSB->LSB の順に生成されても LSB->MSB の順に生成されても、どちらでも正しく、
また境界をまたがるような bitfield がどう生成されても正しいのです。

手元の gcc では sizeof が 40 になりました。
同じく vc++6.0 ではコンパイルエラー
bcc5.5.1 では 44
某社の某 CPU 向けコンパイラではコンパイルエラー
です。

ビットフィールドを使うとコンパイラ間での互換性が皆無になるので個人的には絶対に使いません。
組み込み系では好んで使う人が多いようですが、最初に選んだコンパイラと心中することになりがちです。

# 9bit のビットフィールド使おうなんて設計悪いよ...



No.17723

Re:ビットフィールド
投稿者---Hermit(2004/11/02 14:28:54)


>このビットフィールド定義で UCHAR sectbuf[32]の領域に格納されますでしょうか?

無理です。

>UINT16 asic_acsaはUCHARの配列にまたがってしまうんですが。

そのあたりを、UINT32 にしてはどうでしょうか。
それでも、32byte にはおさまりませんが。

指定サイズをまたがるようなメンバーは、そのまま次のエリアに
移行しますので、収まるように書かないと無理です。

UCHAR は、8bit ですよね、多分
9bit の指定のところがありますが・・・

昔の ANSI C の規格では、ビットフィールドのメンバーは、
int か、unsigned int だけだったと思うのですが・・・
(今のは知らない)
まあ、ほとんどのコンパイラは、他の型も出来るから
問題ないかな?


No.17726

Re:ビットフィールド
投稿者---かずま(2004/11/02 16:34:55)


> このビットフィールド定義で UCHAR sectbuf[32]の領域に格納されますでしょうか?
> UINT16 asic_acsaはUCHARの配列にまたがってしまうんですが。

asic_acsa ではなく、acore_acla : 9 と acore_acfc : 24 とが 32ビット
境界を跨ぎますから、次のようにすると、全体で 32バイトになります。
typedef unsigned char UCHAR;
typedef unsigned long ULONG;

typedef struct _mksectinfo{
    union {
        UCHAR sectbuf[32];

        struct {
            ULONG asic_amod  : 1;
            ULONG asic_cmod  : 1;
            ULONG asic_alst  : 1;
            ULONG asic_fe    : 1;
            ULONG asic_acea  : 1;
            ULONG asic_ek    : 1;
            ULONG asic_acsa  : 9;
            ULONG asic_acla  : 9;
            ULONG asic_fr    : 8;

            ULONG asic_ky_h  : 32;

            ULONG asic_ky_l  : 32;

            ULONG acore_acfs : 1;
            ULONG acore_acfe : 1;
            ULONG acore_acea : 1;
            ULONG acore_dmy1 : 1;
            ULONG acore_acen : 1;
            ULONG acore_acec : 1;
            ULONG acore_acbc : 1;
            ULONG acore_hsec : 1;
            ULONG acore_dmy2 : 7;
            ULONG acore_acsa : 9;
            ULONG acore_dmy3 : 7;
            ULONG acore_acla_1 : 1;  /****/

            ULONG acore_acla_2 : 8;  /****/
            ULONG acore_acns : 24;

            ULONG acore_acid : 16;
            ULONG acore_acfc_1 : 16; /****/

            ULONG acore_acfc_2 : 8;  /****/
            ULONG micon_acm1 : 8;
            ULONG micon_acm2 : 8;
            ULONG micon_acm3 : 8;

            ULONG micon_acm4 : 8;
            ULONG micon_acm5 : 8;
            ULONG micon_acm6 : 8;
            ULONG micon_acm7 : 8;
        } bit;
    } sect;
} ACI_MKSECTINFO;

int main(void)
{
    printf("sizeof(ACI_MKSECTINFO) = %d\n", sizeof(ACI_MKSECTINFO));
    return 0;
}