Поле IsLittleEndian сообщает false, но оно должно быть Little-Endian? - PullRequest
20 голосов
/ 08 января 2010

Я работаю на компьютере Intel (Win7 64-bit) и, согласно тому, что я прочитал, Intel использует Little-Endian. Я пробую это в C # со следующим кодом:

byte[] b2 = new byte[] { 0, 1 };
short b2short = BitConverter.ToInt16(b2, 0);

и b2short == 256, как и ожидалось от Little-Endian.

Затем я прочитал, что в .NET BitConverter.IsLittleEndian должен отражать, какой порядковый номер использует система, и когда я проверяю переменную в Visual Studio, он сообщает false , т.е. это НЕ Little-Endian .

Имеет ли это какое-либо отношение к 64-битной ОС? Есть идеи?


EDIT: Мой коллега, который сидит напротив меня, прошел тот же тест (32-разрядная версия Windows Vista) и получил те же результаты


РЕДАКТИРОВАТЬ 2: Это действительно странно. Всякий раз, когда я запускаю код и ломаюсь после того, как BitConverter сделал свое дело, IsLittleEndian == false. НО, если я добавлю строку Console.WriteLine (BitConverter.IsLittleEndian); впоследствии это ИСТИНА:

byte[] b2 = new byte[] { 0, 1 };
short b2short = BitConverter.ToInt16(b2, 0);
Console.WriteLine(BitConverter.IsLittleEndian);
// Now the IsLittleEndian is true

Но как только я удаляю Console.WriteLine, это снова false .

Я также могу добавить, что даже если я сломаю "Console.WriteLine", IsLittleEndian == true, но если я удалю строку вообще, это false.


РЕДАКТИРОВАТЬ 3: Как отметил Марк Гравелл, это должно быть ошибка времени. Если я использую переменную BitConverter.IsLittleEndian, она инициализируется, если я не делаю (и смотрю на нее при взломе), она не инициализируется и, таким образом, false ...

Ответы [ 4 ]

20 голосов
/ 08 января 2010

Интересно, это ошибка синхронизации, возможно, связанная с "beforefieldinit" ... как вы оцениваете значение? Возможно, инициализатор типа (для BitConverter) не запускается отладчиком VS (который, так сказать, заглядывает под прикрытие). Тем более что false является значением по умолчанию для поля ...

Статическое поле IsLittleEndian устанавливается в статическом конструкторе; и время выполнения инициализатора ... очень сложно предсказать. Если вы используете отладчик, все ставки отключены. Единственный способ надежно проверить значение этого поля - через код (когда CLR запустит инициализатор в какой-то момент до того, как это потребуется):

bool isLittleEndian = BitConverter.IsLittleEndian;

Не доверяйте окнам отладчика / наблюдения и т. Д.

6 голосов
/ 05 августа 2013

Раймонд Чен дает расширенный ответ на вопрос здесь (зеркало, с лучшим форматированием здесь ).

Суть в том, что:

Чтение члена из отладчика не выполняет код для инициализации этого члена.

Поэтому, если вы посмотрите на поле в Visual Studio, оно сообщит о ложном значении, поскольку статический инициализатор еще не запущен. Однако, если вы используете поле в коде, статический инициализатор будет работать, в результате чего поле будет возвращать фактическое правильное значение.

2 голосов
/ 08 января 2010

Как вы это проверяете?

Например, запустите это короткое консольное приложение:

using System;

public class Test
{
    static void Main()
    {
        Console.WriteLine(BitConverter.IsLittleEndian);
    }
}

Что это печатает? Не могли бы вы рассказать, какое оборудование и ОС вы используете?

0 голосов
/ 08 января 2010

Как говорит Марк, похоже, это ошибка синхронизации. Используя отладчик VS, чтобы «посмотреть» значение при запуске, он возвращает false, но если я распечатываю его в окне сообщения, он возвращает true.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...