Почему у 8-битного поля есть сущность?

См. определение заголовка TCP в файле /netinet/tcp.h:

struct tcphdr
  {
    u_int16_t th_sport;         /* source port */
    u_int16_t th_dport;         /* destination port */
    tcp_seq th_seq;             /* sequence number */
    tcp_seq th_ack;             /* acknowledgement number */
#  if __BYTE_ORDER == __LITTLE_ENDIAN
    u_int8_t th_x2:4;           /* (unused) */
    u_int8_t th_off:4;          /* data offset */
#  endif
#  if __BYTE_ORDER == __BIG_ENDIAN
    u_int8_t th_off:4;          /* data offset */
    u_int8_t th_x2:4;           /* (unused) */
#  endif
    u_int8_t th_flags;
#  define TH_FIN        0x01
#  define TH_SYN        0x02
#  define TH_RST        0x04
#  define TH_PUSH       0x08
#  define TH_ACK        0x10
#  define TH_URG        0x20
    u_int16_t th_win;           /* window */
    u_int16_t th_sum;           /* checksum */
    u_int16_t th_urp;           /* urgent pointer */
};

Почему 8-битное поле имеет порядок в endianness? Я думал, что только 16-битные и 32-битные поля имеют значение порядка байтов, и вы можете конвертировать между ними с помощью ntohs и ntohl соответственно. Какова будет функция для обработки 8-битных вещей? Если их нет, кажется, что TCP, использующий этот заголовок на маленькой конечной машине, не будет работать с TCP на большой машине endian.

Ответы

Ответ 1

Существует два порядка. Один из них - порядок байтов, один - порядок битовых полей. Нет стандартного порядка о битовом порядке на языке C. Это зависит от компилятора. Как правило, порядок битных полей меняется на противоположные между большими и маленькими знаками.

Ответ 2

Это зависит от компилятора и не переносится. Как упорядоченные битовые поля зависят от реализации, было бы намного лучше использовать 8-битовое поле и shift/mask для получения подполей.

Ответ 4

Мое понимание заключается в том, что упорядочение бит и его сущность обычно представляют собой две разные вещи. Структуры с битовыми полями, как правило, не переносимы для компиляторов/архитектур. Иногда ifdefs можно использовать для поддержки разных порядков бит. В этом случае утверждение действительно не имеет значения, и это должно быть ifdef о порядке бит. Предположение, что некоторые endianesses имеют определенный бит-порядок, может быть правдой в некоторых случаях.

Ответ 5

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

Ответ 6

Это может помочь узнать, что этот код работает только в том случае, если "# ifdef __FAVOR_BSD". Это от /usr/include/netinet/tcp.h

# ifdef __FAVOR_BSD
typedef u_int32_t tcp_seq;
/*
 * TCP header.
 * Per RFC 793, September, 1981.
 */
struct tcphdr