Perché eseguire il cast di un valore di parametro di funzione inutilizzato su void?


98

In alcuni progetti C, ho visto questo codice:

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;
}

I due calchi a vuoto servono a qualche scopo?


Si vota per chiudere, poiché la risposta corretta (inibendo gli avvisi del compilatore sui parametri inutilizzati) è nella domanda collegata di Charles.
TED

@Cody Grey - È stato chiuso per questo motivo. Tuttavia non era in realtà un duplice problema. 689677 parlava di casting return to void, non parametri.
TED

19
In realtà entrambi i duplicati non sono validi per questa domanda. Uno è C ++, l'altro riguarda i valori di ritorno. Queste non sono le stesse cose . Esistono duplicati dei parametri C?
Matt Joiner

2
Questa è una domanda diversa da quella che coprivano i duplicati suggeriti. Posso capire perché è stato commesso l'errore, però. Riaperto (ovviamente).
Tim Post

4
Avviso: per favore non chiuderlo come un duplicato di una domanda C ++ poiché C ++ usa (void)con un effetto leggermente diverso. Questa domanda riguarda C
Antti Haapala

Risposte:


89

È lì per evitare avvisi dal compilatore perché alcuni parametri non sono utilizzati.


3
Qual è il modo migliore per sopprimere gli avvertimenti: stackoverflow.com/questions/3417837/...
Ciro Santilli郝海东冠状病六四事件法轮功

@Benoit cosa fa effettivamente casting to void? La sua unica funzione è mostrare al compilatore che stai intenzionalmente ignorando qualcosa o che (void) fa effettivamente qualcosa e quando il compilatore lo vede, lo conterà come se avesse fatto qualcosa con la variabile e quindi non emetterà un avviso?
Tan Wang

2
@TanWang La sua unica funzione è mostrare al compilatore che stai intenzionalmente ignorando qualcosa. Non farà nulla in fase di esecuzione.
zwol

14

Il motivo per non averlo utilizzato parametri nel prototipo è solitamente perché la funzione deve essere conforme a qualche API esterna - forse è una funzione di libreria, o un puntatore a quella funzione viene passato a un'altra funzione che si aspetta questa convenzione di chiamata. Tuttavia, non tutti gli argomenti utilizzati dalla convenzione di chiamata sono effettivamente necessari nella funzione stessa.

Il motivo per menzionare il nome del parametro nel corpo è per evitare avvisi come

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) {
                      ^~

Questo avviso può essere soppresso utilizzando il parametro effettivo nel corpo della funzione. Ad esempio, se hai la seguente dichiarazione:

ud;

Questo avviso è ora soppresso. Tuttavia ora GCC produrrà un altro avviso:

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

Questo avviso dice che l'affermazione ud;, pur essendo sintatticamente valida C, non ha alcun effetto su nulla, ed è forse un errore, non diversamente dall'affermazione

abort;

che forse avrebbe dovuto essere scritto come abort();invece per fare qualcosa.

Ed è qui che (void)entra in gioco il cast: dirà al compilatore in modo inequivocabile ed esplicito che l'affermazione non dovrebbe avere assolutamente alcun effetto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.