Direktivy #if, #elif, #else a #endif (C/C++)
Direktiva #if s direktivami #elif, #else a #endif řídí sestavování částí zdrojového souboru.Pokud výraz, který píšete (po #if), má nenulovou hodnotu, skupina řádku bezprostředně po směrnici #if je zachována v překladové jednotce.
Gramatika
podmíněné :
část if části elifoptčást elseoptřádek endifčást if :
text řádku ifřádek if :
#if konstantní výraz#ifdef identifikátor
#ifndef identifikátor
části elif :
text řádku elifčásti elif text řádku elif
řádek elif :
#elif konstantní výrazčásti else :
text řádku elseřádek else :
#elseřádek endif :
#endif
Každé direktivě #if ve zdrojovém souboru musí odpovídat uzavírací direktiva #endif.Libovolný počet direktiv #elif se může objevit mezi direktivami #if a #endif, ale je povolena nejvýše jedna direktiva #else.Direktiva #else (je-li uvedena) musí být poslední direktivou před parametrem #endif.
Direktivy#if, #elif, #else a #endif lze vnořit do jiné části textu jiné direktivy #if.Každá vnořená direktiva #else, #elif, nebo #endif patří k nejbližší předchozí direktivě #if.
Všechny direktivy podmíněné kompilace, jako například #if a #ifdef, musí mít odpovídající uzavírací direktivy #endif před koncem souboru; jinak je generována chybová zpráva.Když direktivy podmíněné kompilace jsou obsaženy v souborech, musí splňovat stejné podmínky: nesmí existovat žádné neporovnané direktivy podmíněné kompilace na konci souboru začlenění.
Náhrada makra se provádí v rámci části příkazového řádku, který následuje po příkazu #elif, takže volání makra lze použít v rámci konstantního výrazu.
Preprocesor vybere jeden z daných výskytů textu k dalšímu zpracování.Blok zadaný v poli text může být libovolná sekvence textu.Může zabírat více než jeden řádek.Obvykle text je text programu, který má význam pro kompilátor nebo preprocesor.
Preprocesor zpracuje vybraný text a předá ho kompilátoru.Pokud text obsahuje direktivy preprocesoru, preprocesor provádí uvedené směrnice.Kompilovány jsou pouze textové bloky vybrané preprocesorem.
Preprocesor vybere jednu položku text vyhodnocením konstantního výrazu po každé položce směrnice #if nebo #elif, dokud nenajde pravdivý (nenulový) konstantní výraz.Vybere celý text (včetně ostatních pokynů preprocesoru počínaje #) až po přidružený #elif, #else nebo #endif.
Pokud všechny výskyty konstantního výrazu jsou false, nebo pokud se nezobrazí žádná směrnice #elif, preprocesor vybere textový blok po klauzuli #else.Pokud je klauzule #else vynechána a všechny výskyty konstantního výrazu v bloku #if jsou false, není vybrán žádný textový blok.
Konstantní výraz je konstantní výraz celého čísla s těmito dalšími omezeními:
Výrazy musí být integrálního typu a mohou obsahovat pouze celočíselné konstanty, znakové konstanty a definovaný operátor.
Výraz nemůže používat operátor sizeof ani operátor přetypování.
Cílové prostředí nemusí být schopno představovat všechny rozsahy celých čísel.
Překlad představuje typ int stejný jako typ long a unsigned int stejný jako unsigned long.
Překladač může přeložit konstanty znaků do sady hodnot kódů odlišných od sady pro cílové prostředí.Pokud chcete určit vlastnosti cílového prostředí, zkontrolujte hodnoty maker z LIMITS.H v aplikaci sestavené pro cílové prostředí.
Výraz nesmí vydávat žádné dotazy na prostředí a musí zůstat izolovaný od podrobností implementace v cílovém počítači.
Operátor preprocesoru defined lze použít ve speciálních výrazech konstant, jak je znázorněno v následující syntaxi:
definovaný( identifier )
definovaný identifier
Tato konstanta je považována za PRAVDA (nenulová), pokud identifikátor je aktuálně definován; v opačném případě, že podmínka je NEPRAVDA (0).Identifikátor definovaný jako prázdný text je považován za definovaný.Direktivu defined můžete použít v rámci direktivy #if a #elif, ale nikde jinde.
V následujícím příkladu určují direktivy #if a #endif kompilaci jednoho ze třech volání funkce:
#if defined(CREDIT)
credit();
#elif defined(DEBIT)
debit();
#else
printerror();
#endif
Volání funkce credit se zkompiluje, pokud dojde k definici identifikátoru CREDIT.Pokud je definován identifikátor DEBIT, volání funkce debit je zkompilováno.Pokud není definován žádný identifikátor, volání printerror je zkompilováno.Všimněte si, že CREDIT a credit jsou odlišné identifikátory v jazyce C a C++, protože jejich případy se různí.
Příkazy podmíněné kompilace v následujícím příkladu předpokládají, že dříve definovaná symbolická konstanta byla pojmenována DLEVEL.
#if DLEVEL > 5
#define SIGNAL 1
#if STACKUSE == 1
#define STACK 200
#else
#define STACK 100
#endif
#else
#define SIGNAL 0
#if STACKUSE == 1
#define STACK 100
#else
#define STACK 50
#endif
#endif
#if DLEVEL == 0
#define STACK 0
#elif DLEVEL == 1
#define STACK 100
#elif DLEVEL > 5
display( debugptr );
#else
#define STACK 200
#endif
První blok #if zobrazí dvě sady vnořených direktiv #if, #else a #endif.První sada směrnic je zpracována pouze v případě, že DLEVEL > 5 má hodnotu true.Jinak jsou zpracovány příkazy po výrazu #else.
Direktivy #elif a #else ve druhém příkladu se používají k výběru jedné ze čtyř možností na základě hodnoty DLEVEL.Konstanta STACK je nastavena na hodnotu 0, 100 nebo 200 v závislosti na definici DLEVEL.Pokud DLEVEL je větší než 5, pak příkaz
#elif DLEVEL > 5
display(debugptr);
je zkompilován a STACK není definován.
Běžným účelem pro podmíněné kompilace je zabránit vícenásobnému zahrnutí stejného souboru hlavičky.V jazyce C++, kde jsou třídy často definovány v záhlaví souborů, lze konstrukce, jako je následující, použít k zabránění více definicím:
/* EXAMPLE.H - Example header file */
#if !defined( EXAMPLE_H )
#define EXAMPLE_H
class Example
{
...
};
#endif // !defined( EXAMPLE_H )
Předchozí kód zkontroluje, zda symbolická konstanta EXAMPLE_H je definována.Pokud ano, soubor již byl součástí a nemusí být přepracován.Pokud ne, konstanta EXAMPLE_H je definována k označení nadpisu EXAMPLE.H jako již zpracovaného.