2009-03-27 9 views
93

Gibt es einen Grund, einen ungenutzten Rückgabewert zu stornieren, oder habe ich recht damit, dass es reine Zeitverschwendung ist?Warum werden nicht verwendete Rückgabewerte in void umgewandelt?

Follow-up:

Nun, das scheint ziemlich umfassend. Ich nehme an, es ist besser, als einen unbenutzten Rückgabewert zu kommentieren, da der selbstdokumentierende Code besser ist als der Kommentar. Persönlich werde ich diese Warnungen deaktivieren, da es unnötiges Rauschen ist.

Ich werde meine Worte essen, wenn ein Fehler, weil es entkommt ...

Antwort

65

David's answer deckt so ziemlich die Motivation dafür ab, explizit andere "Entwickler" zu zeigen, von denen Sie wissen, dass diese Funktion zurückkehrt, aber Sie ignorieren sie explizit.

So stellen Sie sicher, dass bei Bedarf immer Fehlercodes behandelt werden.

Ich denke, für C++ ist dies wahrscheinlich der einzige Ort, an dem ich lieber C-Style-Modelle verwende, da die Verwendung der vollständigen statischen Cast-Notation sich hier einfach als Overkill anfühlt. Schließlich, wenn Sie ein ein Codierungsstandard oder Schreiben Sie bewerten, dann auch, es ist eine gute Idee, explizit Staat, zu überladenen Operatoren nennt (nicht Funktionsaufruf Notation) sollte dies auch befreit:

class A {}; 
A operator+(A const &, A const &); 

int main() { 
    A a; 
    a + a;     // Not a problem 
    (void)operator+(a,a); // Using function call notation - so add the cast. 
+0

Dies ist der einzige Ort, an dem ich C-Style Cast bevorzuge. tho in meinem Codierungsstandard, würde ich hinzufügen (ungültig) zu "a + a;" auch (richtig parened, natürlich: p) –

+5

Etwas abseits des Themas, aber warum überhaupt würden Sie "a + a;" so ohne den Rückgabewert zu verwenden? Das scheint wirklich ein Missbrauch von Nebenwirkungen für mich zu sein und verschleiert die Absicht des Codes. –

+1

Nun, die, die du jeden Tag benutzen wirst, wird 'a = a' sein. Dies gibt das zugewiesene Objekt zurück (für alle Klassen, die sich gut verhalten, das ist! :)). Ein anderes Beispiel ist: os << "Hallo Welt" << std :: endl. Jeder von ihnen gibt das "os" -Objekt zurück. –

35

Bei der Arbeit verwenden wir anerkennen, dass die Funktion einen Rückgabewert hat, aber der Entwickler hat behauptet, dass es sicher ist, es zu ignorieren . Da Sie die Frage, wie C++ markiert sollten Sie static_cast verwenden werden:

static_cast<void>(fn()); 

Soweit der Compiler geht Gießen der Rückgabewert hat wenig Sinn für ungültig zu erklären.

+0

Wird die Warnung über nicht verwendete Rückgabewerte unterdrückt? –

+0

Gibt es eine solche Warnung? –

+0

Nein, tut es nicht. @Mykola: Mit GCC4 können Sie ein Attribut anhängen, das besagt, dass der Rückgabewert nicht ignoriert werden darf, was eine Warnung auslösen wird. –

2

Ausgegossen ist kostenlos. Es ist nur eine Information für den Compiler, wie es zu behandeln ist.

+1

Es ist "kostenlos", wenn die Zeit, um es zu schreiben und die anschließende Zeit lesen, verstehen (und dann ignorieren) den Code frei ist. IMO, das Schreiben von '(void)' kostet mich Zeit und Energie und lässt mich fragen, ob der Autor wusste, wie Ausdrücke funktionieren. – wallyk

28

Die Der wahre Grund dafür ist ein Tool, das für den C-Code lint verwendet wird.

Es analysiert Code sucht nach möglichen Problemen und gibt Warnungen und Vorschläge aus. Wenn eine Funktion einen Wert zurückgegeben hat, der dann nicht geprüft wurde, würde lint warnen, falls dies versehentlich war. Um die Warnung lint für diese Warnung zu deaktivieren, übergeben Sie den Anruf an (void).

+1

Es mag auf diese Weise gestartet worden sein, aber die meisten Werkzeuge haben jetzt andere Mechanismen, um solche Warnungen zu unterdrücken. Außerdem - unabhängig davon, warum dies begann, insbesondere im Bereich des sicherheitskritischen Codes - ist dies der übliche Weg, Entwicklerabsichten zu "dokumentieren". –

+3

GCC gibt eine Warnung mit -Wall. – greyfade

5

Für die Funktionalität von Ihnen ist das Programmieren auf Void bedeutungslos. Ich würde auch argumentieren, dass Sie es nicht verwenden sollten, um etwas an die Person zu signalisieren, die den Code liest, wie in der Antwort von David vorgeschlagen. Wenn Sie etwas über Ihre Absichten mitteilen möchten, ist es besser, einen Kommentar zu verwenden. Einen solchen Cast hinzuzufügen, wird nur seltsam aussehen und Fragen über den möglichen Grund aufwerfen. Nur meine Meinung ...

+1

Dies ist ein bekanntes Muster, um anderen explizit mitzuteilen, dass Sie sich nicht um den Rückgabewert kümmern, den Sie nicht vergessen haben, damit umzugehen. – Spidey

+0

'Für die Funktionalität von Ihnen ist das Programm casting to void bedeutungslos. Für die Selbstdokumentation und die Anzahl der Warnungen beim Kompilieren ist es _really_ nicht. 'Sie sollten es nicht verwenden, um der Person, die den Code liest, etwas zu signalisieren, [...] es ist besser, einen Kommentar zu verwenden.'Der beste Kommentar ist _no comment_, wenn sich der Code selbst erklärt. Und wiederum, hält einen gültig warnen Compiler glücklich in dem Prozess. –

+0

"Das Hinzufügen einer Besetzung wie dieser wird nur komisch aussehen und Fragen über den möglichen Grund aufwerfen." Ich habe eine davon entdeckt, und deshalb lese ich das hier. Scheint wie ein mysteriöser Stapel-Missbrauch für mein untrainiertes Gehirn. – mynameisnafe

19

Casting zu void wird verwendet, um Compiler-Warnungen für nicht verwendete Variablen und nicht gespeicherte Rückgabewerte oder Ausdrücke zu unterdrücken.

Der Standard (2003) sagt in §5.2.9/4 sagt,

Jeder Ausdruck explizit umgewandelt werden können, um Typ „cv nichtig.“ Der Ausdruck Wert verworfen.

So können Sie schreiben:

//suppressing unused variable warnings 
static_cast<void>(unusedVar); 
static_cast<const void>(unusedVar); 
static_cast<volatile void>(unusedVar); 

//suppressing return value warnings 
static_cast<void>(fn()); 
static_cast<const void>(fn()); 
static_cast<volatile void>(fn()); 

//suppressing unsaved expressions 
static_cast<void>(a + b * 10); 
static_cast<const void>(x &&y || z); 
static_cast<volatile void>(m | n + fn()); 

Alle Formen gültig sind. Ich mache es normalerweise kürzer als:

//suppressing expressions 
(void)(unusedVar); 
(void)(fn()); 
(void)(x &&y || z); 

Es ist auch in Ordnung.

+0

Außer, dass es die Compilerwarnungen nicht immer deaktiviert. gcc scheint nicht zu reagieren, um auf Void – Matt

+0

@Matt: Welche Version von GCC verwenden Sie? Können Sie Ihren Code auf ideone.com oder stacked-crooked.com veröffentlichen (letzteres ist besser)? – Nawaz

+1

Bedeutet der Standard "verworfen" Formulierung, dass keine Warnung sollte von Linters erhoben werden? –

2

In C ist es vollkommen in Ordnung, in ungültig zu machen. Praktisch jeder wird die Absicht der Aussage verstehen.

In C++ stehen Ihnen weitere Tools zur Verfügung. Da C Abgüsse sind in der Regel verpönt, und da die explizite Umwandlung Ihre Mitarbeiter wahrscheinlich überraschen nichtig wird (es überrascht von mir), ich habe diese Funktion Vorlage irgendwo

template <typename T> 
void use_expression(const T&) {} 

und ich verwende

... 
use_expression(foo()); 

wo Ich schreibe in

+3

Oder einfach "#define IGNORE_RESULT (fn) if (fn)". Funktioniert in C & C++ und die Bedeutung ist sehr klar. – Matt

+0

@Matt gibt es ein Problem mit diesem Makro. Wie wäre es mit 'if (x) IGNORE_RESULT (f()); sonst g(); '? Das 'else' wird an die falsche if-Anweisung angehängt. –

+0

Colin, ja das stimmt. – Matt

1

Auch bei der Überprüfung Ihres Codes entspricht MISTA (oder anderen) Standards, automatische Tools wie LDRA können Sie nicht eine Funktion mit einem Rückgabetyp aufrufen, ohne es einen Wert zurückgeben, es sei denn du e xplicitly den zurückgegebenen Wert in (void) umwandeln

Verwandte Themen