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

 
 
 
Reply to this topicStart new topic
> Предупреждение от IAR
DVF
сообщение Jul 25 2012, 12:45
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 630
Регистрация: 26-07-06
Из: Саратов
Пользователь №: 19 097



Почему в данной ситуации получаю предупреждение: Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement?
Код
#pragma vector = TIMER1_COMPA_vect
__interrupt void TIMER1_COMPA(void)
{
  unsigned short data = (unsigned short)( (PIND & 0xF3) | ((PINB & 0x06)<<1) )
}
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Jul 25 2012, 12:53
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(DVF @ Jul 25 2012, 15:45) *
Почему в данной ситуации получаю предупреждение: Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement?
Код
#pragma vector = TIMER1_COMPA_vect
__interrupt void TIMER1_COMPA(void)
{
  unsigned short data = (unsigned short)( (PIND & 0xF3) | ((PINB & 0x06)<<1) )
}

Потому что в правой части выражения две volatile-переменных: PIND и PINB.
Можете заменить:
Код
unsigned char pind=PIND, pinb=PINB;
unsigned short data = (unsigned short)( (pind & 0xF3) | ((pinb & 0x06)<<1) );

и предупреждение исчезнет.
Go to the top of the page
 
+Quote Post
DVF
сообщение Jul 25 2012, 14:07
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 630
Регистрация: 26-07-06
Из: Саратов
Пользователь №: 19 097



Да, спасибо, такое проделывал. Просто думал, как бы это через макрос (#define) воплотить.
Go to the top of the page
 
+Quote Post
xemul
сообщение Jul 25 2012, 14:08
Сообщение #4



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Зачем усложнять жизнь компилятору?
Код
unsigned short data = PIND & 0xF3;
data |= (PINB & 0x06)<<1;
Go to the top of the page
 
+Quote Post
Xenia
сообщение Jul 25 2012, 16:38
Сообщение #5


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



О чем спор? Запретить выдавать Warning[Pa082] и дело с концом! sm.gif Тем более что средства для блокировки нежелательных варнингов у компилятора имеются.

Кстати, старые версии IAR на такие вещи не ругались. Да и здравый смысл протестует против такого варнинга, поскольку порядок выполнения операций (precedence) в выражениях жестко определен не только в C, но и в остальных языках программирования. А раз порядок выполнения операций в выражениях определен, то как может быть так, чтобы "accesses is undefined"? Очевидно, что accesses тут тот же самый, что и у порядка выполнения операций.

Вот если бы я так написала:
if( PIND < PINB) {}
то дело другое, тут бы я, пожалуй, не стала протестовать против данного варнинга.
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Jul 25 2012, 17:14
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата(_Артём_ @ Jul 25 2012, 15:53) *
Потому что в правой части выражения две volatile-переменных: PIND и PINB.
Можете заменить:
Код
unsigned char pind=PIND, pinb=PINB;
unsigned short data = (unsigned short)( (pind & 0xF3) | ((pinb & 0x06)<<1) );

и предупреждение исчезнет.


+1 за этот вариант.
Зафиксируете состояние пинов в текущий момент и будуту владеть более-менее актуальной информацией о них в текущий момент.
Запрещать варнинги связанные с предупреждениями о доступе к volatile-переменным не стоит. Они для того и созданы чтобы программист задумался о том, что некоторые переменные могут изменится (напрю в прерывании или другим неизвестным компилятору образом), пока идёт обработка различных сложных условий, приведённых в первом посте. Вместо PINB/D запросто могут быть переменные, значение которых изменяется в прерываниях. И если забыть о том что могут быть изменения значений переменных подобного рода, то можна напороться на необъяснимые поведения программы.

Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 25 2012, 19:01
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Xenia @ Jul 25 2012, 19:38) *
порядок выполнения операций (precedence) в выражениях жестко определен не только в C, но и в остальных языках программирования.
Приоритет операций - да. Порядок вычисления подвыражений - нет.
QUOTE (Xenia @ Jul 25 2012, 19:38) *
то как может быть так, чтобы "accesses is undefined"?
Обращение к одной переменной может вызвать изменение другой. Например, чтение/запись UDR в любимых вами AVR сбразывает/устанавливает флаг RXC/UDRE. Не стоит огульно обвинять авторов компиляторов в глупости - часто они знают то, что вам и в голову не приходило.
QUOTE (Xenia @ Jul 25 2012, 19:38) *
Очевидно, что accesses тут тот же самый, что и у порядка выполнения операций.
Как раз таки очевидно, что access order может быть любым.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

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

 


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


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