Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
+ООП_Навч_посібник.doc
Скачиваний:
8
Добавлен:
01.07.2025
Размер:
6.58 Mб
Скачать

9.1.2. Застосування специфікатора типу даних volatile

Специфікатор типу даних volatile повідомляє компіляторові про те, що значення відповідної змінної може бути змінене у програмі опосередковано. Наприклад, адреса певної глобальної змінної може передаватися керованій змінній перериваннями підпрограмі трактування, яка обновляє цю змінну з приходом кожного імпульсу сигналу часу. У такій ситуації вміст змінної змінюється без використання безпосередньо заданих настанов програми. Існують вагомі підстави для того, щоб повідомити компілятор про зовнішні чинники зміни змінної. Йдеться про те, що С++-компіляторові дозволяється автоматично оптимізувати певні вирази в припущенні, що вміст тієї або іншої змінної залишається незмінним, якщо воно не знаходиться в лівій частині настанови присвоєння. Але, якщо деякі чинники (зовнішні стосовно програми) змінять значення цього поля, то таке припущення виявиться неправильним, внаслідок чого можуть виникнути проблеми.

Специфікатор типу даних volatile інформує компілятор про те, що ця змінна може бути змінена зовнішніми (стосовно програми) чинниками.

Наприклад, у наведеному нижче коді програми припустимо, що змінна chas обновляється кожну мілісекунду годинниковим механізмом комп'ютера. Але, оскільки змінна chas не оголошена з використанням специфікатора типу даних volatile, цей фрагмент коду програми може іноді працювати неналежним чином. Зверніть особливу увагу на рядки, позначені буквами "А" і "Б":

int chas, timerClass;

// ...

timerClass = chas; // Рядок А

//... Виконання будь-яких дій.

cout << "Пройдений час " << chas-timerClass; // Рядок Б

У цьому коді програми змінна chas набуває свого значення, коли вона присвоюється змінній timerClass у рядку А. Але, оскільки змінна chas не оголошена з використанням специфікатора типу даних volatile, то компілятор має можливість оптимізувати цей код, причому у такий спосіб, при якому значення змінної chas, можливо, не буде запитано в настанові cout (рядок Б), якщо між рядками А і Б не буде жодного проміжного присвоєння значення змінної chas. Іншими словами, у рядку Б компілятор може просто ще раз використовувати значення, яке отримала змінна chas у рядку А. Але, якщо між моментами виконання рядків А і Б надійдуть чергові імпульси сигналу часу, то значення змінної chas обов'язково зміниться, а рядок Б у цьому випадку не відобразить коректного результату.

Для вирішення цього питання необхідно визначити змінну chas з ключовим словом volatile:

volatile int chas;

Тепер значення змінної chas запитуватиметься під час кожного її використанні. І хоча на перший погляд це може видатися дивним, проте специфікатори типів даних const і volatile можна використовувати разом. Наприклад, наведене нижче оголошення абсолютно допустиме. Воно створює const-покажчик на volatile-об'єкт:

const volatile unsigned char *port = ( const volatile char *) 0x2112;

У наведеному прикладі для перетворення цілочисельного літерала 0x2112 в const-покажчик на volatile-символ необхідно застосувати операцію приведення типів.