Jump to content
    

Перенос кода в среду IAR

Добрый день, коллеги!

Переношу проект, написанный в AVR Studio 4 под WinAvr, в среду IAR

Столкнулся с тем, что IAR ругается на такую конструкцию (ошибка Pe513):

 

ssp.spiHwInit=(void *)atmega_spi_init;

 

где объявления даны следующим образом:

 

euint8 atmega_spi_init(atmegaSpiInterface *iface);

 

и

struct SdSpiProtocol
{
    void *spiHwInterface;
    euint8 (*spiHwInit)(void* spiHwInterface);
    euint8 (*spiSendByte)(void* spiHwInterface,euint8 data);
};
typedef struct SdSpiProtocol SdSpiProtocol;

Подскажите, пожалуйста, как ее правильно описать в IAR?

Edited by IgorKossak
[codebox] для длинного кода. [code]-для короткого!!! Лишние пустые строки!

Share this post


Link to post
Share on other sites

Очевидно, компилируете в режиме Си++. Не надо так делать. Пусть будет просто тёплый ламповый Си.

Share this post


Link to post
Share on other sites

Очевидно, компилируете в режиме Си++. Не надо так делать. Пусть будет просто тёплый ламповый Си.

Да нет, проверил, в настройках стоит С. C dialect C99

Share this post


Link to post
Share on other sites

Да нет, проверил, в настройках стоит С. C dialect C99

А, не заметил, что, очевидно, указатель на функцию приводите к void* и присваиваете другому указателю на функцию. Это безобразие. Если какой-то компилятор такое проглатывал, то это неправильный компилятор.

Можно сделать вот так:

ssp.spiHwInit=(euint8 (*)(void*))atmega_spi_init;

Но необходимость приведения типа указателя на функцию настораживает, конечно. Кто придумал всё это безобразие?

Share this post


Link to post
Share on other sites

А, не заметил, что, очевидно, указатель на функцию приводите к void* и присваиваете другому указателю на функцию. Это безобразие. Если какой-то компилятор такое проглатывал, то это неправильный компилятор.

Можно сделать вот так:

ssp.spiHwInit=(euint8 (*)(void*))atmega_spi_init;

Но необходимость приведения типа указателя на функцию настораживает, конечно. Кто придумал всё это безобразие?

 

Winavr такое проглатывает..... другой разработчик давно написал этот код. Работало и работало. Пока не появилась необходимость что-то поменять.

 

Спасибо огромное! Заработало! Только... теперь я не понимаю, как эта конструкция построена. Так сложно на первый взгляд. Спасибо еще раз!

Почему-то без приведения типа компилятор тоже выдает ошибку... меня это тоже смущает.

Edited by IgorKossak
бездумное цитирование

Share this post


Link to post
Share on other sites

теперь я не понимаю, как эта конструкция построена. Так сложно на первый взгляд.

Приведение к типу "указатель на функцию". Ну да, с непривычки странно выглядит.

 

Почему-то без приведения типа компилятор тоже выдает ошибку... меня это тоже смущает.

Надо смотреть, какой тип у ssp.spiHwInit. Очевидно, какой-то другой, раз компилятор жалуется без приведения типа.

Share this post


Link to post
Share on other sites

Надо смотреть, какой тип у ssp.spiHwInit. Очевидно, какой-то другой, раз компилятор жалуется без приведения типа.

Так в первом сообщении всё есть.

Поле в структуре описано как указатель на функцию, принимающую указатель на void и возвращающую euint8,

а ему пытаются присвоить указатель на функцию, принимающую указатель на atmegaSpiInterface и возвращающую euint8.

Ясное дело, без явного преобразования типа такое делать нельзя, и преобразование к типу void* не поможет.

Вот если наоборот - полю типа void* можно присваивать любой указатель. Но тогда для вызова функции по такому указателю потребуется преобразование его типа в тип, соответствующий вызываемой функции, что открывает массу возможностей для ошибок.

 

Вообще, передача в функции указателей на структуры и наличие в структурах указателей на функции верный признак того, что рамки С коду уже тесны и пора переходить на С++, а не заниматься имитацией на С классов и виртуальных функций.

Share this post


Link to post
Share on other sites

Только... теперь я не понимаю, как эта конструкция построена. Так сложно на первый взгляд.

 

Более наглядная конструкция:

*((void**)&ssp.spiHwInit) = (void*)atmega_spi_init;

 

 

Share this post


Link to post
Share on other sites

Более наглядная конструкция:

*((void**)&ssp.spiHwInit) = (void*)atmega_spi_init;

Так это же совсем другая семантика. Не будет работать, короче.

Share this post


Link to post
Share on other sites

Так это же совсем другая семантика. Не будет работать, короче.

Зависит от модели памяти: требуется совпадение физических размеров "DATA pointer" и "FUNC pointer", тогда будет работать.

Но пример приведен как альтернатива для понимания.

Правильно будет использовать Ваш вариант приведения.

Share this post


Link to post
Share on other sites

Но пример приведен как альтернатива для понимания.

Что-то я в звёздочках запутался. Вроде бы должно и эдак получиться :laughing:

 

Share this post


Link to post
Share on other sites

Спасибо большое вам за комментарии и разъяснения!

 

Более наглядная конструкция:

*((void**)&ssp.spiHwInit) = (void*)atmega_spi_init;

 

Нет, пожалуй, первая конструкция мне понятнее :)

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...