Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Warning[Pa082]: undefined behavior: the order of v
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
ig_z
Исходные данные:
имеем обработчик
Код
#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


и в железе работает правильно, но неприятный осадок остался smile.gif
Кто нибудь может объяснить смысл ворнинга "порядок доступов к волатайлам неопределен"
Kurt
Цитата(ig_z @ Dec 24 2004, 19:05)
и в железе работает правильно, но неприятный осадок остался smile.gif
Кто нибудь может объяснить смысл ворнинга "порядок доступов к волатайлам неопределен"

Компилятор тебя честно предупреждает, о неопределенном поведении этой конструкции. Волатильные значения P1IFG и P1IES невозможно передать одновременно в функцию. Т.е. в момент считывание одной переменной, значение другой уже считанной может измениться. В этом случае это вообщем-то не критично, если варнинг раздражает, его можно задавить введя временную переменную, ассемблерный код скорей всего не изменится.
ig_z
Цитата(Kurt @ Dec 24 2004, 19:44)
Компилятор тебя честно предупреждает, о неопределенном поведении этой конструкции. Волатильные значения P1IFG и P1IES невозможно передать одновременно в функцию. Т.е. в момент считывание одной переменной, значение другой уже считанной может измениться.
*



Очевидно, что содержимое регистров, зависящих от внешних/внутренних асинхронных событий, не может быть гарантированно в определенный момент времени. Возможно значение такого регистра может измениться быстрее чем закончится операция помещения его (значения регистра) в стек. Имхо ситуация очевидна и без всяких ворнингов smile.gif.
В моем случае P1IES не может менять свое значение иначе чем через запись в него нового значения.

Кроме того, если я правильно понимаю смысл английских слов в ворнинге, речь идет именно о порядке операций чтения. Описания ворнинга я не нашел. И по прежнему не понятно почему порядок чтения может быть андефинед.
aspID
Подниму старую темку...
У меня на АВР то же самое:

Цитата
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, 09:19) *
Ругается на выделенную строку. Поскольку DDRD, PORTD, PD2 жестко определены не понимаю, в чем дело.
Потому что стандарт С не оговаривает, в каком порядке вычисляются аргументы функции. Он также не оговаривает, в каком порядке вычисляются части выражения (кроме приоритета, разумеется). DDRD, PORTD объявлены как volatile, что говорит компилятору, что доступ к такой переменной может влиять на что угодно, в том числе и на содержимое других переменных. Поэтому компилятор предупреждает - "я могу здесь обратиться к переменным в любом порядке. Сейчас так, а добавишь где-нибудь еще команду - могу и поменять порядок. Я дурной, мне глубоко пофиг на что влияет доступ к каждой из этих volatile-переменных. Ты человек - ты и разбирайся".
сделайте так:
Код
{
   uint8_t Tmp = DDRD;
   OW_Basic q( Tmp, PORTD, PD2 );
}
Только подозреваю, что вам там надо указатели передавать, а не значения порта и направления.
aspID
Цитата(Сергей Борщ @ 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, 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.
Можете игнорировать, но лучше заведите временную переменную. Иначе вы можете в куче таких игнорируемых варнингов пропустить какой-нибудь действительно важный.
aspID
Спасибо всем отозвавшимся
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.