20

C 構造体のレイアウトには一定の保証があるという事実に基づいて、ある型を別の型にキャストすることは C の一般的な戦略です。GLib などのライブラリは、オブジェクト指向のような継承を実装するためにこれに依存しています。基本的:

struct Base
{
  int x;
  int y;
};

struct Derived
{
  struct Base b;
  int z;
};

これにより、Base*ポインタをオブジェクトのアドレスに割り当てることができDerivedます。

しかし、「厳密なエイリアシング」規則も認識しています。これは、異なる型のポインターが同じアドレスを指すことはできないというコンパイラーによる暗黙の仮定です。(これにより、コンパイラは特定の最適化を実行できます。)

では、この 2 つのことはどのように調和しているのでしょうか。Glib、CPython などを含む多くの C ライブラリは、上記の戦略を使用して型間のキャストを行います。それらはすべて、単に次のようなフラグでコンパイルされていno-strict-aliasingますか?

4

1 に答える 1

21

この場合、厳密なエイリアシングに違反することはありません。 struct Derived が含まれていstruct Baseます。この種の動作は、言語標準によって明示的に許可されています。C11 6.7.2.1 Structure and union specifiers、段落 15 から:

適切に変換された構造体オブジェクトへのポインターは、その最初のメンバー (または、そのメンバーがビットフィールドの場合は、それが存在するユニット) を指し、その逆も同様です。

于 2013-09-25T17:03:54.037 に答える