Указатели на устройство PIC32 не соответствуют ожидаемым значениям в отладчике

Быстрый вопрос относительно поведения указателей (я работаю над проектом на PIC32MX270F256D).

В настоящее время у меня реализован следующий код:

void main(void)
{
    int size = 15;
    int check;
    int *ptr;

    ptr = &size;
    check = *ptr;

    while(1);        //just so it hangs at the end
}

Сейчас я прохожу программу с переменными часами. После объявления размера я вижу в окне просмотра, что размер имеет значение 15 и находится по адресу 0xA000FFC8 (пока все хорошо). После строки ptr = &size; окно просмотра показывает, что ptr имеет значение 0xA000FFC8 (как и ожидалось). Теперь после последней строки (check = *ptr;) окно просмотра сообщает, что check имеет значение 0xA000FFC8.

Мне кажется, это очень простая функциональность. В конце пока зависает в цикле while, чек должен иметь значение 15, нет? Если да, то мой код неверен или что-то не так с Microchip IDE? Если нет, то чего мне не хватает, чтобы все работало так, как должно?

Спасибо.

-Шон

Примечание. Я использую MPLAB X и компилятор Microchip XC32.


person detroitwilly    schedule 21.11.2014    source источник
comment
Что, если ваш компилятор определил, что ваш код на самом деле ничего не делает, поэтому он не стал генерировать какой-то код (то есть оптимизировать его)? Получает ли check 15, если заменить int *ptr; на volatile int *ptr;? Можно ли отключить оптимизацию компилятора?   -  person indiv    schedule 21.11.2014
comment
^+1. Похоже на проблемы с оптимизацией.   -  person Eugene Sh.    schedule 21.11.2014
comment
эта строка: проверка = *ptr; приводит к неопределенному поведению, потому что разыменование точки по адресу 15 (где адрес 15 НЕ является выделенным адресом памяти) означает, что чтение содержимого памяти может/вероятно происходит в страницу памяти, доступную только для чтения. это может привести к ошибке сегмента.   -  person user3629249    schedule 21.11.2014
comment
в конце проверочная переменная будет иметь значение из памяти, куда указывает ptr (в данном случае адрес 15) фактическое значение может быть любым   -  person user3629249    schedule 21.11.2014
comment
@ user3629249 Это неправда. ptr имеет значение адреса size, поэтому разыменование даст значение size.   -  person Eugene Sh.    schedule 21.11.2014
comment
@indiv, это определенно была проблема с оптимизацией. Изменил int *ptr на volatile int *ptr в соответствии с вашими предложениями, и все работает как положено. Индив, если хочешь ответить, не стесняйся. Я проверю через несколько дней, и если никто не ответил, я отвечу сам. Спасибо за помощь.   -  person detroitwilly    schedule 22.11.2014


Ответы (1)


Вероятно, это проблема оптимизации. Ваш компилятор определил, что ваш код на самом деле ничего не делает, поэтому он не стал генерировать код. В частности, ваш код на самом деле не использует значение, которое вы храните в check.

Вы можете объявить свой указатель как volatile, чтобы заставить компилятор не оптимизировать его. То есть int *ptr; становится volatile int *ptr;.

Вы также можете использовать значение check осмысленно, например, распечатав его.

printf("My pointer %p points to %u.\n", ptr, check);

Или вы можете заглянуть в документацию вашего компилятора и выяснить, как отключить оптимизацию. При отладке часто полезно компилировать без оптимизации, чтобы скомпилированный код точно соответствовал исходному коду.

Примечание. В какой-то момент вам может понадобиться доступ к регистрам оборудования или микросхемы, которые были сопоставлены с адресами памяти. Когда вы это сделаете, убедитесь, что эти указатели на сопоставленную память являются энергозависимыми, иначе у вас будет та же проблема!

person indiv    schedule 21.11.2014
comment
Просто чтобы уточнить, объявление volatile int *ptr; решил мою проблему. Я никогда не пытался отключить оптимизацию. - person detroitwilly; 22.11.2014