У кожної директиви #if в вихідному файлі повинна бути відповідна закриває директива #endif. Між директивами #if і #endif може розташовуватися будь-яку кількість директив #elif. однак допускається не більше однієї директиви #else. Директива #else. якщо присутній, повинна бути останньою перед директивою #endif.
Директиви #if. #elif. #else і #endif можуть бути вкладені в інші текстові частини директив #if. Кожна вкладена директива #else. #elif або #endif відноситься до найближчої попередньої директиві #if.
У всіх директив умовної компіляції, таких як #if і #ifdef. до кінця файлу повинні бути відповідні закривають директиви #endif; в іншому випадку з'являється повідомлення про помилку. Якщо директиви умовної компіляції містяться у включаються файлах, вони повинні задовольняти однакових умов: в кінці файлу, що включається не повинно залишатися непарних директив умовної компіляції.
Всередині тієї частини командного рядка, яка слідує за командою #elif. виконується підстановка макросів, тому виклики макросів можна використовувати в вираженні константне-вираз.
Препроцесор вибирає одне із заданих входжень параметра текст для подальшої обробки. Блок, вказаний в параметрі текст. може являти собою будь-яку послідовність тексту. Він може займати кілька рядків. Зазвичай текст - це текст програми, зрозумілий для компілятора або препроцесора.
Препроцесор обробляє виділений блок текст і передають його компілятору. Якщо блок текст містить директиви препроцесора, препроцесор виконує ці директиви. Компілюються тільки текстові блоки, вибрані препроцесором.
Препроцесор вибирає один елемент текст. оцінюючи вирази зі сталими, наступні за кожною директивою #if або #elif. до тих пір, поки не буде знайдено вираз із значенням true (відмінне від нуля). Виділяється весь текст (включаючи інші директиви препроцесора, що починаються з символу #) до відповідної директиви #elif. #else або #endif.
Якщо все входження константного-вирази мають значення false чи ні жодної директиви #elif. препроцесор вибирає блок тексту після пропозиції #else. Якщо пропозиція #else опущено і всі екземпляри константного-вирази в блоці #if мають значення false, жоден текстовий блок не вибирається.
Константне-вираз - це целочисленное константний вираз з наступними додатковими обмеженнями:
Вирази повинні мати цілочисельний тип і можуть містити тільки цілочисельні константи, символьні константи і оператор defined.
У вираженні не допускається використання оператора sizeof або оператора приведення типу.
Цільова середовище може бути не в змозі представляти всі діапазони цілих чисел.
Перетворення представляє тип int. співпадає з типом long. і тип unsigned int. співпадає з типом unsigned long.
Транслятор може перетворювати символьні константи в набір кодових значень, що відрізняється від набору для цільової середовища. Для визначення властивостей цільової середовища перевірте значення макросів з файлу LIMITS.H в додатку, зібраному для цільової середовища.
Вираз не повинно виконувати жодних запитів середовища і не повинно залежати від конкретної реалізації на цільовому комп'ютері.
Оператор препроцесора defined можна використовувати в спеціальних константних виразах, як показано в наступному синтаксисі:
Це константний вираз вважається рівним true (не рівним нулю), якщо в даний момент ідентифікатор визначений; в іншому випадку умова одно false (0). Ідентифікатор, певний як порожній текст, вважається певним. Директиву defined можна використовувати тільки в директивах #if і #elif.
У наступному прикладі директиви #if і #endif керують компіляцією виклику однієї з 3 функцій:
Виклик функції credit компілюється, якщо визначений ідентифікатор CREDIT. Якщо визначено ідентифікатор DEBIT. компілюється виклик функції debit. Якщо жоден з цих ідентифікаторів не визначений, компілюється виклик функції printerror. Зверніть увагу, що в C і C ++ ідентифікатори CREDIT та credit - це різні ідентифікатори через різного регістра символів.
У наступному прикладі в операторах умовної компіляції використовується раніше певна символьна константа з ім'ям DLEVEL.
Перший блок #if містить 2 набору вкладених директив #if. #else і #endif. Перший набір директив обробляється тільки в тому випадку, якщо виконується умова DLEVEL> 5. В іншому випадку обробляються оператори, розташовані після директиви #else.
Директиви #elif і #else в другому прикладі використовуються для вибору одного з чотирьох варіантів в залежності від значення константи DLEVEL. Константі STACK присвоюється значення 0, 100 або 200 в залежності від визначення константи DLEVEL. Якщо DLEVEL більше 5, то компілюється оператор
і константа STACK залишається невизначеною.
Умовна компіляція зазвичай використовується для запобігання декількох включень одного і того ж файлу заголовка. У мові C ++, в якому класи часто визначаються в файлах заголовків, конструкції, подібні наведеним нижче, можна використовувати для виключення багаторазових визначень.
Попередній код перевіряє, чи визначена символьна константа EXAMPLE_H. Якщо визначена, файл вже включений і його повторна обробка не потрібна. Якщо немає, константа EXAMPLE_H визначається, щоб позначити файл EXAMPLE.H як вже оброблений.