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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> sizeof union, Си
sigmaN
сообщение Oct 14 2009, 19:07
Сообщение #1


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Код
typedef union
{
    int    asHeader;

    struct
    {
        int                    header;
        int                    int1;
        int                    int2;
        int                    int3;
    }asInt3;

    struct
    {
        int                    header;
        char                     array[30];
    }asArray;
}my_union;

const int asInt3_size = sizeof(my_union.asInt3); // error: expected a ")" т.е. предлагает мне сделать sizeof(my_union);

А я бы очень хотел получить размеры каждого члена(или как там правильно его назвать) юниона.

Задумка такая: одной переменной описать три разных типа пакета, отличающиеся длиной и типом поля data.
Однако первые n байт всех трёх типов пакетов одинаковы и соответствуют заголовку(header).
Отправлять планируется в зависимости от надобности либо sizeof(my_union.asHeader); либо sizeof(my_union.asInt3) либо sizeof(my_union.asArray); байтов.
Header содержит поле, описывающее тип пакета, соответственно принемающая сторона всегда будет знать как трактовать пришедший пакет, сначала проанализировав это поле по my_union.asHeader;
К тому-же иногда(для подтверждения доставки) достаточно отправить просто asHeader.

Привлекательность состоит в том, что весь union займет в памяти столько месте, сколько необходимо для самого жирного члена(sizeof(asArray)) а AsHeader будет равен asArray.header и asInt3.header - потому как по идее &my_union_var.asHeader == &my_union_var.asInt3.header == &my_union_var.asArray.header

Верно ли последнее предположение по поводу header и как взять sizeof от члена union?
Или же поступить проще и определить структуры asHeader, asInt3, asArray отдельными typedef'ами, а union просто будет:
Код
typedef union
{
    asHeader_type    asHeader;
    asInt3_type    asInt3;
    asArray_type    asArray;
}my_union;

const int asInt3_size = sizeof(asInt3_type);


P.S. Ссылочку на стандарт С99 мне подкинули, но оказалось что сходу там ответ найти бывает очень сложно. smile.gif


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Oct 14 2009, 19:15
Сообщение #2


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Код
const int asInt3_size = sizeof(my_union.asInt3);

const int asInt3_size = sizeof(((my_union *)0)->asInt3);


Один из вариантов должон сработать. Проверять лень.

-------------
PS. отредактировано уже после нижестоящего поста.

Сообщение отредактировал GetSmart - Oct 14 2009, 19:50


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Oct 14 2009, 19:29
Сообщение #3


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Т.е. всё-таки рекомендуется пойти по второму пути и определить asInt3_type отдельным typedef? Этот вариант резервный smile.gif
Больше меня интересует почему не работает первоначальный вариант(первый codebox) и как выкрутиться без правки union.

added: да да, работает и так. const int asInt3_size = sizeof(((my_union *)0)->asInt3);
Просто меня сразу немного смутило, что вместо asInt3 было asInt3_type smile.gif

added later:Нда, Си мощная штука smile.gif))


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 14 2009, 19:39
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(sigmaN @ Oct 15 2009, 01:07) *
Или же поступить проще и определить структуры asHeader, asInt3, asArray отдельными typedef'ами, а union просто будет:
Не люблю union-ы sad.gif Может я не совсем правильно понял, но вы ведь работаете с буфером, так? А кто вам мешает работать с буфером с помощью указателя? Причем указатель можно объявить любого из трех типов и соответственно работать со структурой именно того типа, который в данный момент нужен. Ну а с выбором наибольшего sizeof от каждой структуры у вас надеюсь нет проблем?
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Oct 14 2009, 19:41
Сообщение #5


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(sigmaN @ Oct 15 2009, 01:29) *
Т.е. всё-таки рекомендуется пойти по второму пути и определить asInt3_type отдельным typedef? Этот вариант резервный smile.gif

Не, я тут как бы опечатался. Хотел внутри sizeof() написать имя поля, а не его тип. Тип поля писать внутри структуры внутри sizoef() вообще бессмысленно.

Сообщение отредактировал GetSmart - Oct 14 2009, 19:43


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Oct 14 2009, 20:56
Сообщение #6


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Ну как сказать. можно и указатели, можно и разные типы. В функции можно передавать void *, а там уже делать с ним что хочешь.

А почему не любите? Я тут как-бы может быть слегка вдохновленный возможностями Си и разошелся маленько. В общем суть такова:
Код
/*
*    Размер пакета может меняться в зависимости от настройки алгоритма(размер блока, размер поля ID(публ. ключа))
*
*    Нам нужны пакеты двух типов
*    1.ID-пакет: используется для передачи ID абонентов и ID корпорации
*    2.Block-пакет: предназначен для транспорта данных длиной в 1 блок(хэш-функция, случайная выборка)
*    Но для унификации функций обработки пакетов яввел union ba05_net_packet
*/
enum conn_stages{ public_keys_interchange, random_sample_interchange, hash_interchange };//стадии соединения
enum packetTypes{ IDPacket, BlockPacket };
//заголовок у обоих типов пакетов общий, поэтому опишем его один раз
typedef struct
{
    enum packetTypes    packetType;    
    enum conn_stages    connStageID;
    unsigned            needACK    : 1;    //сообщает приёмнику, что в ответ на этот пакет нужно обязательно отправить ACK пакет
    unsigned            ACK        : 1;    //Признак пакета подтверждения. Если ACK==1 - все остальные поля не используются(кроме crc8,естественно)    
    unsigned             crc8     : 8;
}ba05_net_pktHeader;

//этот union позволяет использовать один тип данных(ba05_net_packet) для обоих типов пакетов.
typedef union
{
    ba05_net_pktHeader    header;                //иногда нужен _только_ заголовок пакета. К нему можно удобно обратиться :)
    struct
    {
        ba05_net_pktHeader    header;
        ba05_ID                master_ID;    
        ba05_ID                slave_ID;        
        ba05_ID                slave_corpID;    
    }asIDPacket;//1.ID-пакет: используется для передачи ID абонентов и ID корпорации
    struct
    {
        ba05_net_pktHeader    header;
        ba05_blockKey        data;
    }asBlockPacket;//2.Block-пакет: предназначен для транспорта данных длиной в 1 блок
}ba05_net_packet;

enum {     BlockPacketSize = sizeof(((ba05_net_packet *)0)->asBlockPacket),
        IDPacketSize = sizeof(((ba05_net_packet *)0)->asIDPacket),
        HeaderPacketSize = sizeof(((ba05_net_packet *)0)->header) };


По-моему достаточно элегантно выходит.
Но оценить объективно свой подход бывает достаточно сложно.

Поэтому реквестирую кАменты знатоков smile.gif


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
KRS
сообщение Oct 14 2009, 21:07
Сообщение #7


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Я бы в описаниях пакетов использовал типы с явным указанием количества бит!
А то у вас при компилляции для разных процессоров - структуры будут разные!
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Oct 14 2009, 21:13
Сообщение #8


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Взаимодействие систем по этому протоколу будет производиться ТОЛЬКО в сетях, состоящих из девайсов с одинаковыми типами процессоров.
Более того, типы данных ba05_ID и ba05_blockKey определены выше и именно с явным указанием размеров.
Единственное тут будет проблема с
unsigned needACK : 1; //сообщает приёмнику, что в ответ на этот пакет нужно обязательно отправить ACK пакет
unsigned ACK : 1; //Признак пакета подтверждения. Если ACK==1 - все остальные поля не используются(кроме crc8,естественно)
unsigned crc8 : 8;

т.к. паковаться битовые поля будут в int, размер которого действительно может быть различным.
added: нда, похоже и enum тоже implementation defined и могут быть те-же проблемы int


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
zltigo
сообщение Oct 14 2009, 21:28
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Для начала, union притянут за уши. Начните плясать от:
Код
typedef struct ba05_net_packet
{
    ba05_net_pktHeader    header;    //иногда нужен _только_ заголовок пакета. К нему можно удобно обратиться :)
union{
    asIDBody;
    ba05_blockKey;
};
}ba05_net_packet;

Структуру по любому паковать.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Oct 14 2009, 22:14
Сообщение #10


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Отлично!
Благодарю.

Действительно, немножко не с той стороны подошел smile.gif

Хорошо.
Тут вот более глубоко задумался над typedef....
видимо ещё паскалевский стиль мышления заставляет воспринемать структуру как новый тип данных(ну и, естественно, сразу в голову приходит typedef)

Так вот, собственно, так-же известно, что ту-же структуру можно определить без typedef, а потом точно так-же определять структурные переменные.
Вопрос в том, чем отличается
Цитата
struct my_struct
{
int field1;
int fieeld2;
};
//а потом
my_struct my_struct_var;
от
Цитата
typedef struct
{
int field1;
int fieeld2;
}my_struct;
//а потом
my_struct my_struct_var;

Разница ведь только в области видимости?
т.е. typedef действительно глобальный, а тег структуры(при объявлении по первому методу) будет иметь область видимости ограниченную файлом.
Я ничего не упустил?
А то наплодил typedef а теперь вот задумался, что может быть абсолютно напрасно smile.gif


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
KRS
сообщение Oct 15 2009, 08:03
Сообщение #11


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(sigmaN @ Oct 15 2009, 02:14) *
Разница ведь только в области видимости?

Если вы используете С++ то разницы нет!
А если С, то при каждом объявлении надо будет писать:
struct my_struct my_struct_var;
вот что бы не писать слово struct каждый раз и используют typedef.
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Oct 15 2009, 08:24
Сообщение #12


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Понятно. Значит буду продолжать typedef. В принципе он мне нравится


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
defunct
сообщение Nov 3 2009, 23:54
Сообщение #13


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(sigmaN @ Oct 15 2009, 10:24) *
Понятно. Значит буду продолжать typedef. В принципе он мне нравится


Тогда еще одит "trick" на примере приведенном zltigo

Код
typedef struct tag_ba05_net_packet
{
    struct tag_ba05_net_packet *pNextPacket;  // иногда полезно когда пакеты связаны

    ba05_net_pktHeader    header;    //иногда нужен _только_ заголовок пакета. К нему можно удобно обратиться :)
    union{
        asIDBody;
        ba05_blockKey;
    };
} ba05_net_packet_t, *ba05_net_packet_ptr_t;


Сразу и список пакетов формировать можно и указатель на пакет объявлен.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 4 2009, 21:56
Сообщение #14


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(defunct @ Nov 4 2009, 05:54) *
Код
    union{
        asIDBody;
        ba05_blockKey;
    };

Это что такое? Нетипизированные поля?


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
defunct
сообщение Nov 5 2009, 01:52
Сообщение #15


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(GetSmart @ Nov 4 2009, 23:56) *
Это что такое? Нетипизированные поля?

Этот кусочек я отцитировал.

Думаю там предполагались структуры:
Код
union
{
    zzz_t  zzz;
    xxx_t  xxx;
}
Go to the top of the page
 
+Quote Post

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

 


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


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