Чувствителен ли C # Endian? - PullRequest
       47

Чувствителен ли C # Endian?

12 голосов
/ 12 февраля 2010

Является ли C # когда-либо чувствительным к Endian, например, будет такой код:

int a = 1234567;
short b = *(short*)&i;

всегда присваивает одинаковое значение b. Если да, то какое это будет значение?

Если нет, то какие есть хорошие способы борьбы с порядком байтов, если код содержит указатели?

Ответы [ 4 ]

15 голосов
/ 12 февраля 2010

C # не определяет порядок байтов. В действительности, да, он, вероятно, всегда будет с прямым порядком байтов (IIRC даже на IA64, но я не проверял), но в идеале вы должны проверить BitConverter.IsLittleEndian, если важен порядок байтов - или просто использовать сдвиг битов и т. Д., А не прямую память доступ.

Чтобы процитировать несколько строк из protobuf-net (сборка еще не совершена):

WriteInt64(*(long*)&value);
if (!BitConverter.IsLittleEndian)
{   // not fully tested, but this *should* work
    Reverse(ioBuffer, ioIndex - 8, 8);
}

т.е. он проверяет порядок байтов и при необходимости переворачивает.

6 голосов
/ 12 февраля 2010

Да, я считаю, что код чувствителен к порядку байтов. Значение b будет самым младшим байтом в процессоре с прямым порядком байтов и самым старшим байтом в процессоре с прямым порядком байтов. Чтобы это было проще увидеть, давайте переключимся на шестнадцатеричный код:

using System;

class Test
{
    unsafe static void Main()
    {
        int a = 0x12345678;
        short b = *(short*)&a;
        Console.WriteLine(b.ToString("x"));
    }
}

На моем x86-боксе напечатано «5678», показывающее, что младшие байты были в «начале» правила a. Если вы запустите тот же код на процессоре, работающем в режиме с прямым порядком байтов (вероятно, в Mono), я ожидаю, что он выведет «1234».

1 голос
/ 12 февраля 2010

Насколько я могу судить, ни спецификации C #, ни Common Language Infrastructure не имеют требований к порядку байтов для побитовых и математических операций на основе указателей. CLI заявляет, что двоичные данные, хранящиеся в исполняемом файле MSIL, должны иметь формат с прямым порядком байтов. И общее отклонение документов будет означать, что код не должен зависеть от какого-либо конкретного представления памяти (включая упакованные или распакованные массивы и т. Д.), За исключением особых обстоятельств.

0 голосов
/ 12 февраля 2010

Вы действительно не должны делать указатели в C #. Вы должны попытаться скомпилировать свой код, прежде чем спрашивать, что он будет делать.

...