Перейти к содержанию
    

Перенос кода в среду 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?

Изменено пользователем IgorKossak
[codebox] для длинного кода. [code]-для короткого!!! Лишние пустые строки!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

 

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

 

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

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

Изменено пользователем IgorKossak
бездумное цитирование

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

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

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

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

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...