c - 厳格なエイリアシングを破った結果を理解する

原文 c struct unions strict-aliasing

int main()
{
    struct { int x; } foo;

    dostuff(&foo);
    return 0;
}

void dostuff(void *ptr)
{
    struct { int x; } *p = ptr;

    p->x = 5;
}


pの逆参照は、2つの名前のない構造体に互換性がないため互いにエイリアスを設定できないため、厳密なエイリアス違反です。
このようなコードでどのような問題が発生する可能性がありますか?

編集:
彼らは同じタグを持っていないので、私はまだこの定義された動作かどうかわかりません。

互換性がないと仮定すると、次の点で違いはありますか?

union u {
    void *v;
    struct {
        int x;
    } *p;
};

void dostuff(void *ptr)
{
    union u tmp = {.v = ptr};

    tmp.p->x = 5;
}
答え
奇妙な|奇妙な|驚くべき|逆説的なように見えるかもしれませんが、eで述べたように、1つの翻訳単位内のstruct { int x; }struct { int x; }は実際には同じ型ではないと宣言します。 g。 this comment


以下は何か違いがありますか?

union u {
    void *v;
    struct {
        int x;
    } *p;
};

void dostuff(void *ptr)
{
    union u tmp = {.v = ptr};

    tmp.p->x = 5;
}



ここではdostuff()の呼び出し方法を指定しなかったため、最初の例と同じmain()が必要です。このため、引数が同じ変換単位で宣言されている場合、型は依然として互換性がありません。構造体型の2つの宣言は、共用体に含まれている型に関係なく、異なる型を宣言します。
さらに、この2番目のバージョンのdostuff()void *vstruct … *pとして再解釈します。 C標準では、voidへのポインターが構造体型へのポインターと同じ表現を持つことは保証されていないため、この使用法は厳密に準拠していません。
関連記事

java - Android Gstreamer SDKでANativeWindow_lockがエラー-22を返す

c - 二分木;頻度の高い順に印刷します。 C言語

c - コピーを作成するのではなく、ポインタを使い始める前に、構造はどのくらいの大きさにすべきですか? [C] [終了]

c - Cの配列で2次元配列にインデックスを付ける方法のベクトル化

c - 複数の構造体を宣言し、それらをすでに割り当てられているメモリにオーバーレイする

c++ - ゼロパディング付きのインテルMKLを使用した3D FFT

python - プロセス間通信Python [重複]

c - C99で関数ポインターの構造がNULLかどうかを確認するクイックチェック

c - 構造体を関数に渡し、Cで変更する

c - EVP_PKEYを使用したOpenSSL RSA_size