Экспорт упакованных структур с помощью bool

Какова наилучшая практика для экспорта упакованной структуры, содержащей логические значения?

Я спрашиваю об этом, потому что я пытаюсь найти лучший способ сделать это. Тока я делаю:

#ifndef __cplusplus
#if __STDC_VERSION__ >= 199901L
#include <stdbool.h>    //size is 1.
#else
typedef enum {false, true} bool; //sizeof(int)
#endif
#endif

теперь в приведенном выше, размер логического может быть 1 или sizeof(int)..

Так в структуре, как:

#pragma pack(push, 1)
typedef struct
{
long unsigned int sock;
const char* address;
bool connected;
bool blockmode;
} Sock;
#pragma pack(pop)

выравнивание отличается при использовании C по сравнению с C99 & C ++. Если я экспортирую его как целое число, то языки с логическим размером 1 имеют проблемы с выравниванием и должны дополнить структуру.

Мне было интересно, будет ли лучше использовать определение bool как char в случае с pre-C99, но это не так.

Есть идеи получше?

0

Решение

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

Если вы хотите быть быстрым, но можете «потратить» несколько байтов пространства (то есть одно значение для каждого логического флага, см. sizeof bool обсуждение), ваш нынешний подход является превосходным. Это потому, что он может загружать и сравнивать логические значения напрямую, без необходимости маскировать их из упакованного поля (см. Далее).

Если вы хотите сэкономить место, вам следует Си битовые поля:

struct Sock {
...
int connected:1; // For 2 flags, you could also use char here.
int blockmode:1;
}

или сверните свои собственные «флаги» и установите биты в целочисленные значения:

#define SOCKFLAGS_NONE      0
#define SOCKFLAGS_CONNECTED (1<<0)
#define SOCKFLAGS_BLOCKMODE (1<<1)

struct Sock {
...
int flags; // For 2 flags, you could also use char here.
}

Оба примера приводят к более или менее одинаковому коду, который маскирует биты и сдвигает значения вокруг (дополнительные инструкции), но плотнее упаковывается, чем простой bool ценности.

1

Другие решения

ИМХО, используя #pragma pack боль больше (в долгосрочной перспективе), чем выигрыш (в краткосрочной перспективе).

  • Это зависит от компилятора; нестандартный и непереносимый

  • Я понимаю сценарии встроенных систем или протоколов. Приложив немного дополнительных усилий, код можно написать без прагмы.

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

Я бы сделал следующие три вещи:

  • Объявите флаги как bool (вы уже сделали) и назначить true/false
  • Поместите их в качестве последних членов struct (ты уже сделал)
  • Используйте битовое поле (как предложено коллегами по укладке)

Объединяя эти:

typedef struct Sock
{
long unsigned int sock;
const char* address;
bool connected : 1;
bool blockmode : 1;
} Sock;
1

В случае до C99 это рискованно typedef char bool;, Это будет молча нарушать код как:

bool x = (foo & 0x100);

который должен установить x чтобы быть правдой, если этот бит установлен в foo, Перечисление имеет ту же проблему.

В моем коде я на самом деле typedef unsigned char bool; но тогда я осторожно пишу !! везде, где выражение преобразуется в это bool, Это не идеально.

По моему опыту, использование флагов в интегральном типе приводит к меньшему количеству проблем, чем использование bool в вашей структуре, или битовые поля, для C90.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector