Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Мудрёная операция с указателями в IAR C
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
Д_М
Приветствую!
Имеется структура и переменная - указатель, которая хранит адрес этой структуры.
Обращение к полям структуры через указатель Syst->SIO1.CRC;
Проверено, работает. Ничего удивительного. Решил в указатель загрузить адрес поля этой структуры
crc = &Syst->SIO1.CRC;
Компилятор ругается. Собственно, почему? Технически такое корректно. Меня в своё время очень удивило, что в качестве аргумента можно передавать адреса локальных переменных. Здесь ещё менее хитро, а компилятор ругается.
Сергей Борщ
QUOTE (Д_М @ Dec 20 2017, 21:02) *
Компилятор ругается. Собственно, почему?
Потому что вы что-то написали неправильно. Не видя конкретного сообщения компилятора сказать что-либо точнее невозможно (телепатия барахлит).
jcxz
Цитата(Д_М @ Dec 20 2017, 21:02) *
Компилятор ругается. Собственно, почему? Технически такое корректно.

С чего бы это?

Цитата(Д_М @ Dec 20 2017, 21:02) *
а компилятор ругается.

И правильно делает. Берёте указатель на один тип, и пытаетесь присвоить его указателю другого типа.
Если CRC - типа int, то &Syst->SIO1.CRC - имеет тип указателя int *, а не указателя на структуру.

PS: И чего собственно мудрёного-то тут?
ViKo
Потому что у полей нет адресов.
Д_М
Объявления
unsigned int *crc;
syspar Sys; // Декларация структуры типа syspar
__no_init volatile syspar *Syst @0x0100;


Syst = &Sys;
crc = &Syst->SIO1.CRC; // Ругается компилятор
crc = &Sys.SIO1.CRC;



Error[Pe513]: a value of type "unsigned int volatile *" cannot be assigned to an entity of type "unsigned int *"
kolobok0
Цитата(ViKo @ Dec 20 2017, 22:29) *
Потому что у полей нет адресов.


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

2копикастер
в подобных случая нужно
1) привести полностью код влияющий на ругань. т.е. все используемые типы и саму операцию, которую не пропускает компилятор.
Чтоб не париться - обычно делается так. Заводите болванку типа одной функции майн. и вставляете туда свою строчку которая с проблемой. копируете всё необходимое так-же.
проверяете компиляцию. зачастую на этом этапе вы сами с успехом найдёте свою ошибку в большинстве случаев. если проблема всё равно осталась и мысли закончились - только после этого постите
проблему на форум.
2) как уже прозвучало выше - надо привести оригинал ругани.

удачи вам
(круглый)

Цитата(Д_М @ Dec 20 2017, 22:35) *
...Error[Pe513]: a value of type "unsigned int volatile *" cannot be assigned to an entity of type "unsigned int *"


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

попробуйте явно привести ручками тип один к другому. показывая компилятору что Вы знаете о траблах в коде и берёте на себя всю ответственность за результат.
jcxz
Цитата(Д_М @ Dec 20 2017, 21:35) *
Error[Pe513]: a value of type "unsigned int volatile *" cannot be assigned to an entity of type "unsigned int *"

Syst - имеет модификатор типа "volatile" и, соответственно любой член объекта на который он указывает, автоматом имеет этот модификатор.
А Вы пытаетесь указатель на такой тип присвоить обычному указателю без типа volatile. На что Вам и указывает компилятор.
Приведение указателя без модификатора "volatile", к указателю имеющему такой модификатор (указателю такого же типа) - это разрешённая операция и выполняется без ошибки и без варнинга.
Обратная операция - запрещена (ну т.е. требует явного указания такого приведения).
Что является логичным, зная что такое "volatile".
Д_М
extern unsigned int CRC(char data, unsigned int crc, unsigned int poly);

void MB1_Send(void)
{
union
{
char *ch;
int *ui;
}target;
unsigned char
amount = Syst->SIO1.amount,
data = *Syst->SIO1.ptr;

if(Syst->SIO1.size < amount)
{
Syst->SIO1.CRC = CRC(*Syst->SIO1.ptr, Syst->SIO1.CRC, SIO1_poly); // Ругается компилятор
Syst->SIO1.CRC = CRC(data, Syst->SIO1.CRC, SIO1_poly); // Не ругается компилятор

Тоже самое, но через промежуточную локальную переменную.
Сергей Борщ
QUOTE (Д_М @ Dec 21 2017, 12:18) *
// Ругается компилятор
Теперь он, наверное, ругается иначе? Пришет что-то про неопределенный порядок доступа к volatile-переменным в выражении? А вы принципиально не хотите прочитать то, что пишет вам компилятор?
aiwa
Вы умолчали, что компилятор ругается на
Цитата
data = *Syst->SIO1.ptr;


Если Syst - это указатель на структуру, то *Syst - это уже ссылка на структуру и синтакстически требуется точка:
Syst->SIO1.CRC = CRC((*Syst).SIO1.ptr, Syst->SIO1.CRC, SIO1_poly); // Ругается компилятор




jcxz
Цитата(aiwa @ Dec 21 2017, 15:09) *
Если Syst - это указатель на структуру, то *Syst - это уже ссылка на структуру и синтакстически требуется точка:

Нет. Операция -> имеет приоритет выше чем операция разыменования указателя *.

PS: Топик стоит перенести в раздел: "Предлагаю работу" с заголовком: "Ищу телепата". Автор сознательно пытается поиграть тут в шараду, а не ищет реально решение проблемы. А мы ведёмся... laughing.gif
x893
Видимо лень читать гугло-поиск или на крайний случай книгу.
jcxz
Цитата(x893 @ Dec 21 2017, 15:58) *
Видимо лень читать гугло-поиск или на крайний случай книгу.

видимо лень прочитать даже советы озвученные тут laughing.gif
aiwa
Цитата(jcxz @ Dec 21 2017, 15:56) *
Нет. Операция -> имеет приоритет выше чем операция разыменования указателя *.


В смысле ptr - указатель на char-подобный вид?
В таком случае на инициализацию data была бы точно такая же ругань компилятора, как и при вызове функции.
jcxz
Цитата(aiwa @ Dec 21 2017, 17:14) *
В смысле ptr - указатель на char-подобный вид?

В смысле - я читаю то, что написано у ТС. А не пытаюсь придумать, что же он хотел там написать. А написано там: взять значение члена "SIO1.ptr", а затем его разыменовать.
А Вы пытаетесь придумать "Что бы там такое другое могло быть?". Но если так, то почему бы например не предположить что автор там хотел написать скажем "*Syst-SIO1.ptr" или что ещё другое? Тогда можно вообще 100500 вариантов придумать.
Цитата(aiwa @ Dec 21 2017, 17:14) *
В таком случае на инициализацию data была бы точно такая же ругань компилятора, как и при вызове функции.

А Вы обратите внимание что и при инициализации data и при вызове функции выражение-то одно и то же "*Syst->SIO1.ptr".
Если бы ругалось на него, то в обоих случаях должно. А значит - видимо с ним всё нормально.
aiwa
Цитата(jcxz @ Dec 21 2017, 19:04) *
А Вы пытаетесь придумать "Что бы там такое другое могло быть?".

Имхо, в этом и вся суть темы.

Цитата(jcxz @ Dec 21 2017, 19:04) *
А Вы обратите внимание что и при инициализации data и при вызове функции выражение-то одно и то же "*Syst->SIO1.ptr".
Если бы ругалось на него, то в обоих случаях должно. А значит - видимо с ним всё нормально.


Именно об этом я и говорю. Не хватает ругани: должно быть как минимум две.
Хотя можно предположить, что во втором случае в "SIO1" затесалась "О" кириллицей.
jcxz
Цитата(aiwa @ Dec 21 2017, 19:24) *
Хотя можно предположить, что во втором случае в "SIO1" затесалась "О" кириллицей.

Там можно что угодно предположить так как это игра в угадайку.
Сергей Борщ
QUOTE (jcxz @ Dec 21 2017, 19:46) *
Здесь телепаты нужны. laughing.gif
Не ссорьтесь. Там в вызове функции есть два обращения к volatile-переменным. Телепатирую, что компилятор справедливо выдает предупреждение о неопределенном порядке доступа к этим переменным. Но автор темы почему-то стесняется привести нам текст этого предупреждения.
jcxz
Цитата(Сергей Борщ @ Dec 21 2017, 19:50) *
Там в вызове функции есть два обращения к volatile-переменным. Телепатирую, что компилятор справедливо выдает предупреждение о неопределенном порядке доступа к этим переменным.

Да, так скорее всего и есть. Чуть позже это заметил. sm.gif
Д_М
Когда делаю вот так
Syst->SIO1.CRC = CRC(*Syst->SIO1.ptr, Syst->SIO1.CRC, SIO1_poly);

Компилятор выдаёт следующее предупреждение:
Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement D:\Work\MC\Gateway\Actual\Modbus_master1.c 170

И ещё выдаёт такое же предупреждение, когда делаю так
if(Syst->SIO1.size < Syst->SIO1.amount)
{
}

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

Кажется распутал.
Причина оказалась в том, что указатель размещается в строго определённом физическом адресе.
__no_init volatile syspar *Syst @0x0100;
Так нужно для совместного обращения из applycation и boot секторов.

Если сделать просто syspar *Syst;
То никакой ругани нет.
Сергей Борщ
QUOTE (Д_М @ Dec 21 2017, 22:30) *
когда в одной команде дважды фигурирует обращение к структуре, через указатель.
Ну раз вы не хотите читать не только сообщения компилятора, но и то, что вам отвечают на форуме - пусть будет так. Пусть он не любит через указатель. Смиритесь.
Д_М
Большое спасибо за помощь!
jcxz
Цитата(Сергей Борщ @ Dec 21 2017, 22:32) *
Ну раз вы не хотите читать не только сообщения компилятора, но и то, что вам отвечают на форуме - пусть будет так. Пусть он не любит через указатель. Смиритесь.

Может у ТС доступ write-only на форум? cool.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.