реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Доступ к полям структуры.
Oleg_IT
сообщение Aug 30 2013, 11:41
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 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. Может быть это стандарт С++, не проверял и всех тонкостей языка не знаю. Можно какими-нибудь флажками убрать эту особенность?
Go to the top of the page
 
+Quote Post
shmur
сообщение Aug 30 2013, 11:57
Сообщение #2


Участник
*

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



Приведите весь код, а то не понятно это внутри структуры, юниона или просто чистое объявление.
Go to the top of the page
 
+Quote Post
psL
сообщение Aug 30 2013, 12:01
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 5-08-05
Пользователь №: 7 390



компилятору непонятно, как вы собираетесь использовать эту анонимную структуру в дальнейшем.
Go to the top of the page
 
+Quote Post
SlavaG
сообщение Aug 30 2013, 12:17
Сообщение #4





Группа: Участник
Сообщений: 11
Регистрация: 14-07-06
Из: Кишинёв
Пользователь №: 18 825



можно попробовать так:
Код
struct {
  unsigned char Bit1_      : 1;
  unsigned char Bit2_      : 1;
} A1;
#define Bit1 A1.Bit1_
#define Bit2 A1.Bit2_
Go to the top of the page
 
+Quote Post
VAI
сообщение Aug 30 2013, 12:22
Сообщение #5


Профессионал
*****

Группа: Модераторы
Сообщений: 1 120
Регистрация: 17-06-04
Пользователь №: 37



Для анонимных структур существует #pragma anon_unions.
Почитать можно в файле "....\Keil\ARM\Hlp\armcc.chm" или здесь http://www.keil.com/support/man/docs/armcc...ef_BCFBCFBF.htm
или здесь http://infocenter.arm.com/help/index.jsp?t...c/BCFBCFBF.html


--------------------
Если зайца бить, его можно и спички научить зажигать
Сколько дурака не бей - умнее не будет. Зато опытнее
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Aug 30 2013, 12:22
Сообщение #6


Беспросветный оптимист
******

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



Что-то я не понимаю, как эту структуру безымянную использовать.
enum - другое дело.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
A. Fig Lee
сообщение Aug 30 2013, 12:29
Сообщение #7


Знающий
****

Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467



typedef struct {
unsigned char Bit1 : 1;
unsigned char Bit2 : 1;
} tStruct;


tStruct str1;
tStruct str2;

void func1() {
str1.Bit1 = 0;
}


--------------------
Верить нельзя никому, даже себе. Мне - можно.
Go to the top of the page
 
+Quote Post
shmur
сообщение Aug 30 2013, 13:02
Сообщение #8


Участник
*

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



Возможно у топик стартера было что -то вроде:
Код
union uu {
        struct {
            unsigned char Bit1        : 1;
            unsigned char Bit2        : 1;
        };
        int v;
};

Но некоторые компиляторы не позволяют использовать безымянные структуры, возможно Кейл как раз один из таких компиляторов.
Go to the top of the page
 
+Quote Post
vassabi
сообщение Aug 30 2013, 14:47
Сообщение #9


Частый гость
**

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



Может я что-то не понимаю, но как вы в битовое поле длиной один бит хотите воткнуть char, т.е. 8 бит?
Согласно справочника по С, битовое поле может быть signed или unsigned.
Если вы хотите unsigned char, то наверное нужно хотябы длинну поля указать :8...
Go to the top of the page
 
+Quote Post
A. Fig Lee
сообщение Aug 30 2013, 15:10
Сообщение #10


Знающий
****

Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467



Цитата(vassabi @ Aug 30 2013, 10:47) *
Может я что-то не понимаю, но как вы в битовое поле длиной один бит хотите воткнуть char, т.е. 8 бит?
Согласно справочника по С, битовое поле может быть signed или unsigned.
Если вы хотите unsigned char, то наверное нужно хотябы длинну поля указать :8...

Кто хочет? Я?


--------------------
Верить нельзя никому, даже себе. Мне - можно.
Go to the top of the page
 
+Quote Post
SSerge
сообщение Aug 30 2013, 16:13
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528



Цитата(vassabi @ Aug 30 2013, 21:47) *
Может я что-то не понимаю, но как вы в битовое поле длиной один бит хотите воткнуть char, т.е. 8 бит?
Согласно справочника по С, битовое поле может быть signed или unsigned.
Если вы хотите unsigned char, то наверное нужно хотябы длинну поля указать :8...

Я правильно понял, что в Вашей версии С невозможны поля длиной меньше 8 бит?


--------------------
Russia est omnis divisa in partes octo.
Go to the top of the page
 
+Quote Post
vassabi
сообщение Aug 30 2013, 16:18
Сообщение #12


Частый гость
**

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



Цитата("SSerge")
Я правильно понял, что в Вашей версии С невозможны поля длиной меньше 8 бит?
Не правильно. Читайте внимательно.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Aug 30 2013, 16:34
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 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".
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Aug 30 2013, 18:26
Сообщение #14


Знающий
****

Группа: Участник
Сообщений: 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;

………….

Go to the top of the page
 
+Quote Post
Oleg_IT
сообщение Sep 1 2013, 06:35
Сообщение #15


Знающий
****

Группа: Свой
Сообщений: 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;
Go to the top of the page
 
+Quote Post
Oleg_IT
сообщение Sep 2 2013, 08:56
Сообщение #16


Знающий
****

Группа: Свой
Сообщений: 922
Регистрация: 3-06-05
Из: Москва
Пользователь №: 5 709



VAI спасибо, #pragma anon_unions помогла.
Go to the top of the page
 
+Quote Post
pitt
сообщение Sep 3 2013, 12:54
Сообщение #17


Местный
***

Группа: Участник
Сообщений: 328
Регистрация: 1-06-06
Из: USA
Пользователь №: 17 672



Просто хочу, как бывший советский гражданин, дать несколько советов.
Когда имеете дело со структурами, особенно отображающими пакеты данных, не забывайте endianness(простите не знаю как по-русски). Кроме того, советую включать файл stdint.h и использовать типы int8_t, uint16_t и тому подобное- это существенно облегчает как понимание, так и переносимость кода.



--------------------
Прокричал немой глухому:"...Спасибо за внимание!"
http://www.youtube.com/watch?v=3Nnj4ky4Z_g
Go to the top of the page
 
+Quote Post
Oleg_IT
сообщение Sep 4 2013, 11:31
Сообщение #18


Знающий
****

Группа: Свой
Сообщений: 922
Регистрация: 3-06-05
Из: Москва
Пользователь №: 5 709



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

Спасибо, учёл.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Sep 4 2013, 11:47
Сообщение #19


Беспросветный оптимист
******

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



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

По-русски это будет эндианность sm.gif
А я вообще не рекомендую мапить протоколы на структуры, потому как нарвался однажды на грабельное поле, и связано это было с выравниванием.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
alx.bilous
сообщение Sep 4 2013, 12:32
Сообщение #20


Участник
*

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



И какой в этом вообще смысл?

чем это бы отличалось если не использовать вложенную анонимную структуру вообще.
Go to the top of the page
 
+Quote Post
pitt
сообщение Sep 4 2013, 20:42
Сообщение #21


Местный
***

Группа: Участник
Сообщений: 328
Регистрация: 1-06-06
Из: USA
Пользователь №: 17 672



Цитата(MrYuran @ Sep 4 2013, 07:47) *
А я вообще не рекомендую мапить протоколы на структуры, потому как нарвался однажды на грабельное поле, и связано это было с выравниванием.

А вот это напрасно. Если кто-то упаковывается данные, то, скорее всего, кто-то будет распаковывать. Такие вещи хорошо включать в заголовочный файл, который используется с обеих сторон.
Выравнивание часто действительно может стать проблемой, но это другая тема. Особенно важно структурированность пакетов передачи и, по умолчанию, выравнивание побайтное. Подавляющее большинство компиляторов позволяют выравнивать так как надо заказчику. Методы могут быть различными.


--------------------
Прокричал немой глухому:"...Спасибо за внимание!"
http://www.youtube.com/watch?v=3Nnj4ky4Z_g
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Sep 4 2013, 21:16
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 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.

Вывод: использовать битовые поля при работе с внешними данными нельзя. Вообще нельзя.

Ну, добавим пару исключений:
- можно в рамках одной архитектуры и компилятора (что очевидно)
- можно в случае проверки корректности упаковки на этапе сборки
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 5 2013, 03:08
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 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 (для этого устройства) и надо описать протокол взаимодействия - это можно делать в одном файле просто копируя его между двумя проектами.
Go to the top of the page
 
+Quote Post
Oleg_IT
сообщение Sep 5 2013, 10:35
Сообщение #24


Знающий
****

Группа: Свой
Сообщений: 922
Регистрация: 3-06-05
Из: Москва
Пользователь №: 5 709



Цитата(MrYuran @ Sep 4 2013, 15:47) *
По-русски это будет эндианность sm.gif
А я вообще не рекомендую мапить протоколы на структуры, потому как нарвался однажды на грабельное поле, и связано это было с выравниванием.

Я эту "проблему" решаю так
Код
#pragma push
#pragma pack(1)
……………………
#pragma pop

Предпочитаю структуры, нагляднее. Встречал код, где данные в выходной массив просто по смещениям вписываются. Мне не нравится. Вообще - на вкус и цвет, главное что бы работало и правильноsm.gif.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 5 2013, 11:30
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Oleg_IT @ Sep 5 2013, 16:35) *
Я эту "проблему" решаю так
...

Лучше:
#pragma pack(push, 1)
#pragma pack(pop)
Но только это к сожалению не во всех компиляторах работает.
Go to the top of the page
 
+Quote Post
pitt
сообщение Sep 5 2013, 22:26
Сообщение #26


Местный
***

Группа: Участник
Сообщений: 328
Регистрация: 1-06-06
Из: USA
Пользователь №: 17 672



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

Сообщение отредактировал pitt - Sep 5 2013, 22:28


--------------------
Прокричал немой глухому:"...Спасибо за внимание!"
http://www.youtube.com/watch?v=3Nnj4ky4Z_g
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th July 2025 - 17:43
Рейтинг@Mail.ru


Страница сгенерированна за 0.01605 секунд с 7
ELECTRONIX ©2004-2016