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

 
 
> безымянные struct и union, WinAVR
ARV
сообщение Jul 28 2010, 07:31
Сообщение #1


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

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



расширение GNU для GCC вводит возможность задавать в структурах безымянные поля типа struct или union, например, так:
Код
typedef struct {
  uint8_t fix;
  union {
      uint8_t param;
      void *ptr;
   };
}flex_struct_t;

flex_struct_t rec;
и потом в зависимости от условий обращаться rec.param или rec.ptr, как будто эти поля родные для структуры. все хорошо (если не считать того, что Eclipse такой записи не понимает и не подсказывает при вводе имена этих объединенных полей), пока не начинаешь запихивать такие структуры во flash:
Код
PROGMEM flex_struct_t fixed = {.fix=0, .param = 123};
приводит к ошибке unknown field 'param' specified in initializer

вопрос, как обычно, традиционный: что делать? это баг или фича?


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
ARV
сообщение Jul 29 2010, 11:48
Сообщение #2


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

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



до этого предположения я как бы дошел, но у меня закономерный вопрос: а какого, извините, амперсенда, компилятор понимает, что при обращении надо перебрать все имена полей - и перебирает!!! - а при инициализации надо ограничиваться только первыми? я ведь инициализирую с ЯВНЫМ указанием имен полей!!!


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jul 29 2010, 12:29
Сообщение #3


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(ARV @ Jul 29 2010, 14:48) *
я ведь инициализирую с ЯВНЫМ указанием имен полей!!!
Полей. да не тех. Эти поля он ищет в первом элементе охватывающего объединения, так как имя поля этого объединения не указано.
Ну когда допиливали GNU exts до неименованных полей, место с инициализацией union трогать почему-то не стали, оставили по стандарту.
Точнее, одну фишку добавили - "union cast", пример из предыдущего моего сообщения можно переписать так
Код
typedef union {
    char c;
    double d;
} u_t;

u_t foo = (u_t)5.0;
и оно чудненько сообразит проинициализировать double-часть.

Но в данном случае даже вместе с C99 compound literals оно не помогает, где-то задалбывается и литерал не считает константой (впрочем, кажется, по C99 compound literal есть отдельный неименованный временный объект, потому он и не рассматривается как константа). Компилировать с -fms-extensions, нужно для отмеченных мест
Код
typedef struct {
    prog_char    *text;
    uint8_t        type;
    union outer {  /* -fms-extensions */
        struct simplei { /* -fms-extensions */
            union{
                uint8_t id;
                int        *num;
            };
            func_ptr    func;
        };
        struct vari { /* -fms-extensions */
            uint8_t        vcnt;
            uint8_t        *vid;
            prog_char    **var;
        };
        _tm    submenu;
    };
} menu_item_t;

typedef struct {
    uint8_t itemcount;
    menu_item_t items[];
} menu_t;

enum { i_simple, i_int, i_var, i_sub };

#define simple_item(t,i,f)    {.text = t, .type = i_simple, (union outer)(struct simplei){{.id=i}, .func = f} }
#define int_item(t,n,f)        {.text = t, .type = i_int, (union outer)(struct simplei){{.num = n}, .func = f} }
#define var_item(t,c,vi,v)    {.text = t, .type = i_var, (union outer)(struct vari){.vcnt=0} }
#define sub_item(t,s)        {.text = t, .type = i_sub, {.submenu = s}}

Цитата
uni_2.c:53: error: initializer element is not constant
uni_2.c:53: error: (near initialization for ‘mainmenu.items[0].<anonymous>’)
и для остальных элементов то же самое


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jul 30 2010, 09:51
Сообщение #4


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(ReAl @ Jul 29 2010, 15:29) *
Но в данном случае даже вместе с C99 compound literals оно не помогает

Увы.
compound literals удобны, но генерирующийся временный объект не даёт инициализировать статические данные, поэтому тут не проходит.
Если бы не это, то прошло бы. А так выходит ошибка, аналогичная
Код
int i1 = 5;
int i2 = i1; // error: initializer element is not constant


А -fms-extensions нужен только для того, чтобы дать имена типам структур неименованных полей и само по себе оно работает.

p.s. то, что на avrfreaks предложили — на мой взгляд, некрасиво. Хотя, конечно, "работать будет".

Несколько "причесать" предложение с avrfreaks (как-то гарантировать одинаковость структур — неименованной и вспомогательной) это вот -fms-extensions таки поможет
Код
typedef struct {
    union{
        uint8_t id;
        int        *num;
    };
    func_ptr    func;
} simple_t;

typedef struct {
    uint8_t        vcnt;
    uint8_t        *vid;
    prog_char    **var;
} var_t;

typedef struct {
    prog_char    *text;
    uint8_t        type;
    union {
        simple_t;  // это неименованные для работы
        var_t;
        _tm    submenu;
        // вспомогательные для инициализации
        simple_t simple_helper; // первая не нужна, но для однообразия пусть будет
        var_t var_helper;
    };
} menu_item_t;


Но всё равно как-то… Хотя "будут, будут одинаковые структуры одинаково расположены", но "некрасиво".


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- ARV   безымянные struct и union   Jul 28 2010, 07:31
- - MrYuran   Цитата(ARV @ Jul 28 2010, 11:31) все хоро...   Jul 28 2010, 07:44
- - dimka76   а если попробовать проинитить так КодPROGMEM flex...   Jul 28 2010, 07:49
|- - ARV   Цитата(dimka76 @ Jul 28 2010, 11:49) а ес...   Jul 28 2010, 07:57
|- - dimka76   Цитата(ARV @ Jul 28 2010, 11:57) Цитата(d...   Jul 28 2010, 08:00
- - ARV   если инициализировать переменную - ошибка все равн...   Jul 28 2010, 07:50
- - MrYuran   А если так: КодPROGMEM flex_struct_t fixed = {.fix...   Jul 28 2010, 07:54
- - IgorKossak   QUOTE ... Eclipse такой записи не понимает и не по...   Jul 28 2010, 09:00
|- - ARV   Цитата(IgorKossak @ Jul 28 2010, 13:00) H...   Jul 28 2010, 10:58
- - MrYuran   что-то у вас странное... Цитата#define var_item(t,...   Jul 28 2010, 11:46
|- - ARV   Цитата(MrYuran @ Jul 28 2010, 15:46) что-...   Jul 28 2010, 12:02
- - MrYuran   Что-то вы перемудрили... Как можно инициализироват...   Jul 28 2010, 12:12
- - ARV   почему все? я инициализирую только в одном вариант...   Jul 28 2010, 12:17
- - ARV   Жаль, что все знатоки Си, которых тут немало, не ж...   Jul 29 2010, 09:35
|- - ReAl   Цитата(ARV @ Jul 29 2010, 12:35) Жаль, чт...   Jul 29 2010, 11:32
- - dimka76   Кодunion{ uint8_t id; int *num; }; Вы...   Jul 29 2010, 10:30
|- - ARV   Цитата(dimka76 @ Jul 29 2010, 14:30) Кодu...   Jul 29 2010, 10:42
- - neiver   А это стандарт такой в Си, что можно инициализиров...   Jul 29 2010, 12:09
- - ARV   что-то не выходит каменный цветок и с -fms-extensi...   Jul 30 2010, 04:20
- - ARV   на avrfreaks в очередной раз посоветовали написать...   Jul 30 2010, 10:58
- - ARV   все-таки на avrfreaks подали идею, как выкрутиться...   Jul 30 2010, 18:10
- - ReAl   Цитата(ARV @ Jul 30 2010, 21:10) все-таки...   Jul 30 2010, 18:21


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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 03:50
Рейтинг@Mail.ru


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