In C è possibile eseguire il cast del puntatore del vuoto restituito da malloc
. C fa questo per te ma puoi anche essere esplicito.
malloc
restituisce un puntatore void void *
oppure restituito da un programmatore in altri tipi di puntatore. Oppure il programmatore può contare su C per eseguire la conversione del tipo. Non è previsto che la conversione di tipo C mediante cast sia modificata.
Tuttavia, il codice C che si basa sul compilatore C può essere ostile e difficile da leggere. Un programmatore di sviluppo può aiutare i programmatori di manutenzione che alla fine dovranno leggere il codice.
L'aggiunta di un cast esplicito al valore restituito di malloc
aiuta gli utenti che avranno a leggere il codice e determinare l'intenzione dell'autore. Questo è il vero vantaggio del cast esplicito del puntatore void restituito da malloc
. Questa pratica di programmazione fa NON mis-dirige il compilatore o fa uso di qualche caratteristica del compilatore arcano che potrebbe cambiare.
I seguenti tre esempi evidenziano questa pratica di programmazione. Nel primo esempio, malloc
(che è definito in <stdlib.h>
) è espressamente trasmesso e alcuni lavori banali sono eseguiti .
#include <stdlib.h>
#define nr_chars 4
main()
{
char *data;
data = (char *) malloc(nr_chars*sizeof(char));
*data++ = 'a';
*data++ = 'b';
*data++ = 'c';
*data++ = '\0'; // it is allowed to go one past an array
data -= nr_chars; // back to the front of data
printf("%s\n", data);
// prints abc at the console
}
In questo secondo esempio, l'unica differenza è che <stdlib.h>
sia commentata. Il codice viene ancora eseguito e produce lo stesso risultato. Ora, il "perché" del perché questo funziona è abbastanza diretto. Quando C non trova il prototipo per una funzione, presuppone che la funzione restituisca un int
, ma malloc
restituisce un puntatore vuoto.In questo caso il cast esplicito ha indicato al compilatore C, nonché all'unità di carbonio della sorgente, che il valore restituito da malloc
deve essere convertito in un puntatore di caratteri.
//#include <stdlib.h>
#define nr_chars 4
main()
{
char *data;
data = (char *) malloc(nr_chars*sizeof(char));
*data++ = 'a';
*data++ = 'b';
*data++ = 'c';
*data++ = '\0'; // it is allowed to go one past an array
data -= nr_chars; // back to the front of data
printf("%s\n", data);
// prints abc at the console
}
L'ultimo esempio (yeah) non emette il cast e non include <stdlib.h>
. Sia l'editor di Eclipse che il compilatore si lamentano di questo codice (come dovrebbero). Il messaggio di compilatore è
..\main.c(18) : warning C4047: '=' : 'char *' differs in levels of indirection from 'int'
e il codice sorgente è:
//#include <stdlib.h>
#define nr_chars 4
main()
{
char *data;
data = malloc(nr_chars*sizeof(char));
*data++ = 'a';
*data++ = 'b';
*data++ = 'c';
*data++ = '\0'; // it is allowed to go one past an array
data -= nr_chars; // back to the front of data
printf("%s\n", data);
// compiler displays a "warning" and prints abc at the console
}
Cambiare esempio 3 per includere risultati in nessun avviso e il programma viene eseguito come previsto. Tuttavia, entrambi gli esempi 2 e 3 sono privi del cast esplicito e nel corso della vita del codice scritto in questo stile tale codice sarà più costoso e più probabile che venga modificato in modo errato dagli umani (quindi la spesa aggiuntiva) rispetto all'utilizzo esplicito di cast supportati da C-compilatori.
possibile duplicato del [di conversione non valida dal 'vuoto \ *' a 'nodo \ *' \ [-fpermissive \]] (http://stackoverflow.com/questions/16793587/invalid-conversion-from-void-to -node-fpermissive) –
Non penso che il messaggio di errore fosse 'nullo non può essere usato per inizializzare kiss_fft_ctx'. Penso che fosse 'void *' e 'kss_fft_ctx *'. Questi asterischi fanno una differenza ** BIG ** nel significato e nella comprensione della lingua. – abelenky