まず、エイリアシング違反の警告が表示される理由を調べてみましょう。
エイリアシング ルールchar
は、オブジェクト自体の型、符号付き/符号なしバリアント型、または文字型 ( 、signed char
、 )を介してのみオブジェクトにアクセスできることを示していますunsigned char
。
C は、エイリアシング規則に違反すると、未定義の動作が呼び出されると言います (そうしないでください! )。
プログラムの次の行で:
unsigned int received_size = ntohl (*((unsigned int*)dcc->incoming_buf));
incoming_buf
配列の要素は型char
ですが、としてアクセスしていunsigned int
ます。実際、式の逆参照演算子の結果は*((unsigned int*)dcc->incoming_buf)
型unsigned int
です。
これはエイリアシング ルールに違反しています。なぜなら、incoming_buf
配列の要素にアクセスする権利は (上記のルールの概要を参照してください! char
)signed char
またはunsigned char
.
2 番目の犯人にもまったく同じエイリアシングの問題があることに注意してください。
*((unsigned int*)dcc->outgoing_buf) = htonl (dcc->file_confirm_offset);
throughのchar
要素にアクセスするため、エイリアシング違反です。outgoing_buf
unsigned int
提案された解決策
問題を解決するには、アクセスしたい型で配列の要素を直接定義してみてください。
unsigned int incoming_buf[LIBIRC_DCC_BUFFER_SIZE / sizeof (unsigned int)];
unsigned int outgoing_buf[LIBIRC_DCC_BUFFER_SIZE / sizeof (unsigned int)];
(ちなみに、の幅unsigned int
は実装定義なので、プログラムが 32 ビットであるuint32_t
と想定している場合は、使用を検討する必要があります)。unsigned int
このようにして、次のようunsigned int
に type を介して要素にアクセスすることで、エイリアシング規則に違反することなくオブジェクトを配列に格納できます。char
*((char *) outgoing_buf) = expr_of_type_char;
また
char_lvalue = *((char *) incoming_buf);
編集:
特に、プログラムがコンパイラからエイリアシング警告を受け取る理由を説明します。