Сообщение от xlr8
|
Короче теперь я напуган до смерти и волатию все, что движется, а если не движется, шевелю и волатилю... ацтой.
|
Ну, как говорится, у страха глаза велики. Пугаться тут нечего. Главное понять что зачем почему и отчего.
Магическое слово
volatile говорит компилятору, что значение переменной с таким квалификатором может изменяться независимо от программы, например в прерываниях. Маленький пример:
Код:
|
char flag;
..........
while (!flag); // Wait for the event |
В данном случае переменная внутри цикла никак не меняется. Поэтому при включенной оптимизации (компилятор стремится сделать как можно более эффективный код) копирование переменой flag в регистр процессора выносится за пределы цикла. Это будет выглядеть примерно так:
Код:
|
lds r16, flag
loop: tst r16
breq loop |
Т.е. программа попросту "подвисает".
Если же объявить переменную flag с квалификатором volatile, т.е.
Код:
|
volatile char flag;
.......
while (!flag); // Wait for the event |
то будет примерно такой код
Код:
|
loop: lds r16, flag
tst r16
breq loop |
Т.е. компилятор "знает",что переменная может изменится в течение цикла. Поэтому содержимое переменной flag каждый раз копируется в регистр для анализа ее содержимого, и зацикливания не происходит.
С другой стороны, если в цикле происходит вызов какой-либо функции, которая может изменить данную переменную, то компилятор также будет копировать значение этой переменной во время цикла.