Praktische Unterschiede zwischen "do {...} while (0)" und "{...} ((void) 0)" in Makros?

8

In C ist es üblich:

zu verwenden %Vor%

Während das in Ordnung ist, ist es auch möglich:

%Vor%

{...}((void)0) hat viele der gleichen Vorteile: Sie können die Logik nicht versehentlich zusammenführen, und am Ende der Zeile ist ein ; erforderlich, sodass ungerade Ausdrücke wie dieser nicht unbemerkt bleiben: FOO() else {...} .

Der einzige Unterschied, den ich bemerkt habe, ist, dass Sie geschweifte Klammern in if-Anweisungen verwenden müssen.

%Vor%

Muss wie folgt geschrieben werden:

%Vor%

Abgesehen von dieser Eigenart scheint es gut zu funktionieren und verhindert die gleichen Arten von Problemen, für die do/while method typischerweise verwendet wird.

Gibt es signifikante Unterschiede zwischen den beiden Methoden?

Sagt anders , wenn Sie eine Code-Basis mit {...}((void)0) sehen, sind praktische Gründe, um do{..}while(0) zu verwenden, neben dem einen Unterschied bereits bemerkt?

    
ideasman42 28.02.2015, 03:08
quelle

2 Antworten

6

Der praktische Unterschied ist genau das, worauf Sie hingewiesen haben.

Das do { ... } while (0) idiom bedeutet, dass das Makro in jedem -Kontext verwendet werden kann, der eine Anweisung benötigt.

Ihr vorgeschlagenes Idiom { ... } ((void)0) kann sicher in meisten Kontexten verwendet werden, die einen Ausdruck erfordern - aber es kann fehlschlagen, wenn es in einer unverketteten if -Anweisung verwendet wird.

Ich kann mir keinen guten Grund vorstellen, ein unbekanntes Idiom zu verwenden, das fast immer funktioniert, wenn es ein bekanntes Idiom gibt, das immer funktioniert.

    
Keith Thompson 01.03.2015, 00:00
quelle
2

Ein Unterschied besteht darin, dass Sie break mit #define FOO() do { /* body */ } while (0) verwenden können, aber nicht mit #define FOO() { /* body */ }(void)0 .

Nehmen wir an, Sie befinden sich in einer Funktion, sagen hello() , und machen etwas in #define FOO() do { /*some device operation */ } while (0) , aber es ist ein Fehler aufgetreten, so dass Sie nicht mehr mit diesem Gerät fortfahren wollen, aber es gibt andere Anweisungen in der Funktion hello() Ausführen, sagen wir für ein anderes Gerät.

Wenn Sie also eine zweite Anweisung verwenden, werden Sie höchstwahrscheinlich zurückkehren, die aus hello() austritt, aber wenn Sie die erste Anweisung verwenden, können Sie break und eine Operation in derselben Funktion hello() für ein anderes Gerät ausführen .

    
user1627167 28.02.2015 03:42
quelle

Tags und Links