Warum sind leere Ausdrücke in C/C++ zulässig?

Lesezeit: 6 Minuten
int main()
{
  int var = 0;; // Typo which compiles just fine
}

  • Holen Sie sich einen Mikrocontroller mit einer geringen Anzahl von Timern, und bald werden Sie NOP-Befehle verwenden wollen … implementiert mit ; auf C (C++ ist in diesem Szenario unwahrscheinlich)

    – jpinto3912

    5. Mai 09 um 13:37 Uhr

  • @RA ein ;; ist kein Leerzeichen vor einer Compiler-Optimierung: es ist ein NOP.

    – jpinto3912

    5. Mai 09 um 13:38 Uhr

  • @jpinto: Denke, du hast meinen Kommentar falsch gelesen.

    – Haiin

    5. Mai 09 um 13:44 Uhr

  • Technisch gesehen ist dies kein leerer Ausdruck (was C/C++ nicht allow), aber das zweite Semikolon ist ein Null-Ausdruck. Wenn Sie zum Beispiel in einem der Zweige eines bedingten (ternären) Ausdrucks (im leeren Kontext) nichts tun wollen, sind Sie gezwungen, etwas Unnützes zu schreiben (das außerdem mit dem übereinstimmen muss, was im anderen Zweig steht).

    – Marc van Leeuwen

    11. Juli 21 um 12:55 Uhr


Wie sonst könnte assert(foo == bar); zu nichts kompilieren, wenn NDEBUG ist definiert?

  • Nun, mir fällt jetzt ein, dass ich es zu so etwas wie kompilieren lasse 0 oder ((void) 0) wäre wahrscheinlich auch ok, aber trotzdem…

    – j_random_hacker

    14. November 11 um 20:04 Uhr

  • assert() könnte ein Makro sein und kehrt in NDEBUG zu einem Ausdruck ohne Seiteneffekte zurück, z. B. (void)0;

    – Nick

    5. Dezember 17 um 17:04 Uhr

Auf diese Weise drücken sich C und C++ aus NOP.

  • Was bei Mikrocontroller-Systemen mit knappem Budget von größter Bedeutung ist.

    – jpinto3912

    5. Mai 09 um 13:34 Uhr

  • @ jpinto3912: In der Tat ; wird mit ziemlicher Sicherheit nach unten kompilieren gar keine Anleitung, anstatt auf die der Zielplattform NOP Anweisung.

    – j_random_hacker

    14. August ’10 um 4:00 Uhr

  • Das bezweifle ich. Eher ein intrinsischer oder asm. Keine Anweisungen != NOP.

    – Nick

    5. Dezember 17 um 17:02 Uhr

Warum sind leere Ausdrucke in CC zulassig
Dan Fego

Ich bin kein Sprachdesigner, aber die Antwort, die ich geben würde, lautet: “Warum nicht?” Aus Sicht des Sprachdesigns möchte man, dass die Regeln (dh die Grammatik) so einfach wie möglich sind.

Ganz zu schweigen davon, dass “leere Ausdrücke” Verwendungen haben, dh

for (i = 0; i < Wahnsinnszahl; i++);

Will dead-wait (keine gute Verwendung, aber dennoch eine Verwendung).

BEARBEITEN: Wie in einem Kommentar zu dieser Antwort erwähnt, würde wahrscheinlich jeder Compiler, der sein Salz wert ist, dies tun nicht Beschäftigt warten Sie auf diese Schleife und optimieren Sie sie weg. Wenn jedoch etwas Nützlicheres im for-Kopf selbst (außer i++) vorhanden wäre, was ich (seltsamerweise) beim Durchlaufen von Datenstrukturen gesehen habe, dann könnte ich mir vorstellen, dass Sie immer noch eine Schleife mit einem leeren Körper konstruieren könnten (indem Sie / Missbrauch des „für“-Konstrukts).

  • Wird das wirklich warten? Kann der Compiler die Schleife wegoptimieren, da nichts passiert?

    – Tom

    5. Mai 09 um 11:53 Uhr

  • Gute Frage. Jetzt wo du es erwähnst, ich weiß es nicht. Ich weiß nur, dass es sollen. 🙂

    – Dan Fego

    5. Mai 09 um 11:55 Uhr

  • @Tom: Gute Frage. Zumindest in C++ ist die Ausführungszeit laut Standard nicht explizit Teil des “beobachtbaren Verhaltens” des Systems, daher nehme ich theoretisch an, dass ein Compiler dies optimieren könnte. Wenn i jedoch flüchtig ist, ist diese Optimierung verboten.

    – j_random_hacker

    5. Mai 09 um 11:58 Uhr

1643041208 829 Warum sind leere Ausdrucke in CC zulassig
Thomas Padron-McCarthy

Sie möchten in der Lage sein, Dinge zu tun wie

while (fnorble(the_smurf) == FAILED)
    ;

und nicht

while (fnorble(the_smurf) == FAILED)
    do_nothing_just_because_you_have_to_write_something_here();

Aber! Bitte schreiben Sie die leere Anweisung nicht wie folgt in dieselbe Zeile:

while (fnorble(the_smurf) == FAILED);

Das ist eine sehr gute Möglichkeit, den Leser zu verwirren, da man leicht das Semikolon übersieht und daher denkt, die nächste Zeile sei der Schleifenkörper. Denken Sie daran: Beim Programmieren geht es wirklich um Kommunikation – nicht mit dem Compiler, sondern mit anderen Leuten, die Ihren Code lesen werden. (Oder mit sich selbst, drei Jahre später!)

Warum sind leere Ausdrucke in CC zulassig
Jason König

OK, ich füge dies dem Worst-Case-Szenario hinzu, das Sie möglicherweise tatsächlich verwenden:

for (int yy = 0; yy < nHeight; ++yy) {
    for (int xx = 0; xx < nWidth; ++xx) {
        for (int vv = yy - 3; vv <= yy + 3; ++vv) {
            for (int uu = xx - 3; uu <= xx + 3; ++uu) {
                if (test(uu, vv)) {
                    goto Next;
                }
            }
        }
    Next:;
    }
}   

  • +1 für das nützliche Beispiel: Da goto-Labels eine Anweisung haben müssen, aber in den seltenen Fällen, in denen Sie ein goto benötigen, wird das Label oft nur am Ende einer Schleife benötigt, sodass Sie eine NOP-Anweisung benötigen. Sie können gegen gotos wettern, aber es ist gelegentlich vorzuziehen (UND lesbarer), ein goto zu verwenden, um tief verschachtelte Schleifen zu verlassen, anstatt zusätzliche Variablen und if () -Anweisungen zu haben, um jede Schleife einzeln zu verlassen.

    – Darren

    6. November 14 um 17:02 Uhr

1643041208 512 Warum sind leere Ausdrucke in CC zulassig
Tom

Ich weiß ehrlich gesagt nicht, ob dies der wahre Grund ist, aber ich denke, dass es sinnvoller ist, vom Standpunkt eines Compiler-Implementierers darüber nachzudenken.

Große Teile von Compilern werden von automatisierten Tools erstellt, die spezielle Klassen von Grammatiken analysieren. Es scheint sehr natürlich, dass nützliche Grammatiken leere Anweisungen zulassen würden. Es scheint unnötige Arbeit zu sein, einen solchen “Fehler” zu erkennen, wenn er die Semantik Ihres Codes nicht ändert. Die leere Anweisung wird nichts bewirken, da der Compiler keinen Code für diese Anweisungen generiert.

Es scheint mir, dass dies nur ein Ergebnis von “Repariere nichts, das nicht kaputt ist” …

  • +1 für das nützliche Beispiel: Da goto-Labels eine Anweisung haben müssen, aber in den seltenen Fällen, in denen Sie ein goto benötigen, wird das Label oft nur am Ende einer Schleife benötigt, sodass Sie eine NOP-Anweisung benötigen. Sie können gegen gotos wettern, aber es ist gelegentlich vorzuziehen (UND lesbarer), ein goto zu verwenden, um tief verschachtelte Schleifen zu verlassen, anstatt zusätzliche Variablen und if () -Anweisungen zu haben, um jede Schleife einzeln zu verlassen.

    – Darren

    6. November 14 um 17:02 Uhr

1643041208 180 Warum sind leere Ausdrucke in CC zulassig
ib.

Offensichtlich ist es so, dass wir Dinge wie sagen können

for (;;) {
  // stuff
}

Wer könnte ohne das leben?

  • Das ist kein gutes Beispiel, weil zum Beispiel das zweite Semikolon nicht verwendet wird, um eine Anweisung zu beenden. Die zweite Klausel des for ist ein Ausdruck; und das Leerlassen wird als Sonderfall behandelt und ist damit gleichbedeutend mit wahr.

    – neues Konto

    5. Mai 09 um 18:06 Uhr

  • Das ist eigentlich ein schlechtes und irrelevantes Beispiel. Der ; innerhalb der Kopfzeile von for nichts mit dem gemein haben ; in der Frage des OP. Was du drin hast for Header sind überhaupt keine Anweisungen. Und das ; in obigem for sind keine “leeren Aussagen”. Der ; in for sind einfach fest codierte Zeichen von for Syntax ohne besondere Bedeutung. Nur der erste Abschnitt von for Header wird in der Sprachspezifikation als “Anweisung” bezeichnet, aber selbst das ist eine besondere Art von for-spezifische Pseudoaussage mit eigener dedizierter Grammatik.

    – Ant

    24. Oktober 13 um 23:13 Uhr

  • … Mit anderen Worten, die Tatsache, dass for(;;) is legal hat absolut nichts damit zu tun, dass leere Aussagen legal sind. Die beiden werden durch ihre eigenen, absolut unabhängigen Teile der Grammatik- und Sprachspezifikation beschrieben.

    – Ant

    24. Oktober 13 um 23:14 Uhr

  • Und bei der ursprünglichen Frage geht es eigentlich um Aussagen, nicht um Ausdrücke. Das OP hat den Begriff “Ausdruck” anscheinend falsch verwendet, weil sie den Unterschied zwischen Ausdrücken und Anweisungen nicht gelernt haben.

    – Ant

    24. Oktober 13 um 23:15 Uhr

  • Ich kann nicht glauben, dass 13 Personen diesem +1 gegeben haben.

    – Tanveer Badar

    3. Oktober 20 um 5:37 Uhr


.

620340cookie-checkWarum sind leere Ausdrücke in C/C++ zulässig?

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

Privacy policy