Warum do { } while (0) in der Makrodefinition verwenden? [duplicate]

Lesezeit: 2 Minuten

Benutzer-Avatar
Chiffre

Mögliches Duplikat:

Warum gibt es in C/C++-Makros manchmal bedeutungslose do/while- und if/else-Anweisungen?

Ich traf Code wie unten:

#define ev_io_init(ev,cb,fd,events) \
do { \
  ev_init ((ev), (cb)); \
  ev_io_set ((ev),(fd),(events)); \
} while (0)

Ich möchte wissen, warum der Autor verwendet do { } while (0) hier. Gibt es hierzu einen Unterschied?

#define ev_io_init(ev,cb,fd,events) { \
  ev_init ((ev), (cb)); \
  ev_io_set ((ev),(fd),(events)); \
}

Übrigens: Der Code stammt von libev, ev_local.h

In Betracht ziehen if( something ) function1(); else function2();

Wenn function1() ist eigentlich ein Makro, nur mit { } erfordert, dass Sie das Semikolon an der Verwendungsstelle weglassen, aber do { } while(0) können Sie genau die gleiche Syntax wie für eine echte Funktion verwenden.

(Überhaupt kein Blockkonstrukt zu verwenden, würde nur völlig kaputten Code erzeugen, natch)

Das Einschließen von Code in eine Schleife ermöglicht es einer Präprozessordirektive, mehrere Anweisungen auszuführen, ohne if-else-Konstrukte zu „unterbrechen“. Folgendes berücksichtigen:

#define DO_SOMETHING() a();b();c();

void foo()
{
    // This is ok...
    DO_SOMETHING();
}

void bar()
{
    // ...whereas this would trigger an error.
    if (condition)
       DO_SOMETHING();
    else
       blah();
}

Das zweite Beispiel unterbricht das if-else-Konstrukt, da auf drei Anweisungen ein folgt else Klausel. Damit es korrekt ersetzt werden kann, sind die Anweisungen in DO_SOMETHING sollte mit a eingeschlossen werden do { ... } while(0).

  • Wenn Sie solche nackten if-Zeilen verwenden, verdienen Sie es natürlich, dass Ihr Code bricht …

    – Simon

    29. Februar 2012 um 8:54 Uhr

  • @Simon Aber rät uns der Linux-Kernel-Codierungsstil nicht, nackte Zeilen zu verwenden, wenn sonst Zeilen für einen Zeilenblock? kernel.org/doc/Documentation/CodingStyle

    – CoderSpinoza

    23. November 2015 um 3:17 Uhr

  • @CoderSpinoza anscheinend so, und wenn ich am Linux-Kernel arbeiten würde, würde ich diesem Stil folgen. Woanders würde ich es vermeiden.

    – Simon

    23. November 2015 um 11:25 Uhr

  • Viele C-Code-Repositorys verwenden einzeilige ifs ohne Klammern, und das ist völlig in Ordnung.

    – Elvis Teixeira

    4. Januar 2018 um 19:37 Uhr

EIN do{}while(0) ermöglicht es Ihnen, aus der Schleife auszubrechen:

do{
   expr1;
   foo();
   if ( cond )
      break;
   expr2;
   goo(); 
} while (0);

Es ist dasselbe wie ein einfacher Block {...} mit der Ausnahme, dass Sie die Ausführung jederzeit unterbrechen können break Aussage. Sie könnten das nicht in einem einfachen Codeblock tun, es sei denn, Sie haben mehrere Überprüfungen, die umständlich werden können. Aufgrund der Bedingung wird es dennoch einmal ausgeführt while(0).

  • …es tut es, aber bitte nicht…

    – Mondschatten

    29. Februar 2012 um 8:50 Uhr

  • Es reduziert die Anzahl der if-else-Verschachtelungen.

    – KRoy

    9. Januar 2018 um 15:21 Uhr

1258180cookie-checkWarum do { } while (0) in der Makrodefinition verwenden? [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy