2009-07-04 13 views
44

Ich habe irgendwo gelesen, dass der ?:-Operator in C in C++ ein wenig anders ist, dass es einige Quellcode gibt, der in beiden Sprachen anders funktioniert. Leider kann ich den Text nirgendwo finden. Weiß jemand, was dieser Unterschied ist?Bedingte Operator Unterschiede zwischen C und C++

Antwort

67

Der Bedingungsoperator in C++ kann einen Lvalue zurückgeben, während C keine ähnliche Funktionalität zulässt.Daher ist die folgende legal ist in C++:

(true ? a : b) = 1; 

dies in C zu replizieren, möchten Sie zurückgreifen, wenn/else oder direkt mit Referenzen befassen:

*(true ? &a : &b) = 1; 

auch in C++, ?: und = Betreiber haben equal precedence and group right-to-left, so dass:

(true ? a = 1 : b = 2); 

gilt C++ Code, aber einen Fehler in C ohne Klammern um die letzte E werfen xpression:

(true ? a = 1 : (b = 2)); 
+19

In C könnte man schreiben * (true? & A: & b) = 1 statt – finnw

+0

@finnw: nützlich. habe meine Antwort entsprechend aktualisiert. – goldPseudo

+5

Der zweite Unterschied besteht nicht in der Reihenfolge der Operationen, sondern in der Priorität des Operators. – Barmar

22

Der wichtigste praktische Unterschied besteht darin, dass in C die Auswertung von?: Niemals zu einem l-Wert führen kann, wie in C++.

Es gibt weitere Unterschiede in der Definition, die nur wenige praktische Konsequenzen haben. In C++ wird der erste Operand in einen bool konvertiert, in C wird er mit 0 verglichen. Dies ist analog zum Unterschied in der Definition von ==,! = Usw. zwischen C und C++.

In C++ gibt es komplexere Regeln, um den Typ eines Ausdrucks?: Auf der Grundlage der Typen des 2. und 3. Operanden abzuleiten. Dies spiegelt die Möglichkeit benutzerdefinierter impliziter Konvertierungen in C++ wider.

Beispielcode. Gültiges C++; invalid C.

extern int h(int p, int q); 

int g(int x) 
{ 
     int a = 3, b = 5; 

     (x ? a : b) = 7; 

     return h(a, b); 
} 

gcc erzeugt den Fehler: "Fehler: ungültige lvalue in Zuordnung", wenn sie als C Kompilieren, aber der Code kompiliert, ohne Fehler, wenn sie als C++ kompiliert.

Edit: Obwohl: nicht ein L-Wert in C zurückkehren, vielleicht überraschend die Grammatik für: ist:

conditional-expression: 
    logical-OR-expression 
    logical-OR-expression ? expression : conditional-expression 

Das bedeutet, dass a ? b : c = d parst als (a ? b : c) = d obwohl (wegen Bei der Regel "kein L-Wert" kann dies nicht zu einem gültigen Ausdruck führen.

C++ die Grammatik dies ändert:

conditional-expression: 
    logical-or-expression 
    logical-or-expression ? expression : assignment-expression 

Während die Erweiterung bedingter Ausdruck zu ermöglichen, ein l-Wert in einigen Situationen wäre a ? b : c = d gültig ohne die Grammatik Änderung vorgenommen hat, das neue Grammatik Änderungsmittel dass der Ausdruck jetzt gültig ist, aber mit der unterschiedlichen Bedeutung von a ? b : (c = d).

Obwohl ich keine Beweise dafür habe, meine Annahme, dass die Grammatikänderung die Kompatibilität mit existierendem C-Code nicht aufheben konnte, war es wahrscheinlicher, dass die neue Grammatik weniger Überraschungen mit Ausdrücken wie:

erzeugte
make_zero ? z = 0 : z = 1; 
+0

Der Teil der Antwort, die C parse beschreibt, ist falsch. In der C-Grammatik kann der LHS-Operator '=' keinen nicht geklammerten '?:' -Operator enthalten. Das vorgeschlagene '(a? B: c) = d'-Parse ist nicht wirklich möglich. In der C-Grammatik 'a? b: c = d 'Ausdruck ist überhaupt nicht analysierbar. Jeder Compiler, der es als "(a? B: c) = d" interpretiert, tut dies auf eigenes Risiko. (Dies ist typischerweise bei hybriden C/C++ - Compilern der Fall, die versuchen, C- und C++ - Grammatiken unter der Haube zu vereinheitlichen.) Formal gibt es kein Problem darin, da ungültiger Code immer noch abgelehnt wird. Aber "keine lvalue" Nachricht ist irreführend. – AnT

+0

In C, 'a? b: c = d 'ist einfach syntaktisches Kauderwelsch, eine nicht-parsierbare Folge von Tokens. Es ist kein Ausdruck. Zu behaupten, dass es einem Nicht-Wert zugewiesen ist, ist falsch, da hier kein "Zuordnen" existiert. – AnT

Verwandte Themen