Geschiedenis:
Macro's komen van de C-taal en zijn een krachtige manier om herhalende codeblokken te automatiseren tijdens de preprocessing-fase. In C++ bieden ze flexibiliteit, maar hebben ze ook veel verborgen gevaren met zich meegebracht vanwege het ontbreken van typecontrole en de onduidelijkheid van de werking van de preprocessor.
Probleem:
De belangrijkste risico's van het gebruik van macro's zijn:
Oplossing:
In de moderne C++-standaarden wordt aanbevolen om inline-functies, sjablonen, constexpr, enum class en constexpr-variabelen te gebruiken in plaats van macro's.
Codevoorbeeld:
// Slecht: #define MAX(a, b) ((a) > (b) ? (a) : (b)) // Goed: template<typename T> constexpr T max(T a, T b) { return a > b ? a : b; }
Belangrijke kenmerken:
Kan een macro gevaarlijker zijn dan een inline-functie?
Ja. Een macro onderwerpt zich niet aan de regels van syntaxis en types. Onverwachte resultaten zijn mogelijk bij het doorgeven van parameters met bijwerkingen.
#define SQUARE(x) ((x) * (x')) int y = 5; int z = SQUARE(y++); // y wordt twee keer verhoogd!
Is #include ook een macro?
Nee, #include is een preprocessor-directive, maar het gebruik van macro's en include is gerelateerd: via een macro kan de lijst van te includen bestanden worden gewijzigd (aanbevolen niet te doen).
Kun je een macro debuggen zoals een gewone functie?
Nee, de debugger onthult de macro en toont al de ingevoegde tekst, er zijn geen afzonderlijke benoembare entiteiten.
In oude code waren talloze berekeningsmacro's gedefinieerd met effecten (bijvoorbeeld, incrementele), wat leidde tot lastig te vangen bugs bij het exploiteren van nieuwe functies.
Voordelen:
Nadelen:
Bij refactoring werden macro's vervangen door sjabloon- en constexpr-functies, en werd enum class gebruikt in plaats van vlag-macro's.
Voordelen:
Nadelen: