Wie liest und versteht man C- und C++-Standards und die darin verwendete Sprachgrammatik?

Lesezeit: 5 Minuten

Benutzer-Avatar
Nawaz

Ich finde C- und C++-Standards oft schwer zu lesen und zu verstehen, selbst die einfachen englischen Sätze und ihre Formulierungen geben schreckliche Erfahrungen. Obendrein ist die Sprachgrammatik die absolute Hölle. Ich bin sicher, viele teilen das gleiche Gefühl, zumindest meine Freunde.

Ich möchte es an einigen Beispielen verstehen. Beginnen wir damit (was zu erklären versucht, warum the conditional expression in C++ ist anders aus the conditional expression in C : (Zitiert aus Wikipedia)

Die Bindung von Operatoren in C und C++ wird (in den entsprechenden Standards) eher durch eine faktorisierte Sprachgrammatik als durch eine Rangordnungstabelle spezifiziert. Dadurch entstehen einige subtile Konflikte. In C lautet die Syntax für einen bedingten Ausdruck beispielsweise:

logischer ODER-Ausdruck ? Ausdruck : bedingter Ausdruck

während in C++ es ist:

logischer ODER-Ausdruck ? expression : Zuweisungsausdruck

Daher der Ausdruck:

e = a < d ? a++ : a = d

wird in den beiden Sprachen unterschiedlich geparst. In C ist dieser Ausdruck ein Syntaxfehler, aber viele Compiler analysieren ihn wie folgt:

e = ((a < d ? a++ : a) = d)

Dies ist ein semantischer Fehler, da das Ergebnis des Bedingungsausdrucks (der a++ sein könnte) kein L-Wert ist. In C++ wird es wie folgt analysiert:

e = (a < d ? a++ : (a = d))

was ein gültiger Ausdruck ist.

Bitte jemand erklärt das fetter Text im obigen Zitat! Bitte erläutern Sie die Grammatik mit einigen weiteren Beispielen (insbesondere denen, bei denen sich C und C++ unterscheiden).

EDIT: Ich will es nur wissen wie sie zu lesen und zu verstehen. Ich meine, wenn ich das in gesprochenem Englisch erklären müsste, wie würde ich das dann machen?

  • Die ISO-Standards verwenden EBNF für ihre Grammatikbeschreibungen. Verstehst du, wie man das liest? Wenn ja, sollten die Grammatikregeln ziemlich klar sein. en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_Form

    – CB Bailey

    4. Dezember 2010 um 8:32 Uhr

  • Sind Sie sicher, dass Sie “großartige Erfahrung” (wunderbar) und nicht “erschreckende Erfahrung” (schrecklich) meinen? 🙂

    – fredoverflow

    4. Dezember 2010 um 8:46 Uhr

  • Es gibt gute Gründe, warum solche Standards nicht in „plain English“ geschrieben sind; Nicht zuletzt ist „einfaches Englisch“ im Allgemeinen mehrdeutig und die Standards sollen eindeutig sein. Diese Standards sind nicht als Quelle für Lernmaterial für Anfänger gedacht, sondern als Referenz für Compiler-Autoren (und verwandte Berufe).

    – Höchstleistungszeichen

    4. Dezember 2010 um 9:11 Uhr

  • @Nawaz: Diese dritte Bedeutung ist archaisch – niemand verwendet sie mehr auf diese Weise. “Erschreckend” (oder vielleicht “schrecklich”) sind die Worte, die Sie wollen.

    – wnoise

    4. Dezember 2010 um 9:17 Uhr

  • upvoted für den aufrichtigen Lernversuch

    – hacknrock

    16. Februar 2016 um 14:37 Uhr

Benutzer-Avatar
Paul Dixon

Hier ist eine Beschreibung der C++-Grammatik für Ausdrückedie Zuweisungsausdruck definiert als

assignment-expression:
    conditional-expression 
    unary-expression assignment-operator assignment-expression

Im Klartext kann ein Zuweisungsausdruck entweder ein Bedingungsausdruck ODER ein unärer Ausdruck sein, gefolgt von einem Zuweisungsoperator, gefolgt von einem Zuweisungsausdruck. Ihre nächste Frage lautet also: „Was ist ein bedingter Ausdruck?“, und Sie konsultieren diesen Teil der Grammatik und machen weiter, bis Sie den Grund erreicht haben!

In C++ können Sie also sehen, dass der Operator, auf den Sie sich bezogen haben, einen ‘Bedingungsausdruck’ wie in C annehmen kann, aber auch eine Zuweisung

Also schaust du mit deinem C-Hut auf das Finale a = d Teil des Operators als Zuweisung, was die C-Syntax nicht zulassen sollte. Stattdessen scheinen einige Compiler den letzten Teil des Operators einfach als zu analysieren a zu geben

 e = (a < d ? a++ : a) = d

Aber in C++ ist es gültig, dort eine Zuweisung zu finden, also die a = d wird in seiner Gesamtheit als endgültiger Ausdruck akzeptiert, so dass Sie erhalten

 e = (a < d ? a++ : (a = d))

  • . solche Ausdrücke sind überall in den Standards … Ich möchte nur wissen, wie man sie liest und versteht. Ich meine, wenn ich das in gesprochenem Englisch erklären müsste, wie würde ich das dann machen?

    – Nawaz

    4. Dezember 2010 um 8:32 Uhr

  • .. danke für die Bearbeitung … jetzt kann ich etwas verstehen. 🙂

    – Nawaz

    4. Dezember 2010 um 8:41 Uhr

  • Ihre Referenz für die Zuweisungsausdruck in C++ ist falsch. In C++ ein Zuweisungsausdruck kann sein ” logischer Oder-Ausdruck Aufgabenverwalter Zuweisungsausdruck “, der erste Teil ist nur gerade ” unärer Ausdruck „in c.

    – CB Bailey

    4. Dezember 2010 um 9:01 Uhr


  • Es ist eine rekursive Abstiegs-Parser-Baum-Syntax. H behandelt, wenn und Sie sollten gut sein

    – Aditya Singh Rathore

    22. Juli 2021 um 5:46 Uhr

Sie müssen sich auf was beziehen Zuweisungsausdruck ist. Es ist im C++03-Standard in 5.17/1 definiert [expr.ass] :

assignment-expression:
        conditional-expression
        logical-or-expression assignment-operator assignment-expression
        throw-expression

assignment-operator: one of
        = *= /= %= += -= >>= <<= &= ˆ= |=

Was es sagt, ist, dass ein Zuweisungsausdruck kann sein entweder :

  • EIN bedingter Ausdruck
  • EIN logischer Oder-Ausdruck gefolgt von einem Aufgabenverwalter gefolgt von einem Zuweisungsausdruck
  • EIN Throw-Ausdruck.

Ich zitiere nicht die Grammatikdefinition von allem, weil das ziemlich umfangreich wäre (vor allem weil Bedingungsausdruck deckt vieles ab).

Das erste, was wir sehen, ist also ein Zuweisungsausdruck kann ein bedingter Ausdruck sein, also haben wir die C-Syntax abgedeckt. Was der C++-Standard hinzufügt, ist, dass die rechte Seite der : kann auch etwas sein, das ein enthält Aufgabenverwalter oder ein Wurf.

Das bereitgestellte Beispiel ist gut: e = a < d ? a++ : a = d.

Hier die rechte Seite des : ist ein logischer Oder-Ausdruck (aWeil unärer Ausdruck ist darin enthalten logischer Oder-Ausdruck), gefolgt von einem Aufgabenverwalter (=), gefolgt von einem Zuweisungsausdruck (dWeil unärer Ausdruck ist darin enthalten Zuweisungsausdruck).

Grundsätzlich Dinge wie:

assignment-expression:
    conditional-expression 
    unary-expression assignment-operator assignment-expression

(wie in einigen anderen Antworten hier erwähnt) sind Regeln, die zur Beschreibung der “Grammatik” von gültigem C (oder C++) verwendet werden. Diese niedergeschriebenen Regeln halten sich auch an eine bestimmte Grammatik – daher würde ich vorschlagen, dass Sie diese Grammatik lernen, damit Sie die Regeln lesen und verstehen können.

Für den Anfang könntest du zB studieren Backus-Naur-Form, falls du es noch nicht weißt. (Mein Link führt zum Wikipedia-Artikel zu diesem Thema.) Obwohl der C++-Standard kein Backus-Naur-Formular (IIRC) verwendet, ist er ähnlich genug, um Ihnen den Einstieg zu erleichtern.

1100530cookie-checkWie liest und versteht man C- und C++-Standards und die darin verwendete Sprachgrammatik?

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

Privacy policy