Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Странное поведение компилятора
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
Woodoo
Доброго времени суток!

странное поведени компилятора заключаеться в неверном интерпретировании оператора пост-дикремента. Почему так происходит - непонятно.
Код
//Header file
__near __no_init volatile struct
{
    unsigned int Result;
    enum {K2 = 2, K4 = 4, K8 = 3, K16 = 4, K32 = 5, K64 = 6, K128 = 7} PS : 3;
    unsigned char IE : 1, IF : 1, FR : 1, SC : 1, EN : 1;
    enum {ADC0, ADC1, ADC2, ADC3, ADC4, ADC5, ADC6, ADC7, VBG = 0x0E, GND = 0x0F} MUX : 4;
    unsigned char : 1, LAR : 1;
    enum {AREF = 0, AVCC = 1, Internal = 3} REF : 2;
} ADC @ 0x24;

//Source file
    ADC.MUX = 3;
    Array[ADC.MUX++] = ADC.MUX;     // почему? [3] = 4
    ADC.MUX = 4;
    Array[ADC.MUX] = ADC.MUX++;     //  [4] = 4  mux = 5 тут ок


Код составлен для тестирования. Смысла в нем искать не надо. Проблема заключаеться в том, что компилятор некоректно выполняет вторую строчку src. файла (Array[ADC.MUX++] = ADC.MUX;), в результате чего в третьем элементе массива записывается значение 4! Я уж потерял веру в Си, пока разбирался с проблемой.
Может подобное свойство - следствие использования облости ввода-вывода? НО! замена переменной ADC.MUX на DDRD(к примеру) приводит к нормальной работе: Array[3] = 3, Array[4] = 4.

при этом компиялтор, как по мне, безосновательно выругался, когда компилировал этот код:
Цитата
Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement E:\Mazilla\Projects\IAR AVR ATMega8\main.c 59


Замечу вуругался на оба варианта, с ADC.MUX и с DDRD (точнее PORT.D.DIR.Value smile.gif ), но второй, повторюсь, скампилировал верно! В чем проблема?

Кстати, может кому понравится такой подход - организация регистров перефирии в смысловые структуры (ах как не хватает классов си++)? Если кто использует такой подход - поделитись опытом.
_Bill
Цитата(Woodoo @ Dec 22 2006, 12:30) *
Доброго времени суток!

странное поведени компилятора заключаеться в неверном интерпретировании оператора пост-дикремента. Почему так происходит - непонятно.
Код
//Header file
__near __no_init volatile struct
{
    unsigned int Result;
    enum {K2 = 2, K4 = 4, K8 = 3, K16 = 4, K32 = 5, K64 = 6, K128 = 7} PS : 3;
    unsigned char IE : 1, IF : 1, FR : 1, SC : 1, EN : 1;
    enum {ADC0, ADC1, ADC2, ADC3, ADC4, ADC5, ADC6, ADC7, VBG = 0x0E, GND = 0x0F} MUX : 4;
    unsigned char : 1, LAR : 1;
    enum {AREF = 0, AVCC = 1, Internal = 3} REF : 2;
} ADC @ 0x24;

//Source file
    ADC.MUX = 3;
    Array[ADC.MUX++] = ADC.MUX;     // почему? [3] = 4
    ADC.MUX = 4;
    Array[ADC.MUX] = ADC.MUX++;     //  [4] = 4  mux = 5 тут ок


Код составлен для тестирования. Смысла в нем искать не надо. Проблема заключаеться в том, что компилятор некоректно выполняет вторую строчку src. файла (Array[ADC.MUX++] = ADC.MUX;), в результате чего в третьем элементе массива записывается значение 4! Я уж потерял веру в Си, пока разбирался с проблемой.
Может подобное свойство - следствие использования облости ввода-вывода? НО! замена переменной ADC.MUX на DDRD(к примеру) приводит к нормальной работе: Array[3] = 3, Array[4] = 4.

при этом компиялтор, как по мне, безосновательно выругался, когда компилировал этот код:
Цитата
Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement E:\Mazilla\Projects\IAR AVR ATMega8\main.c 59


Замечу вуругался на оба варианта, с ADC.MUX и с DDRD (точнее PORT.D.DIR.Value smile.gif ), но второй, повторюсь, скампилировал верно! В чем проблема?

Кстати, может кому понравится такой подход - организация регистров перефирии в смысловые структуры (ах как не хватает классов си++)? Если кто использует такой подход - поделитись опытом.

Компилятор не выругался. Он просто сделал Вам предупреждение о том, что поведение компилятора непредсказуемо и результат может получится не тот, который Вы ожидали. Вообще, обе Ваши конструкции двусмысленны и интерпретировать их можно по-разному в зависимости от того, какая часть выражения (левая или правая) будет вычисляться первой.
andrvisht
Цитата(Woodoo @ Dec 22 2006, 13:30) *
Код
    ADC.MUX = 3;
    Array[ADC.MUX++] = ADC.MUX;     // почему? [3] = 4


ну так вроде и должно быть 4
ADC.MUX = 3;
Array[3] = ++3;
потому как после выборки ячейки ADC.MUX инкрементируется, и только потом присваивается значению ячейки

хотя согласен с _Bill
потому как компилятор может по разному выполнять такую конструкцию.
Woodoo
Уухх, разобрался.
спецификация Си не декларирует порядок выполнения посдикрементов при выполнении конструкций подобного рода. Оставляет на усмотрение компилятора. Поэтому и матерился компилятор.
Спа за ответы!
Тема закрыта. smile.gif
П'ятныця... это хорошо cheers.gif cheers.gif cheers.gif
_Bill
Цитата(&-rey @ Dec 22 2006, 13:58) *
Цитата(Woodoo @ Dec 22 2006, 13:30) *

Код
    ADC.MUX = 3;
    Array[ADC.MUX++] = ADC.MUX;     // почему? [3] = 4


ну так вроде и должно быть 4
ADC.MUX = 3;
Array[3] = ++3;
потому как после выборки ячейки ADC.MUX инкрементируется, и только потом присваивается значению ячейки

хотя согласен с _Bill
потому как компилятор может по разному выполнять такую конструкцию.

Можно просто посмотреть сгенерированный код для разных случаев. Хотя лично мне непонятно чего именно хотел получить автор.
Woodoo
Я писал выше, что код "HAS NO EFFECT" (как любит выражаться компиляторsmile.gif ).
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.