|
Доступ к полям структуры. |
|
|
|
Aug 30 2013, 11:41
|
Знающий
   
Группа: Свой
Сообщений: 922
Регистрация: 3-06-05
Из: Москва
Пользователь №: 5 709

|
Переношу код из AVR Studio (WINAVR) в Keil. Компилятор выдаёт предупреждение на объявление, на стоку с "};" Код ……… struct { unsigned char Bit1 : 1; unsigned char Bit2 : 1; }; …………. ..\Test.h(37): warning: #40-D: expected an identifier И потом выдаёт ошибку на использование этих полей. Лечится это заданием имени структуры, например "} A1;", что не удобно, для меня. В WINAVR, в MinGW, в Visual Studio такого нет, только в Keil. Может быть это стандарт С++, не проверял и всех тонкостей языка не знаю. Можно какими-нибудь флажками убрать эту особенность?
|
|
|
|
|
Aug 30 2013, 11:57
|
Участник

Группа: Участник
Сообщений: 55
Регистрация: 28-11-11
Пользователь №: 68 553

|
Приведите весь код, а то не понятно это внутри структуры, юниона или просто чистое объявление.
|
|
|
|
|
Aug 30 2013, 12:17
|
Группа: Участник
Сообщений: 11
Регистрация: 14-07-06
Из: Кишинёв
Пользователь №: 18 825

|
можно попробовать так: Код struct { unsigned char Bit1_ : 1; unsigned char Bit2_ : 1; } A1; #define Bit1 A1.Bit1_ #define Bit2 A1.Bit2_
|
|
|
|
|
Aug 30 2013, 13:02
|
Участник

Группа: Участник
Сообщений: 55
Регистрация: 28-11-11
Пользователь №: 68 553

|
Возможно у топик стартера было что -то вроде: Код union uu { struct { unsigned char Bit1 : 1; unsigned char Bit2 : 1; }; int v; }; Но некоторые компиляторы не позволяют использовать безымянные структуры, возможно Кейл как раз один из таких компиляторов.
|
|
|
|
|
Aug 30 2013, 16:18
|

Частый гость
 
Группа: Свой
Сообщений: 156
Регистрация: 18-02-13
Из: Киев
Пользователь №: 75 678

|
Цитата("SSerge") Я правильно понял, что в Вашей версии С невозможны поля длиной меньше 8 бит? Не правильно. Читайте внимательно.
|
|
|
|
|
Aug 30 2013, 16:34
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(vassabi @ Aug 30 2013, 18:47)  Согласно справочника по С, битовое поле может быть signed или unsigned. Согласно стандарта: Цитата A bit-field shall have a type that is a qualified or unqualified version of _Bool, signed int, unsigned int, or some other implementation-defined type. Транслятор Keil в данном случае считает тип signed/unsigned char как "other implementation-defined type".
|
|
|
|
|
Aug 30 2013, 18:26
|
Знающий
   
Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725

|
Цитата(Oleg_IT @ Aug 30 2013, 12:41)  Компилятор выдаёт предупреждение на объявление, на стоку с "};" Код ……… struct { unsigned char Bit1 : 1; unsigned char Bit2 : 1; }; …………. ..\Test.h(37): warning: #40-D: expected an identifier Код ……… struct mystruct_s { unsigned char Bit1 : 1; unsigned char Bit2 : 1; };
... struct mystruct_s variable_a, variable_b; ...
variable_a.Bit1 = variable_b.Bit2;
………….
|
|
|
|
|
Sep 1 2013, 06:35
|
Знающий
   
Группа: Свой
Сообщений: 922
Регистрация: 3-06-05
Из: Москва
Пользователь №: 5 709

|
Цитата Приведите весь код, а то не понятно это внутри структуры, юниона или просто чистое объявление. Это заголовок IP Код typedef struct IP_Head_v4_tag { struct { unsigned char IHL : 4; // IHL - 5 unsigned char Version : 4; // Version - 4 };
struct { unsigned char Prec : 3; // Precedence - 3 unsigned char D : 1; // Delay Normal - 0 unsigned char T : 1; // Throughput Normal - 0 unsigned char R : 1; // Relibility Normal - 0 unsigned char Res1 : 2; // Reserved - 00 };
unsigned short TotalLen; // Total Length unsigned short Identif; // Идентификатор - 0
struct { unsigned short FragOffset: 13; // Fragment Offset - 0 unsigned char MF : 1; // Fragment - 0 = Last Fragment unsigned char DF : 1; // Fragment - 1 = Don't Fragment unsigned char Res2 : 1; // Reserved - 0 }; struct { unsigned char TTL : 8; // Time to Live < 1 unsigned char Prot : 8; // Protocol }; unsigned short Checksum; // Header Checksum IPADDRESS IP_SRC_Adr; // Source Address IPADDRESS IP_DST_Adr; // Destination Address } IP_Head_v4; Со всеми перечисленными компиляторами (WINAVR, MinGW, Visual Studio) анонимные битовые поля структур работают правильно. Цитата Для анонимных структур существует #pragma anon_unions. Спасибо, проверю, а вдруг поможет. Цитата Что-то я не понимаю, как эту структуру безымянную использовать. Например так Код IP_Head_v4 IP_H; IP_H.IHL = 5;
|
|
|
|
|
Sep 4 2013, 11:31
|
Знающий
   
Группа: Свой
Сообщений: 922
Регистрация: 3-06-05
Из: Москва
Пользователь №: 5 709

|
Цитата(pitt @ Sep 3 2013, 16:54)  Просто хочу, как бывший советский гражданин, дать несколько советов. Когда имеете дело со структурами, особенно отображающими пакеты данных, не забывайте endianness(простите не знаю как по-русски). Кроме того, советую включать файл stdint.h и использовать типы int8_t, uint16_t и тому подобное- это существенно облегчает как понимание, так и переносимость кода. Спасибо, учёл.
|
|
|
|
|
Sep 4 2013, 11:47
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(pitt @ Sep 3 2013, 15:54)  Просто хочу, как бывший советский гражданин, дать несколько советов. Когда имеете дело со структурами, особенно отображающими пакеты данных, не забывайте endianness(простите не знаю как по-русски). Кроме того, советую включать файл stdint.h и использовать типы int8_t, uint16_t и тому подобное- это существенно облегчает как понимание, так и переносимость кода. По-русски это будет эндианность  А я вообще не рекомендую мапить протоколы на структуры, потому как нарвался однажды на грабельное поле, и связано это было с выравниванием.
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Sep 4 2013, 12:32
|
Участник

Группа: Участник
Сообщений: 20
Регистрация: 18-03-12
Пользователь №: 70 865

|
И какой в этом вообще смысл?
чем это бы отличалось если не использовать вложенную анонимную структуру вообще.
|
|
|
|
|
Sep 4 2013, 20:42
|
Местный
  
Группа: Участник
Сообщений: 328
Регистрация: 1-06-06
Из: USA
Пользователь №: 17 672

|
Цитата(MrYuran @ Sep 4 2013, 07:47)  А я вообще не рекомендую мапить протоколы на структуры, потому как нарвался однажды на грабельное поле, и связано это было с выравниванием. А вот это напрасно. Если кто-то упаковывается данные, то, скорее всего, кто-то будет распаковывать. Такие вещи хорошо включать в заголовочный файл, который используется с обеих сторон. Выравнивание часто действительно может стать проблемой, но это другая тема. Особенно важно структурированность пакетов передачи и, по умолчанию, выравнивание побайтное. Подавляющее большинство компиляторов позволяют выравнивать так как надо заказчику. Методы могут быть различными.
--------------------
|
|
|
|
|
Sep 4 2013, 21:16
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(pitt @ Sep 5 2013, 00:42)  А вот это напрасно. Если кто-то упаковывается данные, то, скорее всего, кто-то будет распаковывать. Смотрим C99 Annex J - Portability issues: Цитата — The order of allocation of bit-fields within a unit (6.7.2.1). — The alignment of non-bit-field members of structures (6.7.2.1). This should present no problem unless binary data written by one implementation is read by another. Вывод: использовать битовые поля при работе с внешними данными нельзя. Вообще нельзя.Ну, добавим пару исключений: - можно в рамках одной архитектуры и компилятора (что очевидно) - можно в случае проверки корректности упаковки на этапе сборки
|
|
|
|
|
Sep 5 2013, 03:08
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(pitt @ Sep 5 2013, 02:42)  А вот это напрасно. Если кто-то упаковывается данные, то, скорее всего, кто-то будет распаковывать. Такие вещи хорошо включать в заголовочный файл, который используется с обеих сторон. Выравнивание часто действительно может стать проблемой, но это другая тема. Особенно важно структурированность пакетов передачи и, по умолчанию, выравнивание побайтное. Подавляющее большинство компиляторов позволяют выравнивать так как надо заказчику. Методы могут быть различными. Можно и методы сделать одинаковыми для C++. Я делаю так: CODE struct u16p8 { u8 bytes[2]; operator u16() const { return u16load(&bytes); } u16p8 & operator =(u32 val) { u16save(&bytes, val); return *this; } }; struct u32p8 { u8 bytes[4]; operator u32() const { return u32load(&bytes); } u32p8 & operator =(u32 val) { u32save(&bytes, val); return *this; } }; где: u16load(), u16save(), u32load(), u32save() - макросы, определённые по-разному в соответствии с платформой. Если для Cortex-M3 и x86 к примеру u16load() будет: #define u16load(p) (*(u16 *)p)то для ARM7/9: #define u16load(p) (*(u8 *)(p) | (u16)((u8 *)(p))[1] << 8)Таким образом я совершенно свободно перетаскиваю структуры, описывающие пакованные структуры, между разными платформами. Это очень полезно когда пишешь firmware и тут же пишешь клиентское ПО на PC (для этого устройства) и надо описать протокол взаимодействия - это можно делать в одном файле просто копируя его между двумя проектами.
|
|
|
|
|
Sep 5 2013, 10:35
|
Знающий
   
Группа: Свой
Сообщений: 922
Регистрация: 3-06-05
Из: Москва
Пользователь №: 5 709

|
Цитата(MrYuran @ Sep 4 2013, 15:47)  По-русски это будет эндианность  А я вообще не рекомендую мапить протоколы на структуры, потому как нарвался однажды на грабельное поле, и связано это было с выравниванием. Я эту "проблему" решаю так Код #pragma push #pragma pack(1) …………………… #pragma pop Предпочитаю структуры, нагляднее. Встречал код, где данные в выходной массив просто по смещениям вписываются. Мне не нравится. Вообще - на вкус и цвет, главное что бы работало и правильно  .
|
|
|
|
|
Sep 5 2013, 22:26
|
Местный
  
Группа: Участник
Сообщений: 328
Регистрация: 1-06-06
Из: USA
Пользователь №: 17 672

|
Практически каждый компилятор/процессор имеет своё решение. Мои советы не имеют конкретной привязки, это более вопрос стиля, подхода, школы, если хотите. А не хотите - не надо. Для меня это АБСОЛЮТНАЯ необходимость и, по-этому, я ищу и пока всегда находил способы, как её добиться для всех комбинаций, которые мне пришлось встречать. Если есть конкретный вопрос для конкретной архитектуры и компилятора буду рад попробовать помочь.
Сообщение отредактировал pitt - Sep 5 2013, 22:28
--------------------
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|