Warum genau wird das nicht kompiliert, wenn (a) b = c, d = e, return;

7

Ich bin süchtig nach "braceless" ifs, wie folgt:

%Vor%

Aber eine nervige Sache ist, dass return nicht Teil des letzten Teils sein kann. Intuitiv empfinde ich, warum ist das so, aber kann jemand in Programmiersprache erklären, warum dies nicht kompiliert?

%Vor%

Wenn es Ihnen wichtig ist, erklären Sie bitte auch, warum das so aussieht, es scheint mir ein Fehler zu sein. Ich kann in C verstehen, aber in C ++ hätte es ohne großen Kompatibilitätsverlust mit dem vorhandenen C-Code neu gestaltet werden können.

Nur zum Vergleich: Diese werden kompilieren und tun genau das, was man erwartet:

%Vor%     
exebook 24.12.2013, 18:02
quelle

6 Antworten

23

Der "Komma" -Operator ist genau das, ein Operator. Es sind linke und rechte Seiten müssen Ausdrücke sein, und return ist kein Ausdruck.

Der Komma-Operator wertet zunächst die linke Seite aus und verwirft den Wert. Dann wertet es seine rechte Seite aus, und der gesamte Komma-Ausdruck wird zum Wert der rechten Seite ausgewertet.

Es ist ähnlich:

%Vor%

Daher können Sie nichts in einen Komma-Ausdruck einfügen, der kein Ausdruck selbst ist.

Wenn Sie gleichzeitig eine Reihe von Anweisungen ausführen und sie gruppieren möchten, dann sind dies genau ; und {} . Es gibt keinen Grund, dieses Verhalten im Komma-Operator zu duplizieren.

    
AlchemicalApples 24.12.2013, 18:04
quelle
6

Es kann folgendermaßen gemacht werden

%Vor%

Oe, wenn es keinen Rückgabeausdruck gibt

%Vor%     
Vlad from Moscow 24.12.2013 18:09
quelle
5

Es mag offen sein zu hinterfragen, ob dies die Frage beantwortet, die das OP wirklich gestellt hat, aber für den Fall, dass jemand daran interessiert ist, warum der Komma-Operator so entworfen wurde, denke ich, dass er auf BCPL zurückgeht.

In BCPL können Sie eine Reihe von Zuweisungen kombinieren:

%Vor%

... in eine einzelne Anweisung (Befehl) wie:

%Vor%

Ähnlich wie in C und C ++ wurden diese in der Reihenfolge von links nach rechts ausgeführt. Im Gegensatz zu C und C ++ hat dieser "Komma-Operator" keinen einzigen Ausdruck erzeugt (zumindest so, wie C den Begriff verwendet).

BCPL hatte auch eine resultis , mit der Sie einen Anweisungsblock fast wie eine Funktion in etwas verwandeln können.

Zumindest für mich sieht es wie in C aus, dass Dennis entschieden hat, diese beiden Konzepte zu einer einzigen zu kombinieren, die etwas einfacher ist: ein Komma-Operator, der die Auswertung von a erlaubt Anzahl der Ausdrücke in Folge, und zu einem einzigen Ergebnis führen.

Referenz: BCPL-Referenzhandbuch

  1. Ich denke, fairerweise sollte ich die Möglichkeit erwähnen, dass diese Entscheidung tatsächlich von Ken Thomson in der Gestaltung von B getroffen wurde. Es ist wenig über B dokumentiert, dass es fast unmöglich ist, darüber zu raten.
Jerry Coffin 24.12.2013 19:09
quelle
3

Wie bereits erwähnt return ist kein Ausdruck, es ist ein Schlüsselwort. % Co_de% ist jedoch ein Ausdruck. Daher ist deine Absicht wahrscheinlich dies:

%Vor%

b = c, d = e macht keinen Sinn, da es inkonsistent wäre, wie der Komma-Operator in anderen Kontexten funktioniert. Stellen Sie sich vor, Sie könnten das tun:

%Vor%

Das würde absolut keinen Sinn machen. Es wäre auch überflüssig, wenn b = c, d = e, return in diesem Kontext etwas bedeutet, da der Kommaoperator bereits seinen letzten Operanden zurückgibt. Es wäre auch nicht sinnvoll, da der Kommaoperator bereits seine Operanden auswertet, wie wäre return in diesem Fall vorteilhaft?

Jemand, der sich Ihren Code ansieht, könnte einen Blick darauf werfen und sagen: "Das sollte sein: return something ", was wegen fehlender Klammern eine Falle ist. Was sie wirklich meinen würden, ist if (a) (b = c, d = e); return 0; , aber dieses Problem würde vermieden, wenn Sie die Syntax verwenden, die oben in dieser Antwort erwähnt wird. Es ist einfach nicht lesbar, da es keinen semantischen Sinn ergibt.

Unabhängig davon wäre dies nur dann sinnvoll, wenn if (a) { (b = c, d = e); return 0; } und b globale Variablen wären, wie zum Beispiel d , so dass Sie die Variable zuweisen und in einer Anweisung zurückgeben können.

    
user1508519 24.12.2013 18:09
quelle
1
  

Warum genau wird das nicht kompiliert, wenn (a) b = c, d = e, return;

Dies liegt daran, dass ein Komma ( , ) -Operator seine linken und rechten Operanden als Ausdrücke haben muss. Die return -Anweisung ist kein Ausdruck. Siehe die für , operator vom C- und C ++ - Standard definierte Syntax:

C11: 6.5.17 Komma-Operator

%Vor%

Die gleiche Syntax wird vom C ++ - Standard definiert.

C ++: 5.18 Komma operator [expr.comma]

  

Der Komma-Operator wird von links nach rechts gruppiert.

%Vor%      

Ein durch ein Komma getrenntes Ausdruckspaar 1 wird von links nach rechts ausgewertet;

Beachten Sie, dass der Standard über Ausdrücke sagt und return kein Ausdruck ist.

1.Emphasis ist meins

    
haccks 24.12.2013 18:03
quelle
0
  

Ich kann in C verstehen, aber in C ++ hätte es ohne es neu gestaltet werden können   großer Kompatibilitätsverlust mit dem vorhandenen C-Code.

Es könnte gewesen sein, aber warum sollte es jemals jemand haben wollen? Die Sprache enthält bereits ein Mittel zum Zweck, nach dem Sie suchen - Klammern. Sie sind viel zuverlässiger und nützlicher als den Comma-Operator zu missbrauchen, wie Sie ihn haben. Zum Beispiel, wenn Sie UDTs verwenden, dann werden Sie einige böse Überraschungen erleben, wenn ich den Komma-Operator überlasten werde. Ups!

Noch wichtiger ist, dass return als Ausdruck nicht sinnvoll ist, weil die Funktion bereits, wenn sie ausgewertet wurde, zurückgegeben wurde. Es gibt also keine Möglichkeit, irgendeinen hypothetischen Rückgabewert zu verwenden.

Ihre gesamte Frage basiert auf Ihrer persönlichen Abneigung gegen Zahnspange. Niemand sonst, der die Sprache gestaltet, teilt dieses Gefühl wirklich.

    
Puppy 24.12.2013 18:37
quelle

Tags und Links