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 ответ
Ошибка подтверждена осмотром.
Я не могу представить, какой другой ответ может появиться здесь. Если бы ошибка была нереальной, вы бы получили ответ, показывающий, где ваш код неправильный, но ваш код не ошибочный.