Volatile — ключевое слово языков C/C++, которое информирует компилятор о том, что значение переменной может меняться из вне и что компилятор не будет оптимизировать эту переменную. Примерно такое описание volatile я встречал во многих книгах и туториалах, и каждый раз мне не удавалось понять что же хотел сказать автор. На понимание этого я потратил n-ое количество времени, и вот специально для этого, чтобы упростить жизнь новичкам в понимании этого аспекта, решил написать как раз таки эту статью.
«компилятор не будет оптимизировать эту переменную» — что означает оптимизировать? Наверное очень много людей, когда только начинали программировать задавались этим во��росом, не так ли? Думаю лучше продемонстрировать все на примерах, нежели рассказывать термины, которые большинству останутся не понятными.
Ну давайте начнем, к примеру имеем простой массив(правда не с простым размером), в цикле с которым выполняем какое-либо действие:
Самая затратная операция в этом примере не присваивание ячейке массива какого-либо значения и не инкремент счетчика, а именно операция сравнения, поэтому компилятор оптимизирует это примерно вот так:
Еще очень простой пример, в котором имеем массив символов, с помощью цикла проходим по всей строке и выполняем какие-то действия с символами:
В этом случае компилятор вынесет вызов strlen() в отдельную переменную:
Также чтобы не писать код, так как он очевиден, компилятор заменяет умножение на 2, сложением, но и пожалуй самый главный пример по нашей тематике, это то, что в большинстве случаев компилятор разгружает runtime программы, путем подстановки в выражения уже их значения, к примеру мы пишем программу для лифта. Одно из условий данной программы таково, что как только зайдут к примеру больше 4 человек должно выдаться предупреждение.
Все же хорошо, ошибки невозможны в этом коде. Но по сути условие будет всегда истинно, так как компилятор уже запомнил значения этих переменных. И вот как раз таки в таких случаях применяется ключевое слово volatile, чтобы избежать подобных казусов, это будет выглядеть вот так:
Думаю мне получилось объяснить самые азы того зачем нужен volatile. Для еще лучшего понимания советую прочитать эту статью. Желаю удачи в изучение огромного мира технологий C/C++.
Оптимизация кода компилятором
«компилятор не будет оптимизировать эту переменную» — что означает оптимизировать? Наверное очень много людей, когда только начинали программировать задавались этим во��росом, не так ли? Думаю лучше продемонстрировать все на примерах, нежели рассказывать термины, которые большинству останутся не понятными.
Ну давайте начнем, к примеру имеем простой массив(правда не с простым размером), в цикле с которым выполняем какое-либо действие:
int ar[1024];
for(size_t i = 0; i < 1024; i++)
{
ar[i] = ...;
}
Самая затратная операция в этом примере не присваивание ячейке массива какого-либо значения и не инкремент счетчика, а именно операция сравнения, поэтому компилятор оптимизирует это примерно вот так:
int ar[1024];
for(size_t i = 0; i < 1024 / 4; i += 4)
{
ar[i] = ...;
ar[i + 1] = ...;
ar[i + 2] = ...;
ar[i + 3] = ...;
}
Еще очень простой пример, в котором имеем массив символов, с помощью цикла проходим по всей строке и выполняем какие-то действия с символами:
сhar str[125];
for(size_t i = 0; i < strlen(str); i++)
{
...
}
В этом случае компилятор вынесет вызов strlen() в отдельную переменную:
сhar str[125];
size_t length = strlen(str);
for(size_t i = 0; i < lenght; i++)
{
...
}
Также чтобы не писать код, так как он очевиден, компилятор заменяет умножение на 2, сложением, но и пожалуй самый главный пример по нашей тематике, это то, что в большинстве случаев компилятор разгружает runtime программы, путем подстановки в выражения уже их значения, к примеру мы пишем программу для лифта. Одно из условий данной программы таково, что как только зайдут к примеру больше 4 человек должно выдаться предупреждение.
const MAX_COUNT_PEOPLE = 4;
size_t countPeole = 0;
...
if(countPeople > MAX_COUNT_PEOPLE)
{
// Выдаем предупреждение
}
// Значение переменной countPeople к примеру будет менять с другого потока
Все же хорошо, ошибки невозможны в этом коде. Но по сути условие будет всегда истинно, так как компилятор уже запомнил значения этих переменных. И вот как раз таки в таких случаях применяется ключевое слово volatile, чтобы избежать подобных казусов, это будет выглядеть вот так:
const MAX_COUNT_PEOPLE = 4;
volatile size_t countPeole = 0;
...
if(countPeople > MAX_COUNT_PEOPLE)
{
// Выдаем предупреждение
}
// Значение переменной countPeople к примеру будет менять с другого потока
Заключение
Думаю мне получилось объяснить самые азы того зачем нужен volatile. Для еще лучшего понимания советую прочитать эту статью. Желаю удачи в изучение огромного мира технологий C/C++.