Klammer um Rückgabewerte in C.

74

Sehr oft sehe ich im ANSI C-Code Klammern, die einen einzelnen Rückgabewert umgeben.

So was:-

int foo(int x) {
  if (x)
    return (-1);
  else
    return (0);
}

Warum in diesen Fällen () um den Rückgabewert verwenden? Irgendwelche Ideen? Ich kann keinen Grund dafür sehen.

Tooony
quelle
1
So sieht es aus wie ein Funktionsaufruf ;-).
Toon Krijthe
3
Return ist jedoch kein Funktionsaufruf, es sei denn, Sie sind ein Schemer. :-P
Chris Jester-Young
3
Tooony: Ich möchte wissen, warum die Leute auch unnötige Klammern für sizeof setzen!
Chris Jester-Young
Während ergonomische Post-hoc-Begründungen häufig für die Gewohnheit angeboten werden, lohnt es sich, moderne Sprachen mit Rückgabeanweisungen zu betrachten und zu fragen, ob dieselbe Konvention existiert. AFAIK die Antwort ist ein klares NEIN. Die Antwort von User10392 ist insofern interessant, als sie einen C-spezifischen Vorteil bietet, der sich aus der Gewohnheit ergibt.
AmigoNico

Antworten:

60

Es gibt wirklich keinen Grund ... es ist nur eine alte Konvention.

Um Platz zu sparen, führen Programmierer häufig die endgültige Berechnung in der Rückgabezeile statt in der eigenen Zeile durch, und die Parens stellen sicher, dass diese meistens vorhanden sind, um leichter zu erkennen, dass es sich um eine einzelne Anweisung handelt, die wie folgt zurückgegeben wird:

return (x+i*2);

anstatt

int y = x+i*2;
return y;

Die Klammer wurde zur Gewohnheit und blieb hängen.

Adam Haile
quelle
8
Ich neige dazu, es zu tun, wenn ich so Mathe zurückgebe. Ich weiß nicht, es ist, als ob ich befürchte, dass die Methode zurückkehren wird, bevor die Mathematik fertig ist oder etwas anderes
Wes P
2
Ich bin froh, dass nicht nur ich dachte, es sei unnötig. ;-) Klammern zum Festlegen der Priorität von sind verständlich, aber meiner Meinung nach sollte eine return-Anweisung wie oben in mehrere Anweisungen unterteilt werden. Erhöht die Lesbarkeit und ist weniger fehleranfällig. Wagen Sie es, Nein zur Wurstnotation zu sagen! ;-)
Tooony
10
Platz sparen? Bitte erkläre. Ist return x+i*2;doch kürzer?
TonyK
2
"Die Eltern stellen sicher, dass sie meistens da sind, um leichter zu erkennen, dass es sich um eine einzelne Aussage handelt, die zurückgegeben wird" - was soll das überhaupt bedeuten? Abgesehen von der Grammatik können Sie keine Anweisungen zurückgeben und es wird mehr Platz benötigt als ohne Parens.
Erinnern Sie sich an Monica
2
@MarcLehmann Ich habe keine Ahnung, was es bedeuten soll oder wie es so hoch gewählt und akzeptiert wurde. Das Hinzufügen von Klammern sieht für mich einfach hässlich aus (ich könnte sie sogar für ifet al. Loswerden, wenn ich König wäre). Was make it easier to see that it is a single statement that is returnederstens das ist ein Ausdruck , keine „Anweisung“ - und was - denken Menschen returnein gieriger Operator ist und dass return x+i*2könnte zurückkehren x und den Rest verwerfen? Wenn ja, wow. Oder dachte diese Antwort wirklich über lange Ausdrücke nach, die mehrere Zeilen umfassen könnten? In jedem Fall hat es seinen eigenen Punkt völlig verfehlt.
underscore_d
51

Ein praktisches, aber unwahrscheinliches Motiv ist, dass Sie, wenn Sie den Wert in Klammern setzen, die Rückgabe als Makro definieren und dann einen Protokollcode einfügen können, um alle Ihre Rückgaben zu überwachen.

user10392
quelle
5
Beeindruckend! Es mag unwahrscheinlich sein, aber dies ist das einzige Motiv, das ich jemals für die Angewohnheit gehört habe, die nicht "na ja, jemand dachte wahrscheinlich, es könnte besser aussehen oder konsequenter sein", von denen keines jemals auch nur aus der Ferne schien zwingend für mich. Vielen Dank für dieses bisschen Vernunft!
AmigoNico
1
Interessante Beobachtung. In meinen Experimenten habe ich festgestellt, dass ein für die Rückgabe definiertes Makro Makroargumente ohne Parens zulässt, ein für einen anderen Namen (z. B. Quadrat ) definiertes Makro jedoch nicht. Ich glaube, ich habe diesmal in den Abgrund geschaut ...
Alain O'Dea
1
... besser hoffen, dass niemand eine Funktion aufruft oder einen Inkrementoperator verwendet oder andere Nebenwirkungen in ihren return-Anweisungen hat.
Carl Norum
1
Dies ist ein starkes Argument, keine Klammern für Rückgabeanweisungen zu verwenden
nowox
1
@polynomial_donut - Wenn Sie einen Ausdruck in Ihrer return-Anweisung hatten, können normale makrobezogene Probleme wie die Mehrfachauswertung auftreten.
Carl Norum
23

Mein persönlicher Stil ist es, Klammern zu verwenden, wenn es einen komplexen Ausdruck gibt; z.B,

return (a + b);

aber sie nicht zu verwenden, wenn der Ausdruck ein einfacher Begriff ist

return a;

Ich kann nicht sagen, warum ich das so mache. Nur etwas, das ich vor langer Zeit aufgegriffen habe.

Übrigens denke ich, dass es wie ein Funktionsaufruf aussieht, wie folgt:

return(a);  // ugh

ist unglaublich hässlich und einfach falsch.

Kristopher Johnson
quelle
10
Und subjektiv - ich denke, der Raum sieht schlechter aus (was gleichermaßen, aber entgegengesetzt subjektiv ist).
Jonathan Leffler
Und es gibt return (a);undreturn a ;
20

In der ursprünglichen C-Spezifikation waren Klammern um den Rückgabewert erforderlich. Während moderne C-Compiler und der ANSI C-Standard sie nicht erfordern, wirkt sich das Vorhandensein von Klammern nicht auf den Rückgabewert aus, und Programmierer schließen sie manchmal immer noch aus Gewohnheit ein, ohne mit den Standards vertraut zu sein, um die Übereinstimmung mit einer Stilkonvention zu gewährleisten, die sie erfordert. oder möglicherweise aus Gründen der Abwärtskompatibilität.

Ich sollte hinzufügen, für Leute, die über C ++ nachdenken: Diese Frage bezieht sich auf C und C ist nicht C ++; Dies sind zwei verschiedene Sprachen mit unterschiedlichen Standards, Fähigkeiten, Schwierigkeitsgraden und unterschiedlichen Verwendungsstilen - was auch immer sie gemeinsam haben, es ist ratsam, sie als zwei völlig getrennte Dinge zu behandeln. Eine ähnliche Frage zu C ++ finden Sie unter Sind Klammern um das Ergebnis in einer return-Anweisung von Bedeutung? .

Rakslice
quelle
1
IMHO, dies ist die einzige vernünftige / überzeugende Antwort (da sie erklärt, woher eine seltsame Angewohnheit stammen kann). Ich bin von SO hierher gekommen : Sind Klammern um das Ergebnis in einer return-Anweisung von Bedeutung? Ich habe gerade einen weiteren signifikanten Unterschied zwischen C und C ++ gelernt ...
Scheff
13

Es gibt einige Gründe:

  1. if / while / for / etc. sind alle Steuerschlüsselwörter, die Parens haben müssen. Daher erscheint es oft selbstverständlich, sie auch immer wieder zurückzugeben.

  2. sizeof ist das einzige andere Schlüsselwort , das sie entweder hat oder nicht, mit der Ausnahme , dass in einigen Fällen Sie müssen Pars verwenden. So ist es einfacher, sich daran zu gewöhnen, immer Parens zu verwenden. für sizeof, was eine Logik impliziert: Wenn du kannst, immer tun.

  3. case / goto sind die einzigen Schlüsselwörter, bei denen Sie niemals Parens verwenden. ... und die Leute neigen dazu, diese als Sonderfälle zu betrachten (und möchten, dass sie sich beide von anderen Kontrollschlüsselwörtern abheben, insbesondere von goto).

James Antill
quelle
8

Wenn Sie wie in Ihrem Beispiel -1 zurückgeben, ist dies in Klammern besser lesbar, da das Minus besser sichtbar ist:

return 1

oder

return -1

oder

return (-1)
Stein G. Strindhaug
quelle
4

Vielleicht ist es Brauch - schließlich kamen die Leute, die uns Unix und C gebracht haben, aus dem Multics-Projekt. Multics wurde in PL / I geschrieben, und in PL / I sind die Klammern obligatorisch.

James Jones
quelle
2

Ich habe mit mindestens einem Programmierer zusammengearbeitet, der dachte, Return sei eine spezielle Art von Funktionsaufruf, und war überrascht, als er sah, dass mein Code ohne die Parens übereinstimmte.

AShelly
quelle
1
Und früher wurde es in einigen Zusammenhängen durch eine ziemlich eigenartige Funktion, cret, auf Assembler-Ebene implementiert. Das ist eine umfassende Aussage. Ich sollte eine Referenz finden. Es war in Comers XINU-Buch - das können Sie über eine Google-Suche an der Purdue University finden.
Jonathan Leffler
2

Wie so oft bei der Verwendung von Klammern, denke ich, dient dies nur der Lesbarkeit (z. B. unterstützt Ruby Methodenaufrufe ohne Klammern, die die Argumente enthalten, aber neuere Bücher und Artikel raten zu etwas anderem).

Manrico Corazzi
quelle
-4

Die Klammern in einer return-Anweisung geben dem Compiler an, dass dieser Wert auf dem Stapel anstatt im Speicher zurückgegeben werden soll.

Früher wurde dies (normalerweise) rigoros durchgesetzt, aber heute nehmen die meisten Compiler dies nur als Hinweis.

Dies ist etwas, was ich häufig mache, da ein Fehler alles beschädigen kann, was über eine Speicherreferenz zurückgegeben wird, aber normalerweise keine Auswirkung auf eine Variable hat, die auf dem Stapel zurückgegeben wird.

Die Verwendung des Stapels für transiente Variablen reduziert auch die Speichernutzung und beschleunigt in der Regel den Funktionsaufruf / die Rückgabe, da der Stapel für transiente Daten / Variablen ausgelegt ist.

Diogenes
quelle
1
Wenn es tatsächlich einen Compiler gibt, der dies tut, wäre es großartig, ein Beispiel für die vom Compiler für jeden Fall generierte Assembly zu zeigen
Rakslice
-5

Die Verwendung von Klammern in einer return-Anweisung zeigt ein mangelhaftes Verständnis der C/C++Syntax. So einfach ist das. Aber es ist nicht so schlimm, als würde man alles in geschweifte Klammern setzen:

int foo(int x) {
  if (x) {
    return (-1);
  }
  else {
    return (0);
  }
}

So viele Programmierer machen das. Wenn einer von Ihnen dies liest, möchten Sie es vielleicht erklären.

TonyK
quelle
14
Normalerweise werden geschweifte Klammern verwendet, um die Wahrscheinlichkeit zu verringern, dass bei zukünftigen Änderungen des Codes Fehler auftreten. Die erste Antwort auf diese Frage gibt ein Beispiel: programmers.stackexchange.com/questions/16528/…
Mike Pelley
3
Wenn Sie immer geschweifte Klammern verwenden, wird der Code viel automatischer zusammengeführt. Andernfalls treten mit größerer Wahrscheinlichkeit Konflikte auf, die manuell behandelt werden müssen.
hlovdal
5
Es gibt unzählige Fälle von Fehlern, die aufgrund fehlender geschweifter Klammern auftreten. Ich bin damit einverstanden, dass sie für eine Zeile hässlich sind, aber wenn Sie einen Funktionsaufruf durch ein Makro ersetzen - wie es manchmal aufgrund besonderer Einschränkungen geschieht - oder wenn ein Programm überarbeitet wird, um einen einzeiligen Ausdruck durch einen längeren Satz von Ausdrücken zu ersetzen, werden die Fehler möglicherweise nicht auftreten sofort erkennbar sein und nur in besonderen Fällen auftreten, die nicht automatisch überprüfbar sind. Die geschweiften Klammern sind in einigen Unternehmen (das hatte ich bei einer militärischen Vertragsfirma) auch für 1 Liner eine fest codierte Anforderung.
Coyote
1
MISRA verbietet ausdrücklich das Entfernen dieser "zusätzlichen" Klammern.
Toby