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

 
 
> куча const..., элементарный вопрос по Си
cf7k
сообщение Aug 29 2009, 05:26
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 82
Регистрация: 14-03-06
Из: Санкт-Петербург
Пользователь №: 15 227



Дожился... smile.gif Помогите чайнику.

Итак... вводная: пользую 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
Пробовал разные вариации... но, видимо, не все...
Вопрос второй: как сделать правильно?

Компилятор, в общем-то, понимает что я от него хочу. Память распределяет правильно, инициализирует правильно, все компилируется... но этот варнинг... я ж из-за него невыспался. wink.gif

Уфффф... спасибо за терпение дочитавшим сий опус smile.gif
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
AHTOXA
сообщение Aug 29 2009, 19:06
Сообщение #2


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(cf7k @ Aug 29 2009, 11:26) *
Код
const pPWInterface    const PWMonMode1Arr[] = ...
получаю warning: initialization discards qualifiers from pointer target type
Вопрос первый: Что именно я недопонимаю? Хотел как лучше (чтоб через typedef... красившее. Вроде корректно определенный тип указателя при определении структуры)...


Я сильно не вчитывался, но вот такое
Код
typedef struct
{
    void (*FunctionPointer)  (char Param);
    int  (*OtherFuncPointer) (int SomeParam);
}const PWInterface, *pPWInterface;

const PWInterface const PWMonitor0 = {0, 0};
const PWInterface const PWMonitor2 = {0, 0};

const pPWInterface const PWMonMode1Arr[] = {&PWMonitor0, &PWMonitor2};


компилится без ворнингов. Добавил слово const в typedef.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
cf7k
сообщение Aug 29 2009, 20:35
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 82
Регистрация: 14-03-06
Из: Санкт-Петербург
Пользователь №: 15 227



Цитата(AHTOXA @ Aug 29 2009, 23:06) *
Я сильно не вчитывался, но вот такое
.......
компилится без ворнингов. Добавил слово const в typedef.

Гм... любопытный подход... возьму на заметку. Пасиба.
Код
вместо
const PWInterface    *const PWMonMode1Arr[] = {&PWMonitor0, &PWMonitor0_c, &PWMonitor0_r};
получилось то что хотелось:
const pPWInterface const PWMonMode1Arr[] = {&PWMonitor0, &PWMonitor2};

Но это "уровень 1" массива.



Цитата(Student Pupkin @ Aug 29 2009, 22:25) *
Попробовал проделать аналогичное в Visual Studio 2008:
....
Мысли по этому поводу такие
  1. Если не хотите в лоб, то воспользуйтесь define, как в моем куске (не знаю, как там насчет портируемости, эстетики, красоты и т.д., но такой способ работает, все компилится без ошибок и предупреждений). Там есесно упрощенно, но таким макаром можно и массив... И для указателя на указатель можно тоже аналогичный дефайн написать...

вот с дефайном не получилось - на самом деле я не define задаю, а пишу в лоб (ну что там вынести для красоты - это уже другое дело).

Пока самый человеко понятный код у меня такой:
Код
const ppPWInterface const Pathways[]    = {(ppPWInterface)(&PWMonMode1Arr), (ppPWInterface)(&PWMonMode2Arr), (ppPWInterface)(&PWMonMode2Arr)};
В общем-то и в объявлении есть двойной указатель и const'ы там где хочется... но... все же хочется знать, как это делается без коррекции типа, так сказать, по правилам языка.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Aug 29 2009, 21:06
Сообщение #4


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(cf7k @ Aug 30 2009, 02:35) *
Гм... любопытный подход... возьму на заметку. Пасиба.
Но это "уровень 1" массива.

Со вторым уровнем всё проще. Имя массива является указателем на первый его элемент, потому не надо писать & в
const ppPWInterface const Pathways[] = {&PWMonMode1Arr, &PWMonMode2Arr, &PWMonMode3Arr};

Короче, вот оба уровня, с учётом замечаний студента Пупкина:
Код
typedef struct
{
    void (*FunctionPointer)  (char Param);
    int  (*OtherFuncPointer) (int SomeParam);
}WInterface;

typedef WInterface const PWInterface;
typedef PWInterface* const pPWInterface;
typedef pPWInterface* const ppPWInterface;

const PWInterface PWMonitor0 = {0, 0};
const PWInterface PWMonitor2 = {0, 0};

const pPWInterface PWMonMode1Arr1[] = {&PWMonitor0, &PWMonitor2};
const pPWInterface PWMonMode1Arr2[] = {&PWMonitor0, &PWMonitor2, &PWMonitor0};
const pPWInterface PWMonMode1Arr3[] = {&PWMonitor2, &PWMonitor0};

const ppPWInterface final_array[] ={ PWMonMode1Arr1, PWMonMode1Arr2, PWMonMode1Arr3};


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
cf7k
сообщение Aug 29 2009, 21:15
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 82
Регистрация: 14-03-06
Из: Санкт-Петербург
Пользователь №: 15 227



Цитата(AHTOXA @ Aug 30 2009, 01:06) *
Со вторым уровнем всё проще. Имя массива является указателем на первый его элемент, потому не надо писать & в
const ppPWInterface const Pathways[] = {&PWMonMode1Arr, &PWMonMode2Arr, &PWMonMode3Arr};

const ppPWInterface final_array[] ={ PWMonMode1Arr1, PWMonMode1Arr2, PWMonMode1Arr3};[/code]

warning: initialization discards qualifiers from pointer target type
Go to the top of the page
 
+Quote Post
Student Pupkin
сообщение Aug 29 2009, 21:43
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 328
Регистрация: 23-05-08
Пользователь №: 37 760



Цитата(cf7k @ Aug 30 2009, 01:15) *
Код
Со вторым уровнем всё проще. Имя массива является указателем на первый его элемент, потому не надо писать & в
const ppPWInterface const Pathways[] = {&PWMonMode1Arr, &PWMonMode2Arr, &PWMonMode3Arr};

const ppPWInterface final_array[] ={ PWMonMode1Arr1, PWMonMode1Arr2, PWMonMode1Arr3};

warning: initialization discards qualifiers from pointer target type

Кстати да smile.gif. Правильно писать
Код

ppPWInterface final_array[] ={ PWMonMode1Arr1, PWMonMode1Arr2, PWMonMode1Arr3};
или так
ppPWInterface final_array[] ={ &PWMonMode1Arr1[0], &PWMonMode1Arr2[0], &PWMonMode1Arr3[0]};

Тоже самое касается и указателей на функцию. При инициализации структуры PWInterface надо писать просто имена функций, которые сами по себе являются указателями.
Код

PWInterface PWMonitor1 = {func1, func2,...}

Хотя здесь, насколько я знаю, стандарт допускает и запись вида {&func1, &func2, ...}

Цитата(AHTOXA @ Aug 30 2009, 01:36) *
Проверьте на VS, если не трудно.

Никакого мошенства. Я это сначала предварительно в VS проверил, прежде чем здесь писать. smile3046.gif
Правда объявлял не массивы, а переменные, но сути это не меняет. Главное варнингов нет smile.gif .
CODE

typedef const struct
{
void (*func1)(int);
void (*func2)(int);
} PWInterface;
typedef PWInterface *const pPWInterface;
typedef pPWInterface *const ppPWInterface;


PWInterface PWMonitor1 = {func1, func2};
PWInterface PWMonitor2 = {func2, func1};

pPWInterface PWMonitorPtr1[] = {&PWMonitor1, &PWMonitor2};
ppPWInterface ptrPWMonitorPtr1 = PWMonitorPtr1;
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Aug 29 2009, 21:54
Сообщение #7


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Student Pupkin @ Aug 30 2009, 03:43) *
Никакого мошенства. Я это сначала предварительно в VS проверил, прежде чем здесь писать. smile3046.gif


Я имел в виду - проверить мой, исправленный вариантsmile.gif

Хотя теперь наши варианты практически совпадаютsmile.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Student Pupkin
сообщение Aug 29 2009, 22:01
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 328
Регистрация: 23-05-08
Пользователь №: 37 760



Цитата(AHTOXA @ Aug 30 2009, 01:54) *
Я имел в виду - проверить мой, исправленный вариантsmile.gif

Хотя теперь наши варианты практически совпадаютsmile.gif

Проверил - все OK. То что доктор прописал smile.gif .
Go to the top of the page
 
+Quote Post
cf7k
сообщение Aug 30 2009, 17:46
Сообщение #9


Частый гость
**

Группа: Свой
Сообщений: 82
Регистрация: 14-03-06
Из: Санкт-Петербург
Пользователь №: 15 227



Цитата(Student Pupkin @ Aug 30 2009, 02:01) *
Проверил - все OK. То что доктор прописал smile.gif .

Супер. Действительно медицина способна на многое smile.gif

Для себя взял на заметку возможность создания константного типа, хотя все же остановился на неконстанстном типе структуры и отдельном описании константной структуры.
Позволю себе подвести резюме... так сказать решение для тех, кто потом будет искать:
Код
//по моим (стереотипам) убеждениям - тип - это некий "трафарет" для выделения блока памяти и он не должен зависеть от того, в какой памяти память выделяется.
typedef struct
{
    void (*FunctionPointer)  (char Param);
    int  (*OtherFuncPointer) (int SomeParam);
}PWInterface;                    //я все же вернулся к имени PWInterfae от предложенного WInterface (оно у меня от PathWayInterface)

typedef   PWInterface     const   cPWInterface;   //"трафарет" для выделения памяти под структуру в ПЗУ
typedef  cPWInterface    *const  pcPWInterface;
typedef pcPWInterface    *const ppcPWInterface;

//выделение памяти в ПЗУ
cPWInterface PWMonitor0 =
{
    SomeFunc1,    //допустимо через &SomeFunc1
    SomeFunc2
};

//массивы указателей на структуры с адресами функций ("уровень 1") в ПЗУ
pcPWInterface    PWStartArr[]      = {&PWMonitor0, &PWMonitor1, &PWMonitor2, &PWMonitor3};    //адрес структуры - с "&"
pcPWInterface    PWMonitorArr[]    = {&PWMonitor4, &PWMonitor5};
pcPWInterface    PWStopArr[]       = {&PWMonitor6, &PWMonitor7, &PWMonitor8};

//массив указателей на массивы с указателями на структуры с адресами функций ("уровень 2") в ПЗУ
ppcPWInterface    Pathways[]    = {PWStartArr, PWMonitorArr, PWStopArr};

//пример обращения к методу интерфейса
result = Pathways[SomeMode][SomePWID]->OtherFuncPointer(SomeParamValue);

под C30 все работает.
Спасибо Student Pupkin и AHTOXA за оказанную помощь в разрешении проблемы.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- cf7k   куча const...   Aug 29 2009, 05:26
- - Student Pupkin   Я чайник . И помочь ничем не смогу. Но хочу спрос...   Aug 29 2009, 14:26
|- - cf7k   Цитата(Student Pupkin @ Aug 29 2009, 18:2...   Aug 29 2009, 15:18
|- - Student Pupkin   Цитата(cf7k @ Aug 29 2009, 19:18) Хотя эт...   Aug 29 2009, 16:30
|- - cf7k   Цитата(Student Pupkin @ Aug 29 2009, 20:3...   Aug 29 2009, 17:06
|- - Student Pupkin   Цитата(cf7k @ Aug 29 2009, 21:06) Меня ж ...   Aug 29 2009, 18:25
- - Dog Pawlowa   Цитата(cf7k @ Aug 29 2009, 08:26) Дожился...   Aug 29 2009, 15:11
- - Student Pupkin   Цитата(AHTOXA @ Aug 29 2009, 23:06) Я сил...   Aug 29 2009, 20:23
|- - 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   Ну а если так: Код/* Вводим тип структура-констант...   Aug 29 2009, 21:13
- - cf7k   Цитата(Student Pupkin @ Aug 30 2009, 01:1...   Aug 29 2009, 21:20


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

 


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


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