Порядковый номер битового поля в gcc

Порядковый номер битовых полей определяется реализацией. Есть ли способ проверить, во время компиляции, с помощью какого-либо макроса или другого флага компилятора, что на самом деле является порядком байтовых полей gcc?

Другими словами, учитывая что-то вроде:

struct X {
    uint32_t a : 8;
    uint32_t b : 24;
};

Есть ли способ для меня, чтобы узнать во время компиляции, или нет a первый или последний байт в X?

1 ответ

Решение

В системах Linux вы можете проверить __BYTE_ORDER макрос, чтобы увидеть, если это __LITTLE_ENDIAN или же __BIG_ENDIAN, Хотя это не является авторитетным, на практике это должно работать.

Намек на то, что это правильный способ сделать это в определении struct iphdr в netinet/ip.h, для заголовка IP. Первый байт содержит два 4-битных поля, которые реализованы как битовые поля, поэтому порядок важен:

struct iphdr
  {
#if __BYTE_ORDER == __LITTLE_ENDIAN
    unsigned int ihl:4;
    unsigned int version:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
    unsigned int version:4;
    unsigned int ihl:4;
#else
# error "Please fix <bits/endian.h>"
#endif
    u_int8_t tos;
    u_int16_t tot_len;
    u_int16_t id;
    u_int16_t frag_off;
    u_int8_t ttl;
    u_int8_t protocol;
    u_int16_t check;
    u_int32_t saddr;
    u_int32_t daddr;
    /*The options start here. */
  };

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

См. Здесь [godbolt.org]

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

Обратите внимание, что независимо от того, является ли архитектура прямым или прямым порядком байтов, в обоих случаях 8-битное поле находится в начале структуры.

Я протестировал все компиляторы на Godbolt, которые могли генерировать читаемый код сборки для функции is_8bit_tag_at_start, и все они, похоже, вернули истину.

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