Hallo zusammen, ich bin gerade dabei mich in fremden Code einzuarbeiten und dabei auf folgendes gestossen: int func(void) { u16 ret; int status; status = func2(&ret); return status ? : ret; // Diese Zeile verstehe ich nicht } Prinzipiell kenne ich ka die verkürzte if Schreibweise so: x ? y : z FALLS x DANN y SONST z * Irgendwie fehlt mir hier der DANN Zweig * Der SONST Zweig würde u16 zurückgeben und kein int Hat irgendwer einen Rat? Danke, Michael
Die Zeile ist ausgeschrieben Wenn status dann <nichts> sonst ret. Der Returnwert ist also leer oder ret wenn nicht status. int kann auch ein u16 sein, kommt auf die Plattform an. Gruß Fabian
Michael D. schrieb: > return status ? : ret; // Diese Zeile verstehe ich nicht > Prinzipiell kenne ich ka die verkürzte if Schreibweise so: > > x ? y : z > Hat irgendwer einen Rat? IMHO ist das ein Fehler. Da wirst du wohl die Funktion analysieren müssen um festzustellen, was ein sinnvoller Returnwert im Falle von status ist. Aber eine int Funktion kann nicht einfach <nichts> zurückgeben.
x ? : y ist eine GCC spezifische Abkürzung für x ? x : y http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/Conditionals.html#Conditionals
A. K. schrieb: > x ? : y ist eine GCC spezifische Abkürzung für x ? x : y > > http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/Conditionals.html#Conditionals Schrecklich. Warum macht man sowas? Da sind meines Erachtens Fehler vorprogrammiert, wenn der Compiler etwas akzeptiert, was eigentlich eher ein Syntax-Error ist. Jedenfalls sah es Karl Heinz bis eben noch genauso :-) Okay, die Argumentation, man könne damit einen Side-Effect vermeiden, nämlich die Wiederholung von Ausdrücken in Makros und damit eine zweifache Evaluation des Ausdrucks, kann ich ja noch nachvollziehen. Aber dieses Problem zu erschlagen mit einer "Erweiterung" der Syntax des ?-Operators halte ich für grenzwertig. Gruß, Frank
Frank M. schrieb: > Schrecklich. Warum macht man sowas? Da sind meines Erachtens Fehler > vorprogrammiert, wenn der Compiler etwas akzeptiert, was eigentlich eher > ein Syntax-Error ist. Ich sehe das weit weniger kritisch. "Vorprogrammierte Fehler" weil der Compiler Dinge akzeptiert, die nicht dem Standard entsprechen, klingt für mich etwas nach Panik. Manche GCC Erweiterungen sind/waren Versuchsballons, die teilweise später in C99 eingeflossen sind. Aber dann schreib halt -ansi -pedantic-errors rein und du bist es los.
Schon oft habe ich gelesen, dass die ?-Anweisung eine Kurzschreibweise für if sein soll. Kann ich aber gar nicht bestätigen. bei if wird eine Bedingung ausgewertet und bei zutreffen der "then"-Zweig ausgeführt, bei Nicht-Zutreffen - falls vorhanden - der Else-Zweig. Im Gegensatz dazu nimmt der ?-Ausdruck einen Wert in Abhängigkeit der Bedingung an, damit sind Sachen wie neu=bedingung?17:25 möglich. Mit if würde das heißen: if(bedingung)neu=17;else neu=25 Aber ich kann es auch in einen Funktionsaufruf legen: funktion(kalt?wärmen:kühlen) In if-Schreibweise if(kalt)funktion(wärmen);else funktion(kühlen) So gern ich die ?:-Syntax mag, die Implementierung im Compiler habe ich oft ineffektiv gesehen.
Karl heinz Buchegger schrieb: > Aber eine int Funktion kann nicht einfach <nichts> zurückgeben. In PHP geht das sehr wohl. Da kann man auch wild verschiedene Datentüpen innerhalb der Funktion zurückgeben unter anderem auch "nichts" wobei das einfach darin resultiert das man null/false/0 bekommt (je nach Auswertung). Er hat ja nicht geschrieben das es um C und GCC handelt ;P JS kennt es auch, das funktionen nicht immer einen (expliziten) Returnwert haben.
eProfi schrieb: > So gern ich die ?:-Syntax mag, die Implementierung im Compiler habe ich > oft ineffektiv gesehen. Mit hochoptimierten Compilern und Profiling, wo wenig verwendete Codezweige weggeschoben werden, hat sich das geändert. Ganz besonders aber bei Architekturen mit bedingter Ausführung von Befehlen (z.B. ARM) war das von Anfang an recht effizient umsetzbar.
eProfi schrieb: > Aber ich kann es auch in einen Funktionsaufruf legen: > funktion(kalt?wärmen:kühlen) Abgesehen von den Umlauten natürlich schon. Wenn gern etwas unkonventioneller sein darf, dann auch so: (kalt?waermen:kuehlen)(10); Der historische Hintergrund von ?: ist aber weniger eine Kurzschreibweise von if/else. Vielmehr liessen sich nur so wichtige Funktionen wie getc(f) effizient als Makros implementieren - inlining per Präprozessor. Heute kann man das mit ganz offiziellen Inline-Funktionen sprachlich eleganter umsetzen.
Frank M. schrieb: > Schrecklich. Warum macht man sowas? Da sind meines Erachtens Fehler > vorprogrammiert Ich finde es zwar auch schrecklich in diesem Falle :), aber Fehler sind hier keineswegs programmiert. Die meisten C-Programmierer meiden den ternären Operator wie der Teufel das Weihwasser, weil sie ihn nie so gut verstanden haben, dass sie ihn "flüssig lesen" können. Die paar, die ihn benutzen, sind sich daher in ihrer Sache relativ sicher, und solange kein anderer Compiler auf die Idee kommt, den weggelassenen ersten Teil als eine völlig andere Erweiterung zu definieren, schmeißt er einfach nur einen Syntaxfehler, ist also auch kein Portabilitätsproblem. Wenn man die GCC-Erweiterungen nicht haben will, sollte man halt immer mit »-std=c99 -Wall -Wextra -pedantic« compilieren. Warum man sowas implementiert, ist auch klar: weil die Situation, dass man ein fehlendes Ergebnis durch etwas anderes ersetzen will, im praktischen Leben offenbar häufig man auftritt. (Allerdings kannte ich diese GCC-Erweiterung bis soeben auch noch nicht.)
Jörg Wunsch schrieb: > im praktischen Leben offenbar häufig man auftritt. (Allerdings kannte > ich diese GCC-Erweiterung bis soeben auch noch nicht.) Recht verbreitet ist diese Technik als || Operator in Perl, der ja kein logisches 0/1 erzeugt, sondern die Operanden durchreicht.
Jörg Wunsch schrieb: > Warum man sowas implementiert, ist auch klar: weil die Situation, > dass man ein fehlendes Ergebnis durch etwas anderes ersetzen will, > im praktischen Leben offenbar häufig man auftritt. Kann ich mir nicht so richtig vorstellen. Die Bedingung darf dann kein Vergleich sein, sondern muß ein Wert sein. Und nur der Wert 0 wird dann durch was anderes ersetzt. Ist die Bedingung ein Vergleich, dann spart man gerade mal das Schreiben der "1" ein. Die Rückgabe eines Vergleichs erzeugt oftmals mehr Code als ein Sprung bei !=0, da dann ja explizit nach 0/1 gewandelt werden muß. Peter
Jörg Wunsch schrieb: > Warum man sowas implementiert, ist auch klar: weil die Situation, > dass man ein fehlendes Ergebnis durch etwas anderes ersetzen will, > im praktischen Leben offenbar häufig man auftritt. (Allerdings kannte > ich diese GCC-Erweiterung bis soeben auch noch nicht.) Ditto. Ich werde das auch in weiterer Folge nicht verwenden. Mir genügt es in solchen Fällen eine Hilfsvariable zu Hilfe zu nehmen, die mir das Zwischenergebnis aufnimmt. Und dort, wo der ternäre Operator tatsächlich unglaublich praktisch ist (in Argumentlisten von Funktionsaufrufen) hab ich selten komplizierte Ausdrücke, deren doppelte Evaluierung es zu vermeiden gilt. Das es derartige Erweiterungen hauptsächlich nur im gcc gibt, hat einen anderen Grund: Jemand überlegt sich eine Spracherweiterung, die er vernünftig und gut findet. Nun kann nicht einfach jeder kommen und die Sprache C erweitern. Da gibt es Normungsgremien, die solche Dinge beschliessen. Dort wird ein Antrag auf Änderung eingereicht (samt Begründung, Auswirkungen etc) und das Gremium beschliesst oder beschliesst nicht, dass diese Änderung in den offiziellen Sprachstandard eingebracht wird. Nun ist es aber so, dass die Chancen einen derartigen Antrag durchzubringen enorm steigen, wenn man einen Compiler vorweisen kann, der diese Erweiterung bereits enthält. Man dokumentiert damit ,dass die Spracherweiterung prinzipiell machbar ist, mit den bisherigen C-Regeln nicht in Konflikt steht und kann anhand von realen Beispielprogrammen die Erweiterung auch in Aktion zeigen. Kurz und gut: Reicht man den Antrag ein, ist es extrem hilfreich einen gepatchten Compiler zur Verfügung zu haben. Und da bietet sich der gcc natürlich an.
Es gibt aber auch durchaus sehr praktische GCC-Erweiterungen, z.B. die Bereichsangaben bei switch/case. Ansonsten 65536 Cases hinschreiben zu müssen, macht den Code nicht gerade lesbarer. Und diese unsäglichen else/if Monster auch nicht. Sie werden auch lange nicht so effektiv optimiert, wie switch/case mit Bereichen. Peter
Peter Dannegger schrieb: > Es gibt aber auch durchaus sehr praktische GCC-Erweiterungen, z.B. die > Bereichsangaben bei switch/case. Ja, finde ich auch. Wenn muss man denn nerven, damit wir das mal im C1x wiederfinden werden? ;-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.