|
куча const..., элементарный вопрос по Си |
|
|
|
Aug 29 2009, 05:26
|
Частый гость
 
Группа: Свой
Сообщений: 82
Регистрация: 14-03-06
Из: Санкт-Петербург
Пользователь №: 15 227

|
Дожился...  Помогите чайнику. Итак... вводная: пользую PIC24H, пишу на Си (без плюсов), компилятор - С30, уже скурил весь гугль, учебники по сям... имею определение интерфейса (структуру указателей на функции): Код typedef struct { void (*FunctionPointer) (char Param); int (*OtherFuncPointer) (int SomeParam); .... } PWInterface, *pPWInterface, **ppPWInterface; Далее имеется несколько модулей, реализующих некое поведение и предоставляющих указанный интерфейс: Код заголовочный файл: extern const PWInterface const PWMonitor0; Код сишный файл с реализацией: static void SomeFunc1 (char Param); static void SomeFunc2 (int SomeParam);
const PWInterface const PWMonitor0 = { &SomeFunc1, &SomeFunc2, .... }; ну и далее реализация этих функций. таких модулей несколько, все предоставляют означенный в начале интерфейс. Т.е. я сознательно выделяю память в памяти программ и пишу дважды const. Далее собираю интерфейсы в одну кучу: Код #include "PWMonitor0.h" #include "PWMonitor1.h" #include "PWMonitor2.h" ....................
const PWInterface *const PWMonMode1Arr[] = {&PWMonitor0, &PWMonitor0_c, &PWMonitor0_r}; const PWInterface *const PWMonMode2Arr[] = {&PWMonitor1, &PWMonitor1_r}; const PWInterface *const PWMonMode3Arr[] = {&PWMonitor2}; Т.е. массивы константных указателей на константные структуры заданного типа. конструкцию представленную выше компилятор поглощает без проблем, а если же пользую Код const pPWInterface const PWMonMode1Arr[] = ... получаю warning: initialization discards qualifiers from pointer target typeВопрос первый: Что именно я недопонимаю? Хотел как лучше (чтоб через typedef... красившее. Вроде корректно определенный тип указателя при определении структуры)... Продолжу... далее имея массивы(константные) (константных)указателей на (константные)интерфейсы, собираю их в свою очередь в массив(тоже константный): Код const ppPWInterface const Pathways[] = {&PWMonMode1Arr, &PWMonMode2Arr, &PWMonMode3Arr};
чтоб можно было бы где-то в коде сказать нечто подобное: result = Pathways[PowerMode][ID]->OtherFuncPointer(somecode); Вот тут(при определении массива, а не на вызове метода интерфейса) уже имею трижды warning: initialization from incompatible pointer typeПробовал разные вариации... но, видимо, не все... Вопрос второй: как сделать правильно? Компилятор, в общем-то, понимает что я от него хочу. Память распределяет правильно, инициализирует правильно, все компилируется... но этот варнинг... я ж из-за него невыспался.  Уфффф... спасибо за терпение дочитавшим сий опус
|
|
|
|
|
 |
Ответов
|
Aug 29 2009, 14:26
|
Местный
  
Группа: Участник
Сообщений: 328
Регистрация: 23-05-08
Пользователь №: 37 760

|
Я чайник  . И помочь ничем не смогу. Но хочу спросить (в целях самообразования) - а что значит вот это объявление? Цитата(cf7k @ Aug 29 2009, 09:26)  Код заголовочный файл: extern const PWInterface const PWMonitor0; Я в смысле как это укладывается в общую схему объявления переменной? [класс памяти] [const] тип имя [инициализатор] - в данном случае [класс памяти] -extern, тип - структура с именем PWInterface, определенным с помощью typedef, имя переменной - PWMonitor0.... А второй const (...PWInterface const PWMonitor0) - это что такое? А то получается что-то наподобие "extern const int const var1".... Здесь мне тоже ничего не понятно: Цитата(cf7k @ Aug 29 2009, 09:26)  Код const PWInterface const PWMonitor0 = { &SomeFunc1, &SomeFunc2, .... }; Надеюсь, мне по ходу дела объясните  .
|
|
|
|
|
Aug 29 2009, 15:18
|
Частый гость
 
Группа: Свой
Сообщений: 82
Регистрация: 14-03-06
Из: Санкт-Петербург
Пользователь №: 15 227

|
Цитата(Student Pupkin @ Aug 29 2009, 18:26)  Я чайник  . И помочь ничем не смогу. Но хочу спросить (в целях самообразования) - а что значит вот это объявление? Цитата extern const PWInterface const PWMonitor0; То же, что и полное объявление вместе с инициализацией, но в заголовочный файл вынесено только имя. Т.к. стоит extern - я сообщаю, что полное объявление с инициализацией существует где-то, а другим модулям достаточно знать имя, тип и "модифицируемость" объекта - всё, чтоб обратиться к нему, а компилятору сгенерировать код. Цитата(Student Pupkin @ Aug 29 2009, 18:26)  Я в смысле как это укладывается в общую схему объявления переменной? [класс памяти] [const] тип имя [инициализатор] - в данном случае [класс памяти] -extern, тип - структура с именем PWInterface, определенным с помощью typedef, имя переменной - PWMonitor0.... А второй const (...PWInterface const PWMonitor0) - это что такое? А то получается что-то наподобие "extern const int const var1".... Я исходил из следующих утверждений: Код int *int_ptr; // Модифицируемый указатель на модифицируемый объект const int *int_ptr; // Модифицируемый указатель на константный объект int * const int_ptr; // Константный указатель на модифицируемый объект const int * const int_ptr; // Константный указатель на константный объект Хотя это касается указателей.... а в моем примере... гм... как-то даже по-русски не получается... первый const - разместить в памяти программ, второй -... возможно лишний, но результат компиляции не меняется... возможно пока гонялся за указателями - намудрил лишнего... Цитата(Student Pupkin @ Aug 29 2009, 18:26)  Здесь мне тоже ничего не понятно: Код const PWInterface const PWMonitor0 = { &SomeFunc1, &SomeFunc2, .... }; Надеюсь, мне по ходу дела объясните  . Идея такова: хочу инициализированную структуру, полям которой при инициализации присвоены указатели на функции. Далее считаю, что сами эти функции константы (собсно адреса никуда не перемещаются, и изменять их не надо) - ставлю второй const; далее хочу чтоб сия структура была компилятором создана в памяти программ, а не в секции данных, которая инициализируется все равно из памяти программ в startup коде - вот появляется первый const. Вот примерно таковы мои рассуждения... Цитата(Dog Pawlowa @ Aug 29 2009, 19:11)  Я делаю все попроще.
typedef void (*VECTORS)(); const VECTORS function[FUNCTION_QTY]={function1, function2, };
вызов: function[function_index]();
Поэтому первый вопрос к Вам - зачем указатели на адрес функции, если можно хранить собственно адрес функции. Возможно я некорректно выразился, но ведь в инициализированной структуре хранятся адреса функций. Поэтому первичная структура избыточность не содержит. Далее я объявлял массив содержащий указатели на структуры с адресами функций. Цель всей этой затеи - в зависимости от двух параметров, которые выступают индексами по массивам, вызывать нужную функцию. Реализовать пытался без использования "марсианских писем"... так сказать - попонятней.
|
|
|
|
|
Aug 29 2009, 16:30
|
Местный
  
Группа: Участник
Сообщений: 328
Регистрация: 23-05-08
Пользователь №: 37 760

|
Цитата(cf7k @ Aug 29 2009, 19:18)  Хотя это касается указателей.... а в моем примере... гм... как-то даже по-русски не получается... первый const - разместить в памяти программ, второй -... возможно лишний, но результат компиляции не меняется... возможно пока гонялся за указателями - намудрил лишнего... Угумс  . Про указатели (константный указатель на константу) я знаю. А вот подобное объявление переменных - первый раз вижу (хотя я и так мало чего видел пока в жизни  ). Ну так может попробовать "возможно лишние" const убрать? А то как-то не по ANSI/ISO получается  ... И второй вопрос - Цитата(cf7k @ Aug 29 2009, 19:18)  Далее считаю, что сами эти функции константы А смысл? Если структура объявлена константой, то ее поля изменять нельзя... И потом - по логике константы должны размещаться в ROM. И еще сами функции размещаются в ROM, значит их адреса фиксированы... Идею использовать для указателя на функцию уточнение, что он указывает на константный объект не понимаю - это лишь необходимо для предотвращения изменений объекта, на который ссылаемся (в общем случае... для embedded-случаев это еще указывает на то, что объект будет размещен в секции констант, расположенной в ROM). В случае, если объект, на который указывает указатель, - функция, то его и поменять то невозможно... Он в ROM расположен (если специально никаких усилий на то, чтобы разместить функцию в RAM, не предпринималось).... Да и зачем менять то? На ходу править код функции? P.S. Если я чего-то недопонимаю - надеюсь, мне тут объяснят
Сообщение отредактировал Student Pupkin - Aug 29 2009, 16:34
|
|
|
|
|
Aug 29 2009, 17:06
|
Частый гость
 
Группа: Свой
Сообщений: 82
Регистрация: 14-03-06
Из: Санкт-Петербург
Пользователь №: 15 227

|
Цитата(Student Pupkin @ Aug 29 2009, 20:30)  Угумс  . ... Ну так может попробовать "возможно лишние" const убрать? А то как-то не по ANSI/ISO получается  ... Так уже пробовал, пока писал предыдущий пост - компилятор понимает и так и так... Но для порядку причесал. Цитата(Student Pupkin @ Aug 29 2009, 20:30)  А смысл? Если структура объявлена константой, то ее поля изменять нельзя... И потом - по логике константы должны размещаться в ROM. И еще сами функции размещаются в ROM, значит их адреса фиксированы... ...... Ну смысла не много - наверно для выразительности. Я в отрочестве не был сионистом  . Сначала строил структуру, далее инициализировал её указателями (адресами функций) - вот и поставил средний const (сами указатели ж у меня констанстные - хотя для функций это скорее всего само собой разумеющееся). Далее все это разместил в ПЗУ приписав первый const. Вот так и родил монстра  Но компилятор уживается с этим монстром. Меня ж более интересует последний монстр - "массив указателей на массивы указателей на структуры" (и это все в ПЗУ).
|
|
|
|
|
Aug 29 2009, 18:25
|
Местный
  
Группа: Участник
Сообщений: 328
Регистрация: 23-05-08
Пользователь №: 37 760

|
Цитата(cf7k @ Aug 29 2009, 21:06)  Меня ж более интересует последний монстр - "массив указателей на массивы указателей на структуры" (и это все в ПЗУ). Попробовал проделать аналогичное в Visual Studio 2008: CODE // Пустые функции (чтобы было) void func1(int a) { }; void func2(int a) { };
typedef struct { void (*func1)(int); void (*func2)(int); } PWInterface;
/* Здесь с помощью макроподстановки я определяю имя pConstPWInterfaceConst для константного указателя на структуру-константу PWInterface*/ #define pConstPWInterfaceConst const PWInterface *const
/* Таким способом не получается: typedef PWInterface *pPWInterface; */
const PWInterface PWMonitor1 = {func1, func2}; const PWInterface PWMonitor2 = {func2, func1};
pConstPWInterfaceConst PWMonitorPtr1 = &PWMonitor1; /* Таким способом не получается: 1)Ошибка компиляции (повторное использование const): const pPWInterface const PWMonitorPtr1 = &PWMonitor1; 2) Ошибка компиляции (несовместимость квалификаторов типов, т.е. указателю присваивается адрес константного объекта, чего нет в объявлении самого указателя): const pPWInterface PWMonitorPtr1 = &PWMonitor1; */ Мысли по этому поводу такие - Действительно, если писать что называется в лоб
Код const PWInterface *const PWMonitor1 = &PWMonitor1; то никаких ошибок - Если с помощью typedef определить имя pPWInterface для указателя на структуру PWInterface, то запись вида
Код const pPWInterface const PWMonitorPtr1 = &PWMonitor1; получится неверной. Видимо, подобная запись соответствует общей схеме объявления переменной - Код [класс памяти] [const] ТИП ИМЯ [инициализатор] Как видите, в этой схеме места для еще одного const нет. Вы можете только таким способом объявить указатель-константу (массив указателей-констант), но не можете сообщить, что это указатель на объект-константу (а способом в п.1 можете ) - Тоже самое происходит при попытке объявить массив указателей на указатели (есесно все там const - лень писать просто
) - Предлагаю писать в лоб (не вводите с помощью typedef имена "*pPWInterface" и "**ppPWInterface")
- Если не хотите в лоб, то воспользуйтесь define, как в моем куске (не знаю, как там насчет портируемости, эстетики, красоты и т.д., но такой способ работает, все компилится без ошибок и предупреждений). Там есесно упрощенно, но таким макаром можно и массив... И для указателя на указатель можно тоже аналогичный дефайн написать...
|
|
|
|
Сообщений в этой теме
cf7k куча const... Aug 29 2009, 05:26 Dog Pawlowa Цитата(cf7k @ Aug 29 2009, 08:26) Дожился... Aug 29 2009, 15:11 AHTOXA Цитата(cf7k @ Aug 29 2009, 11:26) Кодcons... Aug 29 2009, 19:06 Student Pupkin Цитата(AHTOXA @ Aug 29 2009, 23:06) Я сил... Aug 29 2009, 20:23 cf7k Цитата(AHTOXA @ Aug 29 2009, 23:06) Я сил... Aug 29 2009, 20:35  AHTOXA Цитата(cf7k @ Aug 30 2009, 02:35) Гм... л... Aug 29 2009, 21:06   cf7k Цитата(AHTOXA @ Aug 30 2009, 01:06) Со вт... Aug 29 2009, 21:15    Student Pupkin Цитата(cf7k @ Aug 30 2009, 01:15) warning... Aug 29 2009, 21:18    AHTOXA Цитата(cf7k @ Aug 30 2009, 03:15) warning... Aug 29 2009, 21:36    Student Pupkin Цитата(cf7k @ Aug 30 2009, 01:15) КодСо в... Aug 29 2009, 21:43     AHTOXA Цитата(Student Pupkin @ Aug 30 2009, 03:4... Aug 29 2009, 21:54      Student Pupkin Цитата(AHTOXA @ Aug 30 2009, 01:54) Я име... Aug 29 2009, 22:01       cf7k Цитата(Student Pupkin @ Aug 30 2009, 02:0... Aug 30 2009, 17:46  Student Pupkin Ну а если так:
Код/* Вводим тип структура-констант... Aug 29 2009, 21:13   cf7k Цитата(Student Pupkin @ Aug 30 2009, 01:1... Aug 29 2009, 21:20
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|