11

addr が sockaddr* である、次のようなコードがあります。

struct sockaddr_in *sin = (struct sockaddr_in *) addr;
const char *IP=inet_ntoa(sin -> sin_addr);

これは、Berkeley ソケットを使用するための非常に典型的なコードだと思います。

ただし、これをコンパイルすると、次の警告が表示されます。
dereferencing pointer 'sin' does break strict anti-aliasing rules

オンラインで検索すると、私のやり方がかなり典型的であるという事実についての議論がいくつか見つかりますが、このコンパイラの警告もかなり現実的であり、良いことではありません。

警告を黙らせるだけでなく、警告を修正するためにこのコードをやり直す適切な方法は何ですか?

4

4 に答える 4

2

はい、これは gcc とソケットの既知の問題です。問題は基本的に、この ip[46] の設計方法が、gcc の人々がポインターのエイリアシングについて推測できると考えている仮定と互換性がないことです。

私は通常、最初にポインターを取得することでこれを回避しますstruct

struct in_addr* act = &(sin->sin_addr);

を使用し*actます。

于 2010-08-12T07:09:02.163 に答える
1

の使い方によってはstruct sockaddr、コードが壊れているか、gcc が壊れていると思います。共通の初期要素 ( / )struct sockaddrを持つため、両方のポインターを介してこの要素のみにアクセスした場合、エイリアシング規則に違反しません。そうすることは、C99 で許可されています。さらに、アクセスを許可されている他の要素はありません。これは主に、プリミティブ ソケット アドレス ポリモーフィズムの不透明な型です。の実装固有の内部をいじっていた場合、またはさらに悪いことに、宣言した場合struct sockaddr_insa_familysin_familystruct sockaddrstruct sockaddrstruct sockaddr単なるポインターではなく、オブジェクト間でコピーを実行すると、コードが壊れます。そうではなく、gcc がエイリアシング規則に違反していると主張する警告を出している場合は、gcc の警告生成が壊れています。後者だったとしても不思議ではない。

于 2010-08-12T05:54:26.433 に答える
-2

ヘッダー ファイルとコンパイラが両方とも同じ C または C++ 実装の一部である場合は、ベンダーに苦情を申し立て、ヘッダー ファイルに適切な #pragma を入れてコンパイラを沈黙させるように依頼してください。実装者として、適合する実装を提供する限り、そのようなゲームをプレイすることが許可されています。

ヘッダー ファイルとコンパイラが 2 つの別個の C または C++ 実装から作成されたものである場合、それらが正常に機能することは幸運であり、自分で解決する必要があります。

于 2010-08-12T05:29:44.387 に答える