C preprocessor (tsz. C preprocessors)
Az előfeldolgozó utasításokat hajt végre, melyek #
karakterrel kezdődnek, és olyan feladatokat végeznek, mint például:
#include
)#define
)#if
, #ifdef
, #ifndef
, stb.)#error
, #pragma
)
Még a main()
függvény végrehajtása előtt, a forráskód alapján, a fordítási folyamat kezdetén.
A cpp
egy különálló szakasz:
forráskód.c → → előfeldolgozott kód → → gépi kód
Funkció | Leírás |
---|---|
#include
|
Fájlok beillesztése |
#define
|
Makrók és konstansok definiálása |
#undef
|
Makrók eltávolítása |
#ifdef , #ifndef
|
Feltételes fordítás |
#if , #elif , #else , #endif
|
Fordítási logika |
#error , #warning
|
Hibaüzenetek |
#pragma
|
Fordítónak szóló irányelvek |
#include <stdio.h> // szabványos fejlécek
#include "sajat.h" // saját fájl
A #include
szó szerint bemásolja a fájl tartalmát az aktuális helyre.
Ezért fontos az include guard használata:
#ifndef SAJAT_H
#define SAJAT_H
// tartalom
#endif
C++11-től ajánlott:
#pragma once
#define PI 3.14159
Ezután a fordító minden PI
szót kicserél 3.14159
-re.
#define SZORZAT(a, b) ((a) * (b))
Makróhívás: SZORZAT(2+3, 4+1)
→ ((2+3) * (4+1))
⚠️ Zárójeleket mindig használj! Hibás példa:
#define NÉGYZET(x) x * x // veszélyes!
NÉGYZET(1+2)
→ 1+2 * 1+2
→ 5 (nem 9)
#define DEBUG
#undef DEBUG
Hasznos lehet ideiglenes kiiktatásra.
#ifdef DEBUG
printf("Hibakeresés engedélyezve\n");
#endif
Makró nélkül nem fordul be ez a rész.
#if defined(DEBUG) && !defined(PRODUCTION)
printf("Fejlesztői mód\n");
#else
printf("Éles rendszer\n");
#endif
#ifndef VERSION
#error "VERSION nincs definiálva!"
#endif
Ez leállítja a fordítást és hibaüzenetet ad.
#pragma once
Tartalom csak egyszer illeszkedik be. Nem szabványos, de a legtöbb fordító támogatja (GCC, Clang, MSVC).
Más példák:
#pragma GCC optimize ("O3")
#pragma warning(disable: 4996) // MSVC warning kikapcsolása
Jellemző | Preprocessor | C++ |
---|---|---|
Kifejezések típusa | Szöveg alapú | Típusos |
Ellenőrzés | Nincs típusellenőrzés | Van |
Futási idő | Fordítás előtt | Futásidő alatt |
Használati cél | Konfiguráció, elágazás, platformfüggőség | Logika, algoritmus |
#ifdef _WIN32
// Windows specifikus kód
#else
// Unix/Linux kód
#endif
Fordító parancs:
g++ -E main.cpp -o kimenet.ii
Ez az -E
kapcsoló csak az előfeldolgozást hajtja végre.
// debug.h
#ifndef DEBUG_H
#define DEBUG_H
#ifdef DEBUG
#define DEBUG_PRINT(x) std::cout << x << std::endl
#else
#define DEBUG_PRINT(x)
#endif
#endif
Használat:
DEBUG_PRINT("Valami log");
Ha DEBUG
definiálva van: kiírja. Ha nincs: nem történik semmi.
Makró | Leírás |
---|---|
__FILE__
|
Forrásfájl neve |
__LINE__
|
Aktuális sor szám |
__DATE__
|
Fordítás dátuma |
__TIME__
|
Fordítás ideje |
__cplusplus
|
A C++ szabvány verziószáma |
Például:
std::cout << "Hiba itt: " << __FILE__ << ":" << __LINE__ << std::endl;
Fogalom | Leírás |
---|---|
C preprocessor | Előfeldolgozási szakasz a fordítás előtt |
Direktívák | #include , #define , #if , stb.
|
Makró | Szöveg-helyettesítés |
Feltételes kód | Platform vagy konfiguráció alapján |
Hibák elkerülése | Zárójelek, include guard, #pragma once
|
Veszélyek | Nincs típusellenőrzés, nehéz hibakeresés |
A C előfeldolgozó egy erőteljes, de veszélyes eszköz. Helyes használat esetén nagyon rugalmas, például konfigurációk, hibakeresés, platformfüggőség kezelésére.
A modern C++-ban a constexpr
, enum class
, template
, constexpr if
gyakran biztonságosabb és típusos alternatívák lehetnek a #define
helyett.