Mogelijke duplicaten:
Wat is het gebruik van doen tijdens het gebruik van (0) wanneer We definiëren een macro?
Waarom zijn er soms zinloos doen / terwijl / of / anders uitspraken in C / C++ macro’s?
do {…} terwijl (0) Waar is het goed voor?
Ik heb enkele multi-line C macro’s gezien die in een do / while (0) lus zoals:
zijn ingepakt
#define foo \ \ doen { \ do_stuff_here \ do_more_stuff \ } terwijl (0)
Wat zijn de voordelen (indien aanwezig) van het schrijven van de code op die manier in tegenstelling tot het gebruik van een basisblok:
#define foo \ \ {\ do_stuff_here \ do_more_stuff \ }
Antwoord 1, Autoriteit 100%
Andrey Tarasevich biedt de volgende uitleg:
[kleine wijzigingen in gemaakte opmaak. Parenthetische annotaties toegevoegd in vierkante haakjes []
].
Het hele idee van het gebruik van ‘do / while’-versie is om een macro te maken die dat zal doen
uitbreiden tot een reguliere verklaring, niet in een samengestelde verklaring. Dit is
gedaan om het gebruik van function-stijl macro’s uniform te maken met de
gebruik van gewone functies in alle contexten.Overweeg de volgende codeschets:
if (<condition>) foo(a); else bar(a);
Waar
foo
enbar
zijn gewone functies. Stel je nu voor dat je dat zou doen
Graag functie vervangenfoo
met een macro van de bovenstaande aard [genoemdCALL_FUNCS
]:if (<condition>) CALL_FUNCS(a); else bar(a);
Nu, als uw macro is gedefinieerd in overeenstemming met de tweede aanpak
(Alleen{
en}
) De code zal niet langer compileren, omdat de true ‘
Tak vanif
nu vertegenwoordigd is door een samengestelde verklaring. En wanneer jij
Zet een;
na deze compound-instructie, bent u klaar met de heleif
Verklaring, dus het wezen van deelse
Branch (vandaar de compilatiefout).One Way to Corrigeer dit probleem is om niet te onthouden om niet
;
na te leggen
Macro “aanroepingen”:if (<condition>) CALL_FUNCS(a) else bar(a);
Dit zal samenstellen en werken zoals verwacht, maar dit is niet uniform. De
Meer elegante oplossing is om ervoor te zorgen dat macro zich uitbreidt tot een normale
verklaring, niet in een verbinding één. Een manier om te bereiken, is om te definiëren
de macro als volgt:#define CALL_FUNCS(x) \ do { \ func1(x); \ func2(x); \ func3(x); \ } while (0)
Nu deze code:
if (<condition>) CALL_FUNCS(a); else bar(a);
zal zonder problemen compileren.
Let echter op het kleine maar belangrijke verschil tussen mijn definitie
vanCALL_FUNCS
en de eerste versie in uw bericht. Ik heb geen
;
na} while (0)
. Een;
aan het einde van die definitie plaatsen
zou onmiddellijk het volledige punt verslaan van het gebruik van ‘do / while’ en maken
die macro vrijwel gelijk aan de versie van de compound-statement.Ik weet niet waarom de auteur van de code die u in uw origineel citeert
Bericht Plaats dit;
nawhile (0)
. In deze vorm zijn beide varianten
equivalent. Het hele idee achter het gebruik van ‘Do / While’-versie is niet
neem deze laatste;
op in de macro (om de redenen die ik heb uitgelegd
hierboven).