2016-06-18 9 views
0
#include "stdio.h" 


/* array to store data receeived from CAN Bus */ 
unsigned char a[8] = {0xCD, 0xEF, 0x12, 0x34, 0x50, 0x00, 0x00, 0x00}; 

typedef struct { 
    unsigned int a:12; 
    unsigned int b:12; 
    unsigned int c:12; 
    unsigned int unused:28; 
}test; 

test *tptr; 

int main(void) 
{ 

    tptr = (test*)((void*)&a); // is this line braking any aliasing rule 

    if(tptr->a == 0xCDE) 
    { 
     printf("\n data received ok"); 

    } 

    return 0; 
} 

私は最近、Cでのポインタのエイリアシングに起因する問題について学びました。私は、上記のコードがルールを破っているかどうかを知りたいと思います。それは問題につながるだろうか?struct aliasへのポインタを符号なしchar配列にできますか?

ビットフィールドの順序はマシンと実装に依存することがわかります。私の質問は、より明確に理解したいポインタエイリアシングルールです。

+0

これはクイズサイトではありません。なぜそれはないと思いますか? – Olaf

+0

'#include" stdio.h "'は珍しいです。なぜ#include 'を使用していないのですか? – melpomene

+2

エイリアスについてはわかりませんが、 'tptr = ...'行には未定義の動作があることは間違いありません。まず、 'B x; (A *)(void *)&x'は賢明なことを保証していません(あなたは 'void *'から元の型 'B *'に変換できることのみが保証されています)。第二に、たとえそれが機能しても、構造体は位置合わせの要件を持つことがあります。 – melpomene

答えて

0

厳密なエイリアシングが解除されます。一部の(saner)コンパイラは、aのエイリアスを許可する必要があることを明らかにしていると推測していますが、これは標準によって保証されていません。実際、GCCはtptrを別名aとみなさないでしょう。

もう1つの問題は、アライメントaです。その点でx86はかなり寛容ですが、ARMを含む他の多くのアーキテクチャはそうではありません。

sizeof(int)の倍数であるアドレスからのみintをフェッチすることをサポートするアーキテクチャでは、(int)&a == 0xFFF02およびsizeof(int) == 4を考慮してください。 このようなunaligned accessは、*(int*)&aを実行した場合、または間違った場所にアクセスしているプログラムが悪化した場合、バスエラーが発生します。

定義されていない動作を避けるためには、アラインメントやエイリアシングの制約なしに、unsigned char*からのアクセスが可能であることが保証されています。このように使用します。

test buf; 
can_recv((unsigned char*)&buf, sizeof buf); 
if(tptr->a == 0xCDE) 
{ 
    printf("\n data received ok"); 

} 

を別の移植性の問題は、あなたがそのビットフィールドは、特定の方法で梱包されることを期待ということです。 The standard doesn't guarantee that however。移植性のある動作が必要な場合は、ビットフィールドインターフェイス(bitfield.b1 = 1)に自分自身を制限し、他の手段でビットビットを変更しないでください。

移植性が問題でない場合は、期待しているビットフィールドのパッキングを保証する適切なコンパイラフラグを設定してください。

+1

私は、すべてのsane *コンパイラが、明示的にポインタをキャストする行為は、型キャストポインタで行われたすべてのアクセスが、次のアクセスの前に外側のタイプ。その根拠は、コンパイラがエイリアシングを期待する理由がないポインタに関してルールを記述します。コンパイラがエイリアシングの明白で明白な兆候を無視することを示唆しているという証拠は見当たらなかった。標準の作成者はそれが明らかであると思われる可能性が高いと主張した。 – supercat

関連する問題