2016-12-08 8 views
1

Компилятор C, похоже, оптимизирует переменную, которую я не ожидаю. Этот код ниже:Оптимизатор C, устраняющий непредвиденную переменную

uint32_t GetSysTick(void); 

uint32_t timeout = GetSysTick() + 9000; //9sec 
while(len && (GetSysTick() < timeout)) 
{ 
    ... some code that will decrement len 
} 

Компилятор оптимизирует переменную «тайм-аут». Обычно цикл while выйдет, как только len достигнет нуля, но если процесс занимает больше времени, чем ожидалось, когда systick превышает таймаут, тогда он также должен выйти, конечно, ничего из этого не происходит, если тайм-аут оптимизирован. Я уверен, что я определяю тайм-аут как изменчивый, который не должен его оптимизировать, но технически это не изменчиво. Что мне здесь не хватает? Должен ли я использовать volatile для возвращаемого значения из GetSysTick()? (не уверен, что это даже законно)

Для полноты здесь GetSysTick и декларация системы. Оба находятся в другом файле C. systick получает приращение каждые миллисекунды в прерывании.

static volatile uint32_t systick=0; 

uint32_t GetSysTick(void) 
{ 
    return systick; 
} 
+3

Какой компилятор, как & where is 'GetSysTick' объявлен? См. [Ask] и укажите [mcve]. Обратите внимание, что ожидание - это не очень хорошая идея. Лучше использовать прерывания/семафоры/таймеры/и т. Д. – Olaf

+2

Что заставляет вас думать, что компилятор это делает? У вас есть тайм-аут в цикле? –

+0

@AlexK .: У вас есть точка. Но добавление кода для печати переменной может повлиять на генерацию кода (Heisenberg-Effect). Лучше проверить код сборки или использовать отладчик. – Olaf

ответ

0

Итак, после дальнейшего изучения моего компилятора я узнал, что не использовал последнюю версию. По-видимому, я был на компиляторе gnu arm C версии 5.2 после обновления до последней версии 5.4 моя переменная тайм-аута не оптимизирована. Урок здесь, всегда проверяйте обновления ваших инструментов. Спасибо всем за ваш вклад и предложения. Спасибо @JohnBollinger, чтобы провести время, чтобы проверить его с его настройкой.