2012-06-08 1 views
14

In gcc kann ich foo ? : bar schreiben, die eine Kurzform von foo ? foo : bar ist, aber ich sehe, dass K & R es nicht erwähnt.In C wird die Bedingung "test?: Alt" form (leerer wahrer Fall) unterstützt?

Ist das etwas, auf das ich mich verlassen sollte, definiert in einigen Standards? Oder nur eine (böse) gcc-Erweiterung, die ich vermeiden sollte?

+2

Es ist eine böse gcc-Erweiterung, die Sie vermeiden sollten. – Lundin

+0

Ich weiß nicht, warum alle diese Erweiterung hassen. Es ist sehr prägnant und oft besser repräsentiert was ich meine. Ich wünschte, es würde dem Standard hinzugefügt werden. Wie dem auch sei, sollten Sie es nicht verwenden, wenn Sie Kompatibilität mit anderen Compilern als gcc und clang wünschen. –

Antwort

14

Dies ist eine GCC Erweiterung mit dem Namen:
Conditionals with Omitted Operands.

Es ist nicht Standard c. Using -pedantic Flag für die Kompilierung wird Ihnen sagen, so.

Der mittlere Operand in einem Bedingungsausdruck kann weggelassen werden. Wenn der erste Operand ungleich Null ist, ist sein Wert der Wert des bedingten Ausdrucks.

Daher der Ausdruck

    x ? : y

hat den Wert von x, wenn diese ungleich Null ist; ansonsten der Wert von y.

Dieses Beispiel vollkommen äquivalent zu

    x ? x : y

In diesem einfachen Fall die Möglichkeit, den mittleren Operanden wegzulassen ist nicht besonders nützlich. Wann es nützlich wird, ist, wenn der erste Operand dies tut, oder kann (wenn es ein Makro-Argument ist) einen Nebeneffekt enthalten. Dann würde das Wiederholen des Operanden in der Mitte den Nebeneffekt zweimal ausführen. Das Auslassen des mittleren Operanden verwendet den Wert, der bereits berechnet wurde, ohne die unerwünschten Auswirkungen der Neuberechnung.

Ist das etwas, was ich auf, in einem gewissen Standard definiert verlassen sollte? Oder nur eine (böse) gcc-Erweiterung, die ich vermeiden sollte?

Abhängig von Ihren Anforderungen entspricht, Wenn Ihr Code auf einem anderen Compiler Implementierung andere als GCC laufen does'nt benötigen, dann können Sie es verwenden.Wenn Ihr Code jedoch auf anderen Compilerimplementierungen aufbauen soll, sollten Sie ihn nicht verwenden.

Irgendwie sollte man so viel intuitiven und lesbaren Code wie möglich schreiben, da ich immer vorschlagen würde, solche (hässliche) Konstrukte zu vermeiden.

+2

Danke. Ich denke, ich werde aufhören, es zu benutzen. – blueshift

1

Dies ist eine Erweiterung, die in GCC enthalten ist.

Es wird nicht funktionieren, wenn mit einem anderen Compiler kompilieren (die diese Erweiterung nicht unterstützt).

So würde ich empfehlen, diese Art von Verknüpfung zu vermeiden.

EDIT: Wie @KevinCox darauf hingewiesen, würde auch eine DEFINE nicht funktionieren (siehe 2. Kommentar unten).

+0

Es funktioniert nicht, ich habe noch nie von einem anderen Compiler gehört, der ein solches (nutzloses) Feature implementiert. – Lundin

+0

Diese Funktion ** kann nicht ** ordnungsgemäß über ein Makro implementiert werden. '#define ODER (a, b) ((a)? (a) :(b)) ist falsch, weil es" a "zweimal auswerten kann. Dies kann auch nicht über eine (Inline-) Funktion implementiert werden, da es generisch sein müsste. –

4

Dies ist eine GCC-Erweiterung. Es ist nicht Teil des C-Standards, aber mit dem GCC-Compiler können Sie es verwenden. Einzelheiten finden Sie unter documentation, und beachten Sie die Verhaltensunterschiede zum "äquivalenten" ternären Ausdruck.

Verwandte Themen