1

32 ビット マネージド アプリケーションを 64 ビットに移植しているときに、構造体内の Equals() オーバーライドによる奇妙な動作を観察しました。

再現ファイルはgithubにあります。

バグを再現するには、「最適化」フラグをオンにしてライブラリをコンパイルする必要があります。これは、リリース構成のデフォルトです。消費する TestApp は、最適化せずにコンパイルする必要があります。64 ビット アプリとして起動するには、Prefer 32 ビットを無効にする必要があります。github の注意事項を参照してください。

ライブラリには、単純なコード行で実装される IEquatable インターフェイスを実装する構造体が含まれています。

    public bool Equals(StructWithValue other)
    {
        return value.Equals(other.value);
    }

このコードは、ushort/UInt16 型の Equals メソッドを呼び出します。提案された構成でソリューションをビルドすると、32767 を超える値はすべて失敗します。32768 の ushort 値で Equal を呼び出し、'other' の値も 32768 です。ただし、Equals() は 32767 を超えるすべての値に対して false を返します。

「==」演算子を使用するようにメソッドを変更すると、コードは機能します。また、タイプを構造体からクラスに変更すると、コードは期待どおりに実行されます。

    public bool Equals(StructWithValue other)
    {
        return value == othervalue;
    }

これは RyuJIT-Compiler のバグだと思います。従来の JIT コンパイラを使用すると、コードは正常に動作します。

Visual Studio 2015 と TargetFramework 4.6.2 のさまざまな Windows バージョンでテスト済み。

4

1 に答える 1

1

検品でバグを確認。

ここに他にどのような答えが現れるか想像できません。バグが非現実的である場合、コードのどこが間違っているかを示す回答が得られますが、コードは間違っていません。

于 2016-12-18T21:21:00.420 に答える