はい、これは機能しますが、偶然にすぎません。
私がC99標準を正しく思い出せば、この特定のケースは、期待どおりに機能するために特に必要です。しかし、これは、十分に多くの人々がそれ以前にそれが機能することに依存していたためであり、十分に多くの実装で偶然に機能したため、C99標準委員会は事実上だけでなく正当に機能することを法制化する義務があると感じたことは明らかです。
これが良い考えだと思わせないでください。
標準のエッジケースに依存するものはすべて、ハッキーに見え(したがって、コードの将来の読者を不快にさせます)、賢く見えます(これにより、何かを変更/修正することに神経質になります)。また、それは人々を仮定に導きます。あなたはすでに正当なものの端にいるので、国境を越えて人々を壊れたコードに誘惑する可能性があります。たとえば、構造体内の最初のサブ構造内の最初の要素が期待どおりに整列されているという事実は、他のサブ要素が整列していることを意味するものではありません。それがあなたのコンパイラで機能するという事実は、それが他の誰かのために機能することを意味するものではなく、気が遠くなるほど混乱するバグにつながります。
書く:
A *a = &(b->a);
(上記のコメントが示唆しているように)そしてあなたの意味は明らかです。
なんらかの理由でキャストB*
する必要がある場合は、必要なことを実行する以外に選択肢がない理由を説明する非常にA*
明確なコメントを書き、読者にそれが合法であることを保証し、C99標準のサブサブセクションを指し示します。ライセンスを取得します。
あなたが本当にそのサブセクションを見つけることができない(そしてそれがあなたの宿題/罰であると見つける)なら、このようにコメントしてください、そして私はそれを掘り下げます。