A razão para ter parâmetros não usados no protótipo é geralmente porque a função precisa estar em conformidade com alguma API externa - talvez seja uma função de biblioteca ou um ponteiro para essa função é passado para outra função que espera essa convenção de chamada. No entanto, nem todos os argumentos usados pela convenção de chamada são realmente necessários na própria função.
A razão para mencionar o nome do parâmetro no corpo é para evitar avisos como
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) {
^~
Este aviso pode ser suprimido usando o parâmetro real no corpo da função. Por exemplo, se você tiver a seguinte declaração:
ud;
Este aviso foi suprimido. No entanto, agora o GCC produzirá outro aviso:
unused.c:5:5: warning: statement with no effect [-Wunused-value]
ud;
^~
Este aviso informa que a instrução ud;
, embora seja sintaticamente válida em C, não afeta absolutamente nada e é possivelmente um erro, não muito diferente da instrução
abort;
que talvez devesse ter sido escrito abort();
para fazer algo.
E é aí que (void)
entra o elenco - ele dirá ao compilador sem ambigüidade e explicitamente que a instrução não deve ter absolutamente nenhum efeito.