Ошибка компиляции, связанная с __builtin_bswap32

Я играю с открытым исходным кодом, который содержит следующий код

uint32_t addr = htonl(* (uint32_t *)RTA_DATA(rth));
if (htonl(13) == 13) {
    // running on big endian system
} else {
    // running on little endian system
    addr = __builtin_bswap32(addr);
}

Похоже, что он проверяет, является ли система с прямым или прямым порядком байтов с if (htonl(13) == 13), это правильно? и не могли бы вы объяснить, почему проверить это таким образом? а почему он использует 13?

Так же addr = __builtin_bswap32(addr); вызвать проблему компиляции "неопределенная ссылка". Есть ли решение, чтобы это исправить? похоже, что эта функция больше не существует в новых версиях gcc libs. это правильно?

РЕДАКТИРОВАТЬ:

Я использую набор инструментов toolchain-i386_gcc-4.1.2_uClibc-0.9.30.1

для опций, которые я использовал в компиляции:

  • для вариантов компиляции c to object:

    -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -I. -I/opt/lampp/htdocs/backfire/staging_dir/target-i386_uClibc-0.9.30.1/usr/include -O2 -pipe -march=i486 -funit-at-a-time -fhonour-copts -D_GNU_SOURCE -MT

  • для объекта в двоичный файл (компоновщик)

    -O2 -pipe -march=i486 -funit-at-a-time -fhonour-copts -D_GNU_SOURCE -L/opt/lampp/htdocs/backfire/staging_dir/target-i386_uClibc-0.9.30.1/usr/lib -L/opt/lampp/htdocs/backfire/staging_dir/target-i386_uClibc-0.9.30.1/lib -L/opt/lampp/htdocs/backfire/staging_dir/toolchain-i386_gcc-4.1.2_uClibc-0.9.30.1/lib -Wl,-rpath-link=/opt/lampp/htdocs/backfire/staging_dir/target-i386_uClibc-0.9.30.1/usr/lib

1 ответ

Решение

htonl преобразует число "host-order" в сетевой порядок байтов. Порядок хостов - это любой порядок в системе, в которой выполняется код. Порядок байтов в сети - big-endian. Если хост-сеть имеет большое значение, это означает отсутствие изменений - вот что 13 -> 13 проверил бы. С другой стороны, если хост-сеть имеет малые размеры, это означает, что вы получите обмен, поэтому наименее значимый байт 13 (хотя бы потому, что изменение его на 1 изменяет общее число только на 1) станет самым старшим байтом 13 (чаще всего потому, что изменение этого байта на единицу меняет общее число на наибольшую сумму), и 13 -> (13 << 24),

13 конкретно неважно. Вы можете использовать любое число, если его представление с прямым порядком байтов не совпадает с его представлением с прямым порядком байтов. (0 было бы плохо, потому что 0 поменять местами все еще 0, То же самое для (65536 + 256) также, потому что 32-битное представление 00 01 01 00 как с прямым порядком байтов, так и с прямым порядком байтов.

Обратите внимание, что существуют также системы со смешанным порядком байтов, где для 32-разрядного числа 0x12345678вы бы имели байты не в порядке 12 34 56 78 (big-endian) или 78 56 34 12 (Прямой порядок байтов): 34 12 78 56 во-первых, я верю. Эти системы не распространены, но они все еще существуют, и код здесь не будет обрабатывать их правильно.

http://gcc.gnu.org/onlinedocs/gcc-4.2.0/gcc/Other-Builtins.html и http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Other-Builtins.html предложить __builtin_bswap32 был добавлен в gcc 4.3, поэтому ваш набор инструментов gcc 4.1.2 не будет иметь его.

Другие вопросы по тегам