Почему кастинг с байта на sbyte дает неправильное значение для оптимизированного кода?
Проблема может быть воспроизведена с помощью следующего примера кода, с установленным NUnit 3.
[TestFixture]
public class SByteFixture
{
[Test]
public void Test()
{
var data = new byte[] { 0xFF };
sbyte x = -128;
data[0] = (byte) x;
byte b1 = data[0];
var b2 = (sbyte) b1;
Assert.AreEqual(b1.ToString(), "128");
Assert.AreEqual(b2.ToString(), "-128");
}
}
- Проект должен быть библиотекой классов, потому что в консольном приложении он не воспроизводится.
-
Должна быть включена оптимизация, т.е. Следующая настройка в файле csproj:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<Optimize>true</Optimize>
</PropertyGroup>
Тест проходит, когда Optimize является ложным, но он терпит неудачу, когда Optimize истинно (b2.ToString()
дает "128"
).
Это можно увидеть с помощью ReSharper для запуска теста или NUnitConsole, не воспроизводимого с помощью VS Test Explorer.
Как это можно объяснить?
Ответы
Ответ 1
Как предположил @HansPassant, я сообщил об этой проблеме в GitHub, и, похоже, это подтвержденная ошибка.
Здесь цитата по этому вопросу из mikedn
Тот факт, что вы можете воспроизвести в библиотеке классов, а не в консольном приложении, может означать, что вы используете.NET Framework, а не.NET Core. В консольных приложениях.NET Framework по умолчанию 32 бит, поэтому они используют устаревший JIT32, а не RyuJIT. 64-разрядные приложения.NET Framework используют RyuJIT, но обычно это более старая версия, чем версия.NET Core.
Я могу воспроизвести эту проблему с использованием 64-битной.NET Framework 4.7.2, но не текущей основной версии.NET Core. Он может воспроизводиться с использованием.NET Core 2.1, поэтому, вероятно, это уже было исправлено в master.