Warum einen nicht verwendeten Funktionsparameterwert in void umwandeln?

98

In einem C-Projekt habe ich diesen Code gesehen:

static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
    (void)ud;
    (void)osize;
    /* some code not using `ud` or `osize` */
    return ptr;
}

Haben die beiden nichtig gewordenen Abgüsse irgendeinen Zweck?

Bastibe
quelle
Die Abstimmung zum Schließen, da die richtige Antwort (die Compiler-Warnungen vor nicht verwendeten Parametern verhindert) in Charles 'verknüpfter Frage steht.
Ted
@Cody Grey - Es wurde aus diesem Grund geschlossen. Tatsächlich war es jedoch kein Betrug dieser Frage. 689677 sprach von Casting Returns auf void, nicht von Parametern.
Ted
19
Tatsächlich sind beide Duplikate für diese Frage nicht gültig. Eines ist C ++, das andere betrifft Rückgabewerte. Dies sind nicht die gleichen Dinge . Gibt es Duplikate von C-Parametern?
Matt Joiner
2
Dies ist eine andere Frage als die vorgeschlagenen Duplikate. Ich kann jedoch sehen, warum der Fehler gemacht wurde. Wieder geöffnet (offensichtlich).
Tim Post
4
Hinweis: Bitte schließen Sie dies nicht als Duplikat einer C ++ - Frage, da C ++ einen (void)etwas anderen Effekt verwendet. Diese Frage ist über C
Antti Haapala

Antworten:

89

Dies dient dazu, Warnungen des Compilers zu vermeiden, da einige Parameter nicht verwendet werden.

Benoit Thiery
quelle
3
Was ist der beste Weg, um die Warnungen zu unterdrücken: stackoverflow.com/questions/3417837/…
Ciro Santilli 法轮功 冠状 病 六四 六四 法轮功
@ Benoit Was macht Casting to Void eigentlich? Ist es die einzige Funktion, dem Compiler zu zeigen, dass Sie absichtlich etwas ignorieren oder (void) tatsächlich etwas tun, und wenn der Compiler es sieht, zählt er es einfach als etwas mit der Variablen getan und gibt daher keine Warnung aus?
Tan Wang
2
@ TanWang Die einzige Funktion besteht darin, dem Compiler zu zeigen, dass Sie absichtlich etwas ignorieren. Zur Laufzeit wird nichts unternommen.
zwol
14

Der Grund für nicht verwendete Parameter im Prototyp liegt normalerweise darin, dass die Funktion einer externen API entsprechen muss - möglicherweise handelt es sich um eine Bibliotheksfunktion, oder ein Zeiger auf diese Funktion wird an eine andere Funktion übergeben, die diese Aufrufkonvention erwartet. Es werden jedoch nicht alle Argumente, die von der aufrufenden Konvention verwendet werden, tatsächlich in der Funktion selbst benötigt.

Der Grund für die Erwähnung des Parameternamens im Body ist die Vermeidung von Warnungen wie

unused.c: In function l_alloc’:
unused.c:3:22: warning: unused parameter ud [-Wunused-parameter]
 void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
                      ^~

Diese Warnung kann durch Verwendung des Aktualparameters im Funktionskörper unterdrückt werden. Zum Beispiel, wenn Sie die folgende Anweisung haben:

ud;

Diese Warnung wird jetzt unterdrückt. Jetzt wird GCC jedoch eine weitere Warnung ausgeben:

unused.c:5:5: warning: statement with no effect [-Wunused-value]
     ud;
     ^~

Diese Warnung weist darauf hin, dass die Anweisung ud;, obwohl sie syntaktisch gültiges C ist, überhaupt nichts beeinflusst und möglicherweise ein Fehler ist, ähnlich wie die Anweisung

abort;

das hätte vielleicht so geschrieben werden sollen, als abort();ob es etwas tun würde.

Und hier kommt die (void)Besetzung ins Spiel - sie wird dem Compiler eindeutig und explizit mitteilen, dass die Anweisung überhaupt keine Wirkung haben soll.

Antti Haapala
quelle