4

この警告が表示されます。定義された動作が欲しいのですが、このコードをそのままにしておきたいです。エイリアシングルールに違反するのはいつですか?

警告:型のパンニングされたポインターを間接参照すると、厳密なエイリアスのルールが破られます[-Wstrict-aliasing]

文字列はPODである私自身の文字列です。このコードはCから呼び出されます。Sはintである可能性があります。文字列はほとんどですstruct String { RealString*s; }が、テンプレート化されたヘルパー関数です。Stringがポッドであり、4バイトであり、intが4バイトであることを確認するために、静的アサーションを実行します。また、すべてのポインターが>=NotAPtrであるかどうかをチェックするアサーションを作成しました。それは私の新しい/mallocオーバーロードにあります。あなたが提案するなら、私はそのアサーションを文字列に入れるかもしれません

私が従うルール(主に文字列はポッドであり、常にintと同じサイズです)を考慮すると、エイリアシングルールに違反しても問題ありませんか?これは、それを正しく破っている数少ない回数の1つですか?

void func(String s) {
    auto v=*(unsigned int*)&s;
    myassert(v);
    if(v < NotAPtr) {
        //v is an int
    }
    else{
        //v is a ptr
    }
}
4

4 に答える 4

4

memcpy完全にサポートされています。だからしゃれchar*です(たとえば、を使用できstd::copyます)。

于 2012-06-09T23:46:59.410 に答える
1

提案されているようにコードを2つの関数に変更できない場合は、理由を説明します(C99コンパイラを使用uintptr_tする必要があります。古いMSVCの場合は、自分で定義する必要があります。2008/ 2010で問題ありません)。

void f(RealString *s) {
    uintptr_t int = reinterpret_cast<uintptr_t>(s);
    assert(int);
}
于 2012-06-09T23:25:53.447 に答える
1

標準では、変換の制限に遭遇しない限り、すべての準拠する実装が予測可能な方法で処理する必要のある最小限のアクションのセットが指定されています(すべての賭けがオフになります)。特定の目的に適したものにするために実装がサポートしなければならないすべてのアクションを定義しようとするわけではありません。代わりに、義務付けられたものを超えるアクションのサポートは、実装の品質の問題として扱われます。著者は、実装が適合している可能性があるが、それでも役に立たないほど品質が悪い可能性があることを認めています。

あなたのようなコードは、低レベルのプログラミングを目的とした、メモリ内の物事を期待どおりに表現する高品質の実装に使用できる必要があります。「実装の品質」の問題を、品質は低いが準拠した方法で動作しようとする誘いとして解釈するものを含め、他の種類の実装で使用できると期待すべきではありません。

于 2018-07-13T19:42:48.567 に答える
-2

変数を2つの異なる型として扱う安全な方法は、変数を和集合に変えることです。和集合の一部はポインタ、他の部分は整数にすることができます。

struct String
{
    union
    {
        RealString*s;
        int i;
    };
};
于 2012-03-19T19:35:26.370 に答える