2

理由はわかりませんが、ビットフィールドの割り当てが期待どおりに機能していません。おそらく愚かなことですが、私は問題を見つけることができませんでした。

どんな助けでも大歓迎です。

typedef struct  a {
    unsigned char a1 :1;
    unsigned char a2 :3;
    unsigned char a3 :2;
    unsigned char a4 :2;
} __attribute__((packed)) mystruct;

int main() {
    mystruct d;
    d.a1 = 0;
    d.a2 = 2;
    d.a3 = 1;
    d.a4 = 2;

    unsigned char *val = (unsigned char*) &d;

    printf("%02X \n", *val);
    printf("%02X \n", sizeof(hola));

    exit(0);
}

返された出力:

94
01

期待される出力:

26
01
4

2 に答える 2

8

ビットフィールドに関するほぼすべてが実装定義です。特に、ユニット内のビットの順序。

(C99、6.7.2.1p10)「ユニット内のビットフィールドの割り当ての順序(高次から低次または低次から高次)は実装によって定義されます。」

実装では、ビットは最初に単位lsb(最下位ビット)に格納され、予想どおり最初にmsb(最上位ビット)ではありません。

あなたが持っているものは:

[a1.0] [a2.0] [a2.1] [a2.2] [a2.0] [a3.1] [a4.0] [a4.1] 
   0      0      1      0      1      0      0      1
 bit 0                     -                      bit 7

 lsb                       -                      msb

これは0x94、左端のビットが最下位ビットであると考える場合です。

于 2012-04-12T16:49:52.040 に答える
8

アスキーアート:

  MSB                                LSB
+----+----+----+----+----+----+----+----+
|a4.1|a4.0|a3.1|a3.0|a2.2|a2.1|a2.0| a1 |
+----+----+----+----+----+----+----+----+
| 1  | 0  | 0  | 1  | 0  | 1  | 0  | 0  |
+----+----+----+----+----+----+----+----+
|        0x9        |        0x4        |
+----+----+----+----+----+----+----+----+

前述のように、動作は実装によって定義されます。これは、データを整理する2つの正当な方法の1つであり、マシンで選択された形式のようです。別の動作はです。

  MSB                                LSB
+----+----+----+----+----+----+----+----+
| a1 |a2.2|a2.1|a2.0|a3.1|a3.0|a4.1|a4.0|
+----+----+----+----+----+----+----+----+
| 0  | 0  | 1  | 0  | 0  | 1  | 1  | 0  |
+----+----+----+----+----+----+----+----+
|        0x2        |        0x6        |
+----+----+----+----+----+----+----+----+

これは明らかにあなたが期待した振る舞いでした。

これは実装定義であるため、コンパイラはその動作を文書化する必要があるため、マニュアルを調べてコンパイラが何をするかを見つけることができます。

移植性について心配する必要がある場合は、使用する各プラットフォームで機能するために必要な方法で機能するように、構造定義をどのように編成するかを考える必要があります。

于 2012-04-12T18:13:50.503 に答える