RyuJIT - ошибка с переопределением ushort и Equals (64 бита)

При портировании 32-битного управляемого приложения на 64-битное я наблюдал странное поведение переопределения Equals() внутри структуры.

Вы найдете репродукцию на github.

Чтобы воспроизвести ошибку, вы должны скомпилировать библиотеку с включенным флагом "оптимизировать". Это по умолчанию в конфигурации выпуска. Потребляющий TestApp должен быть скомпилирован без какой-либо оптимизации. Предпочитаю 32-битная должна быть отключена, чтобы начать как 64-битное приложение Смотрите заметки на GitHub!

Библиотека содержит структуру, которая реализует интерфейс IEquatable, который реализуется с помощью простой строки кода.

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

Этот код вызывает метод Equals типа ushort/UInt16. Если вы строите решение с предложенной конфигурацией, все значения выше 32767 не будут выполнены. Вы вызываете Equal для ushort-значения 32768, и значение "other" также равно 32768. Но Equals() вернет false для всех значений выше 32767.

Если вы измените метод на использование оператора '==', код будет работать. Кроме того, если вы измените тип со структуры на класс, код будет работать так, как ожидается.

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

Я думаю, что это ошибка в RyuJIT-компиляторе. Если я использую устаревший JIT-компилятор, код работает нормально.

Протестировано с Visual Studio 2015 и TargetFramework 4.6.2 на разных версиях Windows.

1 ответ

Ошибка подтверждена осмотром.

Я не могу представить, какой другой ответ может появиться здесь. Если бы ошибка была нереальной, вы бы получили ответ, показывающий, где ваш код неправильный, но ваш код не ошибочный.

Другие вопросы по тегам