Как я могу обнаружить порядковый номер в системе, где все примитивные целочисленные размеры одинаковы? - PullRequest
1 голос
/ 17 января 2011

(Этот вопрос возник из-за того, что вчера кто-то объяснил детали CHAR_BIT, sizeof и endianness. Это совершенно гипотетично.)

Допустим, я на платформе, где CHAR_BIT равен 32, поэтому sizeof (char) == sizeof (short) == sizeof (int) == sizeof (long).Я считаю, что это все еще среда, соответствующая стандартам.

Обычный способ определения порядка байтов во время выполнения (, потому что нет надежного способа сделать это во время компиляции ), это сделать union { int i, char c[sizeof(int)] } x; x.i = 1 и посмотрите, установлены ли x.c[0] или x.c[sizeof(int)-1].

Но это не работает на этой платформе, так как я получаю символ [1].

Есть лиспособ определить, является ли такая платформа с прямым порядком байтов или с прямым порядком байтов во время выполнения?Очевидно, это не имеет значения в этой гипотетической системе, но можно представить, что она записывает в файл или в какую-то область отображаемой памяти, которую другая машина считывает и восстанавливает в соответствии со своей (более разумной) моделью памяти.

Ответы [ 8 ]

4 голосов
/ 17 января 2011

Концепция порядка байтов имеет смысл только для скалярных типов, представленных несколькими байтами.По определению, char является однобайтовым, поэтому любой целочисленный тип, имеющий тот же размер, что и char, не имеет порядкового номера.

Также имейте в виду, что порядковый номер может быть различным для разных типов: например,PDP-11 представляет собой 16-разрядную архитектуру с прямым порядком байтов, а 32-разрядные целые числа построены из двух 16-разрядных значений с прямым порядком байтов, заканчивающихся смешанным порядком байтов.

4 голосов
/ 17 января 2011

Гипотетически, в среде, где все типы данных имеют одинаковый размер, не существует порядка байтов.

Я вижу три возможности для вас:

  • Еслиограничение дается только компилятором C, и технически платформа имеет несколько меньших типов данных, вы можете использовать ассемблер для определения порядка байтов.

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

  • Также вы можете записать данные в файл, как вы предложили, и затем прочитать обратно.Просто напишите два символа (файл в двоичном режиме), переместите указатель файла в положение 1 и прочитайте обратно символ.

2 голосов
/ 17 января 2011

Я полагаю, что вопрос сводится к следующему: является ли порядок байтов значимым понятием на этой платформе, т. Е. Оказывает ли оно заметное влияние на поведение программы?

Если этого не происходит, то порядок байтов (то есть порядок, в котором отдельные байты, составляющие 32-битное количество, хранятся в памяти) - это просто деталь реализации, которую вы не можете обнаружить, но которая не должна беспокоить Вы тоже.

Если порядковый номер действительно обнаруживает влияние на поведение определенного аспекта языка ... ну, тогда создайте тест, основанный на этом поведении. Вот несколько примеров:

  • Как работает система адресации на платформе? Если вы увеличиваете адрес на единицу, скольким битам это соответствует? Если ответ - восемь битов, и система позволяет вам читать с адресов, не кратных четырем, то вы можете переместить указатель вперед на один байт (через объезд до intptr_t) и проверить таким образом порядок байтов , (Да, это поведение, определяемое реализацией, но при этом используется объединение для проверки на порядковый номер, а также на всю концепцию порядкового номера в целом.) Если, однако, наименьшая адресуемая единица памяти составляет 32 байта, то вы можете ' Таким образом, t-тест на порядковый номер.

  • Имеет ли платформа 64-битный тип данных (a long long)? Затем вы можете создать объединение long long и двух int с и построить свой тест на последовательность, основываясь на этом.

0 голосов
/ 26 марта 2012

Вы можете сместить указанную переменную и посмотреть, с какого конца смещается 1.

0 голосов
/ 18 января 2011

htonl должно работать:

if(htonl(1)==1) {
   /* network order (big-endian) */
} else {
   /* little-endian */
}

(Я не вижу причин, чтобы не внедрять htonl и друзей обычным способом, даже для этой надоедливой гипотетической системы - хотя я не уверен, насколько сильно они окажутся на практике. )

0 голосов
/ 17 января 2011

Вопрос не предлагает достаточно информации, но с тем, что он предлагает, я бы сказал: не возможно.

0 голосов
/ 17 января 2011

Если ваш код полагается на знание, является ли архитектура BE или LE, тогда ваш код должен иметь безопасность, а не компилироваться для неизвестной платформы. Некоторые #if ! defined(ARCH_IS_LE) && ! defined(ARCH_IS_BE) \ #error unknown architecture должны сделать.

0 голосов
/ 17 января 2011

Структурные битовые поля должны по-прежнему работать правильно на любой платформе, даже этой:

union {
   int i;
   struct {
       int b1 : 8;
       int b2 : 8;
       int b3 : 8;
       int b4 : 8;
   } s;
} u;

u.i = 1;
if (u.s.b1 != 0)
   ....
...