Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > the alignment and storage of bit fields


Автор: onetimer 22.4.2008, 21:44
Есть типы:
Код

typedef unsigned char byte;
typedef unsigned short word;

typedef struct {
  byte  type    : 8;
  byte  dev_id  : 3;
  byte  grp_id  : 5;
  byte  head_id : 2;
  byte  ver     : 2;
  word  len     :10;
  byte  res     : 2;
} x_header_s;


Использую #pragma option -a1
Проблема в том, что мне СОВЕРШЕННО необходимо поместить это в 4 байта, а зараза билдер делает 6: сует 
[C++ Warning] : W8059 Structure packing size has changed.

На основании "According to the C and C++ language specifications, the alignment and storage of bit fields is implementation defined. Therefore, compilers can align and store bit fields differently. If you want complete control over the layout of bit fields, it is advisable to write your own bit field accessing routines and create your own bit fields." считает себя правым. Есть советы? Предложения?

Автор: jonie 22.4.2008, 21:57
делай так и не парься:
Код

#pragma pack(push)
#pragma pack(1)
typedef union {
  DWORD _all;
  byte  type    : 8;
  byte  dev_id  : 3;
  byte  grp_id  : 5;
  byte  head_id : 2;
  byte  ver     : 2;
  word  len     :10;
  byte  res     : 2;
} x_header_s;
#pragma pack(pop)

Автор: onetimer 22.4.2008, 23:07
Совершенно глупый совет, извините!
Код

  int i = 300;

  x_header_s x;
  x.type = 5;
  x.len = i;
  ShowMessage(sizeof(x_header_s));
  ShowMessage(x.len);
  ShowMessage(x.type);

Автор: jonie 23.4.2008, 00:18
и чего не так?!
http://ipicture.ru/uploads/080423/MVhynWgxxA.png

если вы будете внимательными, то может заметите что я заменл структуру объединением.

Автор: onetimer 23.4.2008, 00:53
и это об'единило все битовые поля! Потому я и привел фрагмент кода, чтобы Вы сами могли убедиться!

Автор: dumb 23.4.2008, 05:36
Код

#pragma pack(push, 1)
typedef struct {
  word  type    : 8;
  word  dev_id  : 3;
  word  grp_id  : 5;
  word  head_id : 2;
  word  ver     : 2;
  word  len     :10;
  word  res     : 2;
} x_header_s;
#pragma pack(pop)

Автор: jonie 23.4.2008, 08:13
а ну да, я идиот, признаю.
в любом случае pragma pack(1)+правильное использование битовых масок (), по идее работать должно...

Автор: onetimer 23.4.2008, 16:16
dumb вариант не работает.
Еще идеи?

Автор: dumb 23.4.2008, 20:39
Цитата(onetimer @  23.4.2008,  17:16 Найти цитируемый пост)
dumb вариант не работает
это не вариант и не идея. это правильное и рабочее решение твоей "проблемы". и, кстати, раз уж поля впихиваются в 4 байта, то логичнее было бы тип ставить dword.

Автор: onetimer 23.4.2008, 22:05
Код

void __fastcall TForm1::FormCreate(TObject *Sender)
{
  int i = 300;

  x_header_s x;
  x.type = 5;
  x.len = i;
  ShowMessage(sizeof(x_header_s));
  ShowMessage(x.len);
  ShowMessage(x.type);
}

Не работает: можете убедиться самостоятельно.
Цитата
это правильное и рабочее решение твоей "проблемы". и, кстати, раз уж поля впихиваются в 4 байта, то логичнее было бы тип ставить dword.

Совершенно не согласен ни с тем ни с другим.

Автор: Rififi 23.4.2008, 22:57
onetimer

откомпилировал этот код на древнем VC 6.0 sp6

Код
int i = 300;

x_header_s x;
memset(&x, 0, sizeof(x));

x.type = 257;  // 257 & 0xFF == 1
x.len = i;
std::cout << sizeof(x_header_s) << std::endl;
std::cout << x.len << std::endl;;
std::cout << x.type << std::endl;


выхлоп:

Код
4
300
1


отсюда вывод про борланд: "ну не шмогла я, не шмогла..."

Автор: jonie 23.4.2008, 23:18
onetimer вариант dump отработал у меня не совсем норм. builder6 (вывел 4,300,5)
вообще корректнее пихать все поля в DWORD... и делать битовые поля "из этого типа"...

в общем-то можно написать свой класс обертуку на DWORD-ом)
уж если это не заработает разбить монитор...

Автор: onetimer 23.4.2008, 23:42
Код

#pragma pack(push, 1)
typedef struct {
  byte  type    : 8;
  byte  dev_id  : 3;
  byte  grp_id  : 5;
  byte  head_id : 2;
  byte  ver     : 2;
  word  len     :10;
  byte  res     : 2;
} x_header_s;
#pragma pack(pop)


Только BCB6. VC в любом соусе, пожалуйста, не предлагать smile 
jonie, как я могу получить (вывел 4,300,5)? Я был бы рад! Нельзя ли выложить весь проект?
У меня размер 6 байт. Могу добиться и 8 smile 
Класс сделать можно и, скорее всего, нужно, но пока пытаюсь без, по-простому.
Через DWORD дурной стиль - поля могут и будут меняться.

Автор: Rififi 23.4.2008, 23:49
onetimer
Цитата
VC в любом соусе, пожалуйста, не предлагать

не будем. ведь так интересно и весело наблюдать за мучениями борландятников :grin:

Автор: onetimer 23.4.2008, 23:55
Цитата
так интересно и весело наблюдать за мучениями борландятников

Если долго мучиться - что-нибудь получится! Может быть smile 

Автор: ksili 24.4.2008, 05:39
Цитата(onetimer @  24.4.2008,  03:42 Найти цитируемый пост)
Через DWORD дурной стиль - поля могут и будут меняться.

С чего вдруг дурной стиль? 
Причём сами же в первом посте определяете типы byte и  word, хотя в Билдере уже есть Byte, Word, BYTE и WORD

Автор: HappyLife 24.4.2008, 10:51
На самом деле, объявить тип как DWORD и использоваться битовые операции, самое оно как обычно поступают.

Автор: ksili 24.4.2008, 10:59
HappyLife, во-во, я бы тоже так сделал, а не парился бы со всякими обёртками

Автор: dumb 24.4.2008, 11:01
Цитата(Rififi @  24.4.2008,  00:49 Найти цитируемый пост)
так интересно и весело наблюдать за мучениями борландятников
не стоит обобщать. в данном конкретном случае это проблема невнимательности топикстартера.

Цитата(onetimer @  23.4.2008,  23:05 Найти цитируемый пост)
Не работает: можете убедиться самостоятельно.
уже убедился - работает. вместо раздувания топика, лучше б внимательно читал - в приведенном мной отрывке изменилось не только написание прагмы.

Цитата(onetimer @  24.4.2008,  00:42 Найти цитируемый пост)
Через DWORD дурной стиль - поля могут и будут меняться.
"дурной стиль"?! - ты когда описываешь типом byte битовые поля, которые "пересекают" границы этого самого байта, чего ожидаешь? тут и word "проканывает" только из-за того, что поля в него вмещаются.

Автор: onetimer 24.4.2008, 15:57
Цитата(ksili @  24.4.2008,  05:39 Найти цитируемый пост)
ами же в первом посте определяете типы byte и  word, хотя в Билдере уже есть Byte, Word, BYTE и WORD 

Не Borlandом единым мы живем. Есть еще, например, GCC.
Цитата(dumb @  24.4.2008,  11:01 Найти цитируемый пост)
уже убедился - работает. вместо раздувания топика, лучше б внимательно читал - в приведенном мной отрывке изменилось не только написание прагмы.

Сознаюсь, не заметил, сорри.

Цитата(dumb @  24.4.2008,  11:01 Найти цитируемый пост)
"дурной стиль"?! - ты когда описываешь типом byte битовые поля, которые "пересекают" границы этого самого байта, чего ожидаешь? тут и word "проканывает" только из-за того, что поля в него вмещаются. 


Спорить о стиле занятие дурное - пусть каждый выбирает себе сам, а жизнь рассудит.

PS A вот общаться с незнакомым человеком на "ты", вне всяких сомнений дурной стиль и бескультурие, хотя это уже за пределами топика.

Автор: dumb 24.4.2008, 18:13
Цитата(onetimer @  24.4.2008,  16:57 Найти цитируемый пост)
Спорить о стиле занятие дурное
в данном случае - это не стиль. это суть.

Цитата(onetimer @  24.4.2008,  16:57 Найти цитируемый пост)
A вот общаться с незнакомым человеком на "ты", вне всяких сомнений дурной стиль и бескультурие,
в жизни - естественно, в сети - это дефолтная модель общения. неписанное правило.

Автор: onetimer 24.4.2008, 18:21
Остаюсь при своем мнении. Спор не рождает истину, но может порадить вражду. Культура остается таковой и в сети и в жизни.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)