Ce face #ifdef, #ifndef, #if, #endif
#ifdef NUME păstrează codul de până la #else sau #endif doar dacă macro-ul NUME este definit; altfel îl elimină complet, ca și cum nu ar fi fost scris. #ifndef face invers. #if evaluează o expresie cu numere întregi, iar defined(NUME) verifică existența unui macro.
Se folosește pentru: cod de depanare activat doar în versiunea de test, cod diferit pe sisteme diferite (_WIN32, __APPLE__, __linux__), verificarea standardului (__cplusplus) și gărzile de includere ale fișierelor antet.
Macro-urile pot fi definite și din linia de comandă: c++ -DDEBUG main.cpp echivalează cu #define DEBUG la începutul fișierului. C++23 a adăugat #elifdef și #elifndef.
Exemple
Exemplul 1: Mesaje de depanare activate cu DEBUG
Cu #define DEBUG, mesajul de depanare rămâne în program. Fără el (sau fără -DDEBUG), linia ar dispărea complet din codul compilat.
#include <print>
#define DEBUG
int main() {
int total = 0;
for (int i = 1; i <= 3; ++i) {
total += i * 10;
#ifdef DEBUG
std::println("[debug] pas {}, total {}", i, total);
#endif
}
std::println("Total: {}", total);
}
Rezultat
[debug] pas 1, total 10
[debug] pas 2, total 30
[debug] pas 3, total 60
Total: 60
Exemplul 2: Cod diferit după sistem
Programul a rulat pe macOS, unde compilatorul definește __APPLE__.
#include <print>
int main() {
#if defined(_WIN32)
std::println("Rulez pe Windows");
#elif defined(__APPLE__)
std::println("Rulez pe macOS");
#elif defined(__linux__)
std::println("Rulez pe Linux");
#else
std::println("Sistem necunoscut");
#endif
#if __cplusplus >= 202302L
std::println("Compilat cu C++23 sau mai nou");
#endif
}
Rezultat
Rulez pe macOS
Compilat cu C++23 sau mai nou
Exemplul 3: #ifndef și #elifdef (C++23)
#include <print>
#define VERSIUNE_PRO
#ifndef LIMITA_UTILIZATORI
#define LIMITA_UTILIZATORI 5
#endif
int main() {
#ifdef VERSIUNE_GRATUITA
std::println("Versiune gratuită");
#elifdef VERSIUNE_PRO
std::println("Versiune Pro");
#endif
std::println("Limită utilizatori: {}", LIMITA_UTILIZATORI);
}
Rezultat
Versiune Pro
Limită utilizatori: 5
Greșeli frecvente
- Uiți
#endif. Preprocesorul dă eroarea „unterminated conditional directive”, adesea la sfârșitul fișierului, departe de locul greșelii. - Scrii
#ifdef DEBUG && VERBOSE.#ifdefacceptă un singur nume; pentru condiții compuse folosește#if defined(DEBUG) && defined(VERBOSE). - Folosești în
#ifvariabile sauconstexpr-uri din C++. Preprocesorul rulează înainte de compilare și știe doar de macro-uri și numere; pentru condiții pe valori C++ foloseșteif constexpr.
Comenzi înrudite
#define: Definește un macro: preprocesorul înlocuiește textual numele cu valoarea lui, peste tot în cod, înainte de compilare.#include: Directivă a preprocesorului care copiază conținutul unui fișier antet în locul ei, ca să poți folosi funcțiile și clasele declarate acolo.#pragma once: Pusă la începutul unui fișier antet, face ca fișierul să fie inclus o singură dată, chiar dacă apare în mai multe #include-uri.if constexpr: Un if evaluat la compilare: ramura falsă este eliminată complet, deci poate conține cod care nu s-ar compila pentru tipul curent.