いくつかのフレーム構造に取り組んでいるうちに、私は奇妙な動作に出くわしました。 は、私はすぐに次のように、独立したサンプルコードでそれをテスト:奇妙な構造体のパッキング
struct non_alligned_struct
{
uint8_t flag;
// start of uint32 bit fields
uint32_t a:2;
uint32_t b:2;
uint32_t c:1;
uint32_t d:1;
uint32_t e:1;
uint32_t f:1;
uint32_t g:3;
uint32_t h:1;
uint32_t i:1;
uint32_t j:3;
uint32_t k:3;
uint32_t l:1;
uint32_t m:1;
uint32_t n:1;
uint32_t o:1;
uint32_t p:3;
uint32_t q:2;
uint32_t r:1;
uint32_t s:1;
uint32_t t:2;
//4 bytes ends here
// shouldn't this start at 5th byte ??
uint16_t u;
uint16_t v:13;
uint16_t w:3;
uint16_t x;
uint16_t y:13;
uint16_t z:3;
};
int main()
{
struct non_alligned_struct obj1;
void *ptr1 = &obj1;
void *ptr2 = &(obj1.u);
printf("ptr1: %p, ptr2: %p, ptr2 - ptr1: %d\n", ptr1, ptr2, ptr2 - ptr1);
return 0;
}
出力: PTR1:0x7fff3216a620、PTR2:0x7fff3216a626、PTR2 - PTR1:6
質問:PTR2なぜ - PTR1は6でなければなりません。私の計算によると、5になっているはずです。また、構造体は13バイトなので、4バイトの位置合わせができ、パディングは奇妙な方法で行われます。 Iは、メンバ変数にランダムな値を与えることによって確認し、私は、パディングは、以下太字場所
00000000で行われることを観察:01 22 31 10 67 FE FF 86 01 FE FF 86 01
ptr2-ptr1は6になります... – DigitalNinja
MSVCでは、 'struct'を '#pragma pack(push、1)'と '#pragma pack(pop)'で囲むと、そうでなければ「8」である。 void *型のポインタ算術は実装定義のため、 'void *'ポインタを 'char *'に変更しなければなりませんでした。 –
制約違反が 'void *' sの算術演算をしています。あなたのコンパイラは、このエラーの診断を出す義務がありました。 – EOF