|
|
  |
Warning[Pa082]: undefined behavior: the order of v, архитектура / асм 430-х |
|
|
|
Dec 24 2004, 14:05
|
Местный
  
Группа: Свой
Сообщений: 437
Регистрация: 27-08-04
Пользователь №: 551

|
Исходные данные: имеем обработчик Код #pragma vector=PORT1_VECTOR __interrupt void PORT1ISR(void) { KbDrvTask.SendEv(P1IFG,P1IES); P1IES ^= P1IFG; P1IFG = 0; } После компиляции получаем ворнинг Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement на строки KbDrvTask.SendEv(P1IFG,P1IES); P1IES ^= P1IFG; В листинге все выглядит красиво Код 151 __interrupt void PORT1ISR(void) \ ??PORT1ISR: 152 { \ 000000 0D12 PUSH.W R13 \ 000002 0C12 PUSH.W R12 \ 000004 0F12 PUSH.W R15 \ 000006 0E12 PUSH.W R14 153 KbDrvTask.SendEv(P1IFG,P1IES); \ 000008 52122400 PUSH.B &0x24 \ 00000C 5E422300 MOV.B &0x23, R14 \ 000010 3C40.... MOV.W #KbDrvTask, R12 \ 000014 B012.... CALL #??SendEv 154 P1IES ^= P1IFG; \ 000018 D2E223002400 XOR.B &0x23, &0x24 155 P1IFG = 0; \ 00001E C2432300 MOV.B #0x0, &0x23 156 } \ 000022 2153 ADD.W #0x2, SP \ 000024 3E41 POP.W R14 \ 000026 3F41 POP.W R15 \ 000028 3C41 POP.W R12 \ 00002A 3D41 POP.W R13 \ 00002C 0013 RETI и в железе работает правильно, но неприятный осадок остался  Кто нибудь может объяснить смысл ворнинга "порядок доступов к волатайлам неопределен"
|
|
|
|
|
Dec 24 2004, 16:44
|
Участник

Группа: Свой
Сообщений: 63
Регистрация: 16-06-04
Из: Россия, Уфа
Пользователь №: 31

|
Цитата(ig_z @ Dec 24 2004, 19:05) и в железе работает правильно, но неприятный осадок остался  Кто нибудь может объяснить смысл ворнинга "порядок доступов к волатайлам неопределен" Компилятор тебя честно предупреждает, о неопределенном поведении этой конструкции. Волатильные значения P1IFG и P1IES невозможно передать одновременно в функцию. Т.е. в момент считывание одной переменной, значение другой уже считанной может измениться. В этом случае это вообщем-то не критично, если варнинг раздражает, его можно задавить введя временную переменную, ассемблерный код скорей всего не изменится.
|
|
|
|
|
Dec 27 2004, 11:06
|
Местный
  
Группа: Свой
Сообщений: 437
Регистрация: 27-08-04
Пользователь №: 551

|
Цитата(Kurt @ Dec 24 2004, 19:44) Компилятор тебя честно предупреждает, о неопределенном поведении этой конструкции. Волатильные значения P1IFG и P1IES невозможно передать одновременно в функцию. Т.е. в момент считывание одной переменной, значение другой уже считанной может измениться. Очевидно, что содержимое регистров, зависящих от внешних/внутренних асинхронных событий, не может быть гарантированно в определенный момент времени. Возможно значение такого регистра может измениться быстрее чем закончится операция помещения его (значения регистра) в стек. Имхо ситуация очевидна и без всяких ворнингов  . В моем случае P1IES не может менять свое значение иначе чем через запись в него нового значения. Кроме того, если я правильно понимаю смысл английских слов в ворнинге, речь идет именно о порядке операций чтения. Описания ворнинга я не нашел. И по прежнему не понятно почему порядок чтения может быть андефинед.
|
|
|
|
|
Sep 11 2007, 06:19
|

Местный
  
Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714

|
Подниму старую темку... У меня на АВР то же самое: Цитата Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement C:\asp_Projects\Temp\Source\main.cpp 172 Код //main.cpp #include <iotiny2313.h> #include <asp/OW.h> ... main() { ... [b]OW_Basic q( DDRD, PORTD, PD2 );[/b] ... } Код //OW.h ... OW_Basic :: OW_Basic ( unsigned char cDDRAddr, unsigned char cPortAddr, unsigned char cMask ) { this->cDDRAddr = cDDRAddr; this->cPortAddr = cPortAddr; this->cMask = ( 1 << cMask ); } ... Ругается на выделенную строку. Поскольку DDRD, PORTD, PD2 жестко определены не понимаю, в чем дело.
Сообщение отредактировал aspID - Sep 11 2007, 06:20
|
|
|
|
|
Sep 11 2007, 07:24
|

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

|
Цитата(aspID @ Sep 11 2007, 09:19)  Ругается на выделенную строку. Поскольку DDRD, PORTD, PD2 жестко определены не понимаю, в чем дело. Потому что стандарт С не оговаривает, в каком порядке вычисляются аргументы функции. Он также не оговаривает, в каком порядке вычисляются части выражения (кроме приоритета, разумеется). DDRD, PORTD объявлены как volatile, что говорит компилятору, что доступ к такой переменной может влиять на что угодно, в том числе и на содержимое других переменных. Поэтому компилятор предупреждает - "я могу здесь обратиться к переменным в любом порядке. Сейчас так, а добавишь где-нибудь еще команду - могу и поменять порядок. Я дурной, мне глубоко пофиг на что влияет доступ к каждой из этих volatile-переменных. Ты человек - ты и разбирайся". сделайте так: Код { uint8_t Tmp = DDRD; OW_Basic q( Tmp, PORTD, PD2 ); } Только подозреваю, что вам там надо указатели передавать, а не значения порта и направления.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 12 2007, 03:36
|

Местный
  
Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714

|
Цитата(Сергей Борщ @ Sep 11 2007, 14:24)  DDRD, PORTD объявлены как volatile Код //iotiny2313.h /**************************************************************************** * SFR_B(AVR, 0x1F) Expands to: * __io union { * unsigned char AVR; // The sfrb as 1 byte * struct { // The sfrb as 8 bits * unsigned char AVR_Bit0:1, * AVR_Bit1:1, * AVR_Bit2:1, * AVR_Bit3:1, * AVR_Bit4:1, * AVR_Bit5:1, * AVR_Bit6:1, * AVR_Bit7:1; * }; * } @ 0x1F; ***************************************************************************/ ... SFR_B(PORTD, 0x12) /* Data Register, Port D */ SFR_B(DDRD, 0x11) /* Data Direction Register, Port D */ ... #define PD2 2 ... Они считаются volatile? Можно ли в данном случае просто игнорировать данный Warning?
Сообщение отредактировал aspID - Sep 12 2007, 03:38
|
|
|
|
|
Sep 12 2007, 10:09
|

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

|
Цитата(aspID @ Sep 12 2007, 06:36)  Код * __io union { Они считаются volatile? Можно ли в данном случае просто игнорировать данный Warning? Читаем описание компилятора (Help->C/C++ Compiler reference) Цитата The __io memory attribute implies that objects are __no_init and volatile, and allows objects to be accessed by use of the special I/O instructions in the AVR microcontroller. Можете игнорировать, но лучше заведите временную переменную. Иначе вы можете в куче таких игнорируемых варнингов пропустить какой-нибудь действительно важный.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|