Присвоить целочисленное значение структуре

У меня есть структура, определенная как:

typedef struct {
   uint8_t field1 : 6,
   uint8_t field2 : 1,
   uint8_t field3 : 1
} myStruct;

а потом:

myStruct s;

Каков безопасный способ присвоить 8-битное значение всем полям сразу, т.е.:

s = 10;

Компилятор выдает ошибку при попытке назначить подобное (очевидно, я даже не подразумеваю, что это способ сделать это :)).

Будет ли это рекомендовано:

uint8_t a = 10;
s = * ((myStruct*) &a);

?


person Bogdan Alexandru    schedule 19.08.2014    source источник
comment
Не существует безопасного способа сделать это, потому что язык не указывает, является ли это прямым порядком байтов или прямым порядком байтов.   -  person Barmar    schedule 19.08.2014
comment
Big endian или little endian не играет роли для однобайтовых типов. Байт — это байт (при условии, что байт — это октет).   -  person Rudy Velthuis    schedule 19.08.2014
comment
@Barmar Вся структура имеет ширину 1 байт, поэтому я не понимаю, как здесь имеет значение порядок следования байтов.   -  person Bogdan Alexandru    schedule 19.08.2014
comment
В этом случае порядок байтов также относится к порядку битов в байте. C не указывает это.   -  person Barmar    schedule 19.08.2014
comment
возможный дубликат преобразования битового поля в int   -  person Barmar    schedule 19.08.2014
comment
его можно назначить следующим образом myStruct s = { 10 };   -  person mahendiran.b    schedule 19.08.2014


Ответы (2)


Вы можете использовать союз:

union myUnion {
  struct myStruct ms;
  uint8_t byte;
};

myUnion u;
u.byte = 10;  /* Uses the same memory as myStruct and its fields. */
printf("field1=%u field2=%u field3=%u\n", u.ms.field1, u.ms.field2, u.ms.field3);

Раньше это не одобрялось, но см. комментарий @mafso ниже, это похоже, сейчас это разрешено.

person unwind    schedule 19.08.2014
comment
... но компиляторы поддерживают это, и цель стандарта - разрешить это. В 6.5.2.3 p3 добавлена ​​сноска. Если элемент, используемый для чтения содержимого объекта объединения, не совпадает с элементом, который в последний раз использовался для сохранения значения в объекте, соответствующая часть объектного представления значения переинтерпретируется как представление объекта в новом типе, как описано в 6.2.6 (процесс, иногда называемый «каламбуром типа»). Это может быть представление-ловушка. См. DR 283 - person mafso; 19.08.2014

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

myStruct s;
s = 10;

Это не разрешено. Это не правильный способ делать вещи!

Когда вы делаете, как показано ниже-

uint8_t a = 10;
s = * ((myStruct*) &a);

Это небезопасный способ присвоить значение 10 членам битового поля! Так что делайте это индивидуально, как-

s.field1=xx; // Instead of xx, yy and zz assign values
s.field2=yy;
s.field3=zz;

Это лучший способ сделать это!

person Sathish    schedule 19.08.2014
comment
-1. Если конструкция мягкая, вышеперечисленное вызовет искры. - person unwind; 19.08.2014
comment
@unwind Я думаю, что если OP использует битовые поля, он уже знает, что делает, и может быть уверен, что нет проблем с заполнением, порядком битов, строгим псевдонимом и т. д. - person anatolyg; 19.08.2014