|
Инициализация структуры. Что не так?, Обращаюсь к коллективному разуму |
|
|
|
Sep 6 2012, 11:59
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Написал симулятор и отладил в QT4. Всё работает, достаточно объёмный проект. Начал переносить на целевую платформу в IAR. Споткнулся на ровном месте. Хотелось бы решить "в лоб", так как по-другому очень большой кусок работы. Помогите. Есть объявление структуры: Код // хранится во флэши typedef struct { int8_t *Index; // Указатель на редактируемый параметр/ смещение для каналов uint16_t Number; // Число пунктов uint16_t Ch; // 0/ Указатель на канал uint8_t *ItemName[]; // Указатели на имена пунктов } RadioBtn_t; Есть строки: Код uint8_t const sFlowControlComport[3][9] = {"None","Hard","Xon/Xoff"}; Есть объявление: Код //*************************************************************** // @@ 1312. Управление потоком RadioBtn_t rbtFlowControl = { 0, // Указатель на редактируемое значение 3, // Всего 3 пункта, ((uint32_t)&ComSetting[0].flowcontrol- (uint32_t)ComSetting), // flowcontrol {sFlowControlComport[NONE], sFlowControlComport[HARD], sFlowControlComport[SOFT]} }; Qt компилирует правильно и никаких вопросов у него это не вызывает У IAR ARM 6.4.02 возникает 2 ошибки 1 - в строке 4 структуры у него претензия, что это не константа, но на самом деле это смещение адресов и должно вычислятся на этапе компиляции. Не вижу здесь проблемы и QT тоже не видит. Как это объяснить IAR? 2 - IAR в строке 5 пишет: слишком много параметров инициализации. Честно говоря, тоже не вижу проблемы. Понятно что я могу указать лишь только имя масива и смещаться на длину элемента, но здесь я привожу только частный случай. Есть места, где это разные строки произвольной длины, так что такой метод не предлагать. Хотелось бы поэкономить место. Не хотелось бы также создавать отдельный масив указателей - тоже + 4 байта на один радиобутон. Поскольку элементов очень много, то будет набегать. Ну и QT почемуто понимает меня и работает как нужно. Поэтому непонятно ... Какие будут предложения? Заранее благодарю всех откликнувшихся ...
|
|
|
|
|
Sep 6 2012, 12:22
|

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

|
Цитата uint8_t const sFlowControlComport[3][9] = {"None","Hard","Xon/Xoff"}; Обычно это несколько по-другому пишется, если имеются в виду константные строки. uint8_t const* sFlowControlComport[3] = {"None","Hard","Xon/Xoff"}; По-моему, так. Компилятор составит таблицу указателей на ascii-строки
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Sep 6 2012, 12:39
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
По поводу ошибки номер раз. Воспользуйтесь дефайном offsetof()Он гораздо яснее для понимания задумки программера. Цитата(SasaVitebsk) Поскольку элементов очень много, то будет набегать. Ну и QT почемуто понимает меня и работает как нужно. Поэтому непонятно ... Напоминает Борланд Билдер, препроцессор и sizeof  Вопрос стоит как это должно быть по стандарту. С пояснением от какого года стандарт.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Sep 6 2012, 13:08
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(GetSmart @ Sep 6 2012, 16:39)  По поводу ошибки номер раз. Спасибо огромное. Ошибку номер раз закрыли. Цитата(MrYuran) Обычно это несколько по-другому пишется, если имеются в виду константные строки. Имеется ввиду именно это, но IAR не позволяет инициализировать двухмерный массив, если младшее измерение открыто. По-моему другие компиляторы тоже. То есть Ваше объявление не проходит. uint8_t const sFlowControlComport[3] = {"None","Hard","Xon/Xoff"}; Error[Pe144]: a value of type "char [5]" cannot be used to initialize an entity of type "unsigned char const [3]" E:\work\IAR C Proect\tm3\Source\var.c 86 Вот такое, естественно, пройдёт uint8_t const sFlowControlComport[] = {"None"};
|
|
|
|
|
Sep 6 2012, 13:27
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (SasaVitebsk @ Sep 6 2012, 16:08)  То есть Ваше объявление не проходит. uint8_t const sFlowControlComport[3] = {"None","Hard","Xon/Xoff"}; Error[Pe144]: a value of type "char [5]" cannot be used to initialize an entity of type "unsigned char const [3]" E:\work\IAR C Proect\tm3\Source\var.c 86 "Смешались в кучу кони, люди", uint8_t, char, указатели... Вы хотите массив из трех указателей на строки символов, а объявляете массив из трех беззнаковых 8-битных чисел. Попробуйте все же объявлять массив указателей, и указателей именно на char: char const * const sFlowControlComport[3] = {"None","Hard","Xon/Xoff"};
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 7 2012, 05:54
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Спасибо большое. Что-то вчера, к концу рабочего дня мозги уже не работали. Вариант "const uint8_t* const sFlowControlComport[3] = {"None","Hard","Xon/Xoff"};" работает, собственно как и мой первоначальный. Проблема то не в этом. Проблема в объявлении структуры Код // @@ 1312. Управление потоком RadioBtn_t rbtFlowControl = { 0, // Указатель на редактируемое значение 3, // Всего 3 пункта, offsetof(ComSetting_t,flowcontrol), // flowcontrol {sFlowControlComport[NONE], sFlowControlComport[HARD], sFlowControlComport[SOFT]} }; Error[Pe146]: too many initializer values E:\work\IAR C Proect\tm3\Source\MonoMenu\lcd_work.c 346 Объявление структуры - в посте выше. Ещё раз отмечаю - QT скомпилировал и прекрасно работал
|
|
|
|
|
Sep 7 2012, 06:03
|

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

|
Цитата(SasaVitebsk @ Sep 7 2012, 09:54)  Вариант "const uint8_t* const sFlowControlComport[3] = {"None","Hard","Xon/Xoff"};" работает, собственно как и мой первоначальный. Вот и чудненько. Код // @@ 1312. Управление потоком RadioBtn_t rbtFlowControl = { 0, // Указатель на редактируемое значение 3, // Всего 3 пункта, offsetof(ComSetting_t,flowcontrol), // flowcontrol sFlowControlComport[] };
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Sep 7 2012, 06:18
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Код typedef struct { int8_t* Index; uint16_t Number; uint16_t Ch; const char* const* ItemName; } RadioBtn_t;
const char* const sFlowControlComport[] = {"None", "Hard", "Xon/Xoff"};
const RadioBtn_t btn = { (void*)0, 0, 0, sFlowControlComport };
int main(void) { puts(btn.ItemName[0]); puts(btn.ItemName[1]); puts(btn.ItemName[2]);
return (0); } output: Код None Hard Xon/Xoff
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Sep 7 2012, 06:24
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Кстати, как-то не очень хорошо выглядит эта структура: Код typedef struct { int8_t *Index; uint16_t Number; uint16_t Ch; uint8_t *ItemName[]; } RadioBtn_t; В конце она содержит массив неопределённого размера. Лучше применить указатель на массив строк: Код typedef struct { int8_t *Index; uint16_t Number; uint16_t Ch; char const * const *ItemName; } RadioBtn_t;
|
|
|
|
|
Sep 7 2012, 07:38
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(scifi @ Sep 7 2012, 10:24)  Кстати, как-то не очень хорошо выглядит эта структура: В конце она содержит массив неопределённого размера. Именно это я и хотел! Я показал один вариант, когда у меня массив указателей, но в других элементах интерфейса, может быть просто несколько несвязанных указателей. Если я укажу просто масив указателей, то дополнительные затраты - 1 указатель. Элементов много и набежит прилично. Оно конечно не критично, но просто переписать придётся. Там где применены разрозменные строки, то надо добавить массив указателей.
|
|
|
|
|
Sep 7 2012, 08:09
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Не выйдет. Нельзя в си инициализировать константу константой... например так нельзя: Код const int x = 3; const int y = x; // никак, обидно:-( и так нельзя: Код const RadioBtn_t rbtFlowControl = { 0, 3, offsetof(ComSetting_t,flowcontrol), {sFlowControlComport[NONE], sFlowControlComport[HARD], sFlowControlComport[SOFT]} // это невозможно при наличии const квалификатора у типа этой rbtFlowControl структуры. }; разве что: Код typedef struct { int8_t* Index; uint16_t Number; uint16_t Ch; const char* ItemName[]; } RadioBtn_t;
const char sFlowControlComportNone[] = "None"; const char sFlowControlComportHard[] = "Hard"; const char sFlowControlComportXonXoff[] = "Xon/Xoff";
const RadioBtn_t btn = { (void*)0, 0, 0, { sFlowControlComportNone, sFlowControlComportHard, sFlowControlComportXonXoff } }; И keil и gcc (правда gcc только при включенной опции --pedantic) ругаются на сие, но по-разному: Код keil: main.c(26): error: #146: too many initializer values gcc: main.c:26:2: error: initialization of a flexible array member [-Werror=pedantic] Думаю, что keil не прав, но от этого вам не легче. И переписать всё-же придётся чтобы был нормально переносимый код. Я обычно когда сомневаюсь в чём-то (правда уже редко это бывает) сразу на разных компиляторах прогоняю тестики и делаю выводы о том что такое хорошо, а что такое плохо. Безотносительно даже стандарта Си... Вы кстати добавьте следующие ключи компиляции к gcc (если у вас он установлен) узнаете много нового о своих программах:-) -std=c99 -pedantic -Wall -Wextra -Werror
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|