Умовна компіляція

Умовна компіляція забезпечується в мові С++ набором команд, які, по суті, управляють не компіляцією, а препроцесорною обробкою:

#if константний вираз

#ifdef ідентифікатор

#ifndef ідентифікатор

#else

#endif

#elif

Перші три команди виконують перевірку умов, дві наступні - дозволяють визначити діапазон дії умови, що перевіряється. Команду #elif розглянемо дещо пізніше. Загальна структура застосування директив умовної компіляції така:

#if ... текст 1

#else текст_2

#endif

Конструкція #else текст_2 не обов'язкова. Твкст_1 включається в

компільований текст тільки при істинності умови, що перевіряється. Якщо умова помилково, то за наявності директиви #else на компіляцію передається текст_2. Якщо директива #else відсутня, то весь текст від #if до #endif за помилкової умови опускається. Відмінність між формами команд #if полягає в наступному.

У першій з перерахованих директив #if перевіряється значення константного цілочисельного виразу. Якщо воно відмінно від нуля, то вважається, що умова, що перевіряється, істинно. Наприклад, в результаті виконання директив:

#if 5+4

текст_1

#endif

текст_1 завжди буде включений в компільовану програму.

У директиві #ifdef перевіряється, чи визначений за допомогою команди #define до теперішнього моменту ідентифікатор, поміщений після #ifdef. Якщо ідентифікатор визначений як препроцесорний, то текст_1 використовується компілятором.

У директиві #ifndef перевіряється зворотна умова - істинною вважається невизначеність ідентифікатора, тобто той випадок, коли ідентифікатор не був використаний в команді #define або його визначення було відмінено командою #undef.

Умовну компіляцію зручно застосовувати при відладці програм для включення або виключення контрольного друку. Наприклад

#define DE 1

#ifdef DE

cout << " Налагоджувальний друк ";

#endif

Такого друку, що з'являється в програмі залежно від визначеності ідентифікатора de, може бути декілька і, прибравши директиву #define DE 1, відразу ж відключаємо весь налагоджувальний друк.

Файли, призначені для препроцесорного включення в модулі програми; звичайно забезпечують захистом від повторного включення. Таке повторне включення може відбутися, якщо декілька модулів, в кожному з яких заплановано препроцесорне включення одного і того ж файлу, об'єднуються в загальний текст програми. Наприклад, такими засобами захисту забезпечені всі заголовні файли (подібні iostream.h) стандартної бібліотеки. Схема захисту від повторного включення може бути такий:

// Файл з іменам filename

#ifndef _FILE_NAME

// Текст файлу filename, що включається

#define _FILE_NAME 1

endif

Тут _file_name - зарезервований для файлу filename npe-процесорнийідентифікатор, який не повинен зустрічатися в інших текстах програми.

Для організації галужень під час обробки препроцесором початкового тексту програми введена директива

#elif константний вираз

Структура початкового тексту із застосуванням цієї директиви така:

#if

текст_для_ if

#elif выражекие_1

текст_1

#elif выражекие_2

текст_2

#else

текст_для_случая_еlse

#endif

Препроцесор перевіряє спочатку умову в директиві #if, якщо воно помилково (рівне 0) - обчислює выражение_1, якщо выражекие_1 рівне 0 - обчислюється выражение_2 і т.д. Якщо всі вирази помилкові, то в ком-пільований текст включається текст_для_случая_е1sе. Інакше, тобто при появі хоч би одного дійсного виразу (у #if або в #elif) починає оброблятися текст, розташований безпосередньо за цією директивою, а вся решта ди-ректив не розглядається. Таким чином, препроцесор обробляє завжди тіль-ки одну з ділянок тексту, виділених командами умовної компіляції.