SapegoAL 0 24 июня, 2013 Опубликовано 24 июня, 2013 · Жалоба Есть структура. Вся структура константная (размещается во флэши). В ней есть 2 поля int. Дописывал функционал. Ввёл ещё одно поле, которое определяет тип констант. И работаю с ними поразному - или как с int32 или как с float. А вот при заполнении такой структуры вываливается ошибка. Как правильно записать, чтобы компилятор понял, что я от него хочу? typedef const struct { const int32_t *Index; // Указатель на редактируемый параметр/ смещение для каналов const uint16_t Ch; // 0/ Указатель на канал const uint8_t fSignEn; // Отображение знака числа const uint8_t LenDig; // Число цифр в числе (0 - гашение незначащих нулей) const uint8_t DigAfterDot; // Число цифр после точки (0 - точки нет) const uint8_t DigType; // Тип результирующего числа (0 - int8, 1 - int16, 2 - int32, 3 - float) const int32_t min,max; // минимальное и максимальное значение (если <min, то min, если >max, то max) const uint16_t typeEditing; // возможножность редактирования void (*savefunc)(void); // Указатель на функцию записи редактируемых параметров const char* const* NameUnits; // наименование единиц измерения } DigEditing_t; //*************************************************************** // @@ 23155. Диаметр трубопровода 1 DigEditing_t dgeD12_1 = // Меню "Диаметр трубопровода" { 0, // непрямое offsetof(PipelineChanal_t,QConfChanal[0])+offsetof(QConfChanal_t,dia_D12), // 0, // неотображать знак 7, 3, // 3 знака, нет запятой (int32_t)1.0,(int32_t)5.0e3, // min,max 3, // float PRGEDIT, 0, // Редактировать по паролю, не сохранять (сохранять по выходу из PRG) &strMm // "мм" }; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 24 июня, 2013 Опубликовано 24 июня, 2013 · Жалоба Как правильно записать, чтобы компилятор понял, что я от него хочу? В gcc делаю так: //----------------------------------------------------------------------------- // typedef struct sPARAM //----------------------------------------------------------------------------- typedef struct sPARAM { int delta; DWORD act_datetime; BYTE park_mask; BYTE wait_on; BYTE wait_period; BYTE pre_on; BYTE pre_period; BYTE fin_on; BYTE fin_period; BYTE to_pre; BYTE to_fin; BYTE to_done; BYTE l_pre; BYTE l_fin; BYTE to_btn_press; BYTE to_btn_release; union { DWORD flags; struct { union { WORD ev_msk; struct { WORD ev_msk_total:1; WORD ev_msk_restart:1; WORD ev_msk_power_fail:1; WORD ev_msk_enter:1; WORD ev_msk_start:1; WORD ev_msk_release:1; WORD ev_msk_enable:1; WORD ev_msk_disable:1; WORD ev_msk_reserv:8; }; }; WORD btn_inv:1; WORD box_led_inv:1; WORD flags_reserv:14; }; }; } sPARAM; //----------------------------------------------------------------------------- // const sPARAM param_default //----------------------------------------------------------------------------- const sPARAM param_default = { delta: 0, // delta act_datetime: ACT_ALWAYS,// ACT_NEVER, park_mask: 0, wait_on: RED_TIME(0.2), wait_period: RED_TIME(3.0), pre_on: RED_TIME(0.2), pre_period: RED_TIME(0.5), fin_on: RED_TIME(1.0), fin_period: RED_TIME(1.0), to_pre: TO_TIME(1.0), to_fin: TO_TIME(10.0), to_done: TO_TIME(2.0), l_pre: DISTANCE(1.0), l_fin: DISTANCE(0.4), to_btn_press: TO_BTN(1.0), to_btn_release: TO_BTN(1.0), ev_msk: 0, btn_inv: 0, box_led_inv: 0, }; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 24 июня, 2013 Опубликовано 24 июня, 2013 · Жалоба Спасибо. Подумал про union, но немноого не в том ключе. Переклинило чего-то. Как-то я вообще очень редко union применяю. Непроходит. У меня IAR. Объявил тип: typedef union { float f; int32_t i; } variant_t; теперь изменил строчку структуры на const variant_t min,max; // минимальное и максимальное значение (если <min, то min, если >max, то max) Работаю соответственно с min.i и min.f. Всё прекрасно (собственно как и было). При заполнении структуры IAR не даёт указать имя поля (как у Вас). И присваивает все значения как float. хотя я и ставлю L для константы например 200L Как ему указать что из union заполнять? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 79 24 июня, 2013 Опубликовано 24 июня, 2013 · Жалоба есть еще дурацкий вариант сконвертировать float в int руками: http://www.h-schmidt.net/FloatConverter/ 5e3 == 0x459c4000 и еще более дурацкий - сделать такой ковертер на препроцессоре :). по поводу инициализации uniona в IARе: приведение руками к нужному типу вроде должно работать (int) 0x4444, (float) 5e-3 постфикс L после константы вроде только на длину указывает, а не на тип. ну то есть 5000L - long int, 5000.0L - double Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 24 июня, 2013 Опубликовано 24 июня, 2013 · Жалоба Как ему указать что из union заполнять? Не уверен, но кажется это фича gcc, а не языка C. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 24 июня, 2013 Опубликовано 24 июня, 2013 · Жалоба есть еще дурацкий вариант сконвертировать float в int руками :rolleyes: Так я так и делал. )) Но хочется, чтобы кто-нибудь потом разобрался ... )) У меня много таких данных. Это менюшка крупного прибора. Приведение сейчас попробую Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 24 июня, 2013 Опубликовано 24 июня, 2013 · Жалоба по поводу инициализации uniona в IARе: приведение руками к нужному типу вроде должно работать (int) 0x4444, (float) 5e-3 Не поможет. int и float легко преобразуются друг в друга С приведением типа. Причем преобразуются правильно - т.е. из целого он сделает плавающее, и наоборот. Т.е. побитовое представление изменится. Что бы оно не менялось, нужно преобразовывать через указатели: как то так - *(int32_t*)(float*)&<ваша константа>. Но для констант это пройти не должно :( Если у вас есть C++ то вас спасет reinterpret_cast<int32_t>(5e-3f) (не забудьте про суффикс f в константе - без него это будет double, и reinterpret_cast не сработает) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 79 24 июня, 2013 Опубликовано 24 июня, 2013 · Жалоба Не поможет. int и float легко преобразуются друг в друга С приведением типа. Причем преобразуются правильно - т.е. из целого он сделает плавающее, и наоборот. Т.е. побитовое представление изменится. это понятно, вопрос был про инициализацию uniona и там вроде как именно по типу должно определяться какое именно поле инициализируется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 24 июня, 2013 Опубликовано 24 июня, 2013 · Жалоба В QT, кстати, те же проблемы. Тему не закрываю. Интересно кто и как с такими вопросами борется. Для С++ тоже актуально. Я свою проблему решил. Я сделал две идентичных структуры. Одну с полями int, вторую с полями float. При обработке поступаю как и прежде. А при ображении к структуре всё работает. //*************************************************************** // @@ 15. MenuItem_t mnuitSysClock[5] = // Меню "Настройка часов"/ Пункты меню { {&imCorrClock, // Коррекция времени @@ 151 0,MenuTimeCorr,0,MenuTimeHlp}, {&imLocalClock, // Местное время @@ 152 0,MenuTimeEdit,0,MenuTimeHlp}, {&imTimeZone, // Часовой пояс @@ 153 (struct Menu_t *)&dgeTimeZone,EditIntCh,0,TimeZoneHlp}, {&imSumWin, // Летнее/зимнее @@ 154 (struct Menu_t *)&rbtSumWin,RadioBtnCh,0,RadioBtnHlp}, {&imCorrFreq, // Коррекция генератора @@ 155 (struct Menu_t *)&dgeFreqRtcCorr,EditIntCh,0,EditIntHlp}, }; struct Menu_t mnuSysClock = // Меню "Настройка часов" {5,mnuitSysClock}; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 24 июня, 2013 Опубликовано 24 июня, 2013 · Жалоба это понятно, вопрос был про инициализацию uniona и там вроде как именно по типу должно определяться какое именно поле инициализируется.Не должно. Стандарт С99, раздел 6.7.8 (Initialization), пункт 17,18: 17. Each brace-enclosed initializer list has an associated current object. When no designations are present, subobjects of the current object are initialized in order according to the type of the current object: array elements in increasing subscript order, structure members in declaration order, and the first named member of a union.127) In contrast, a designation causes the following initializer to begin initialization of the subobject described by the designator. Initialization then continues forward in order, beginning with the next subobject after that described by the designator.128) 18. Each designator list begins its description with the current object associated with the closest surrounding brace pair. Each item in the designator list (in order) specifies a particular member of its current object and changes the current object for the next designator (if any) to be that member.129) The current object that results at the end of the designator list is the subobject to be initialized by the following initializer. Сноски 127,128: 127) If the initializer list for a subaggregate or contained union does not begin with a left brace, its subobjects are initialized as usual, but the subaggregate or contained union does not become the current object: current objects are associated only with brace-enclosed initializer lists. 128) After a union member is initialized, the next object is not the next member of the union; instead, it is the next subobject of an object containing the union. Так что увы, тип константы полностью игнорируется. Но в том же С99 есть синтаксис инициализации с указанием конкретного поля (a-la GCC, но немного по другому) initializer: assignment-expression { initializer-list } { initializer-list , } initializer-list: designationopt initializer initializer-list , designationopt initializer designation: designator-list = designator-list: designator designator-list designator designator: [ constant-expression ] . identifier Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 24 июня, 2013 Опубликовано 24 июня, 2013 · Жалоба 2 XVR. :beer: Проверил - работает. Правда только для union можно указать. :a14: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Fujitser 0 25 июня, 2013 Опубликовано 25 июня, 2013 · Жалоба Однозначно только union. Для доступа к полям union можно применять конструкции вида: struct { int x, y, z; } point = { .y=10, .z=20, .x=30 }; (стандарт с99, в c++ работать не будет). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться