Perché c ++ proibisce la conversione implicita di void *?

In C, possiamo convertire void* in qualsiasi altro puntatore.

Ma C ++ lo proibisce.

 int *a = malloc(4); 

porta a questo errore:

 invalid conversion from 'void*' to 'int*' [-fpermissive] 

Ci sono pericoli latenti qui in c ++?

Ci sono esempi di c ++?

In C ++, a differenza di C, devi lanciare il risultato di malloc. Il tuo codice può essere ottimizzato per funzionare con un cast semplice.

 int *a = (int *)malloc(sizeof(int)); 

Un grande articolo su questo cast obbligatorio e le ragioni dietro di esso può essere trovato qui.
Un ulteriore collegamento per riferimento può essere trovato qui.

Modifica: come suggerito nei commenti, l’uso di malloc() non dovrebbe essere comune. L’alternativa più vicina è l’utilizzo di new da allocare.

 int *a = new int[15]; 

Modifica aggiuntiva: come suggerito di nuovo nei commenti, se devi usare malloc() , almeno usa un cast di C ++.

 int *a = static_castmalloc(sizeof(int)); // shout out to @edheal, @mgetz 

Puoi fare la conversione in C ++, ma richiede un cast. C ++ mira ad essere un linguaggio più sicuro rispetto al linguaggio C, quindi cerca di chiudere alcuni “buchi nel sistema di tipi” che C consente.

In C, questo sarà accettato senza che sia richiesta alcuna diagnostica:

 int x; void *p = &x; double *q = p; *q = 0.0; 

La sicurezza del tipo è stata violata senza che nessun cast sia presente nel codice sorgente.

Questa è una FAQ in C ++ a risposta di B. Stroustrup, inventore di C ++ .

C ++ non vieta la conversione; vuole solo che sia documentato da una specie di blurb nel codice sorgente, vale a dire un cast che almeno suggerisce, se non prova, che è stato fatto apposta.

Circa l’origine del void * , Stroustrup scrive questo (in grassetto mio):

Alla fine della sua storia, C with Classes * ha iniziato a supportare la nozione di puntatore a “raw memory, void * . L’origine del void * è avvolta in qualche mistero. Ricordo vagamente di averlo inventato insieme a Larry Rosler e Steve Johnson. Tuttavia, Dave Prosser ricorda in primo luogo di averlo suggerito in base a qualcosa usato “da qualche parte in Australia”. Forse entrambe le versioni sono corrette perché Dave ha lavorato a stretto contatto con Larry al momento. In entrambi i casi, void * stato introdotto in entrambe le lingue più o meno allo stesso tempo . La prima menzione del void * che posso trovare è in un memo datato 1 gennaio 1983 sui meccanismi di gestione della memoria forniti dal mio compilatore C ++, Cfront, quindi le origini di void * in C ++ devono risalire almeno alla metà del 1982 . La prima registrazione scritta di void * nel contesto di ANSI C è una proposta di Mike Meissner datata “12 ott 83”, che ha presentato il void * essenzialmente come è stato accettato in ANSI C nel giugno 1984 [Prosser, 2001]

Quindi C ++ eredita il concetto di void * come originariamente lo aveva immaginato Stroustrup, mentre nello stesso periodo, i C avevano un’idea leggermente diversa che era più sciolta nella sicurezza del tipo.

Nel caso di malloc , ovviamente ci sono pericoli; ma quelli sono già contrassegnati dalla presenza dell’identificatore ben noto malloc ; il cast non introduce nulla di più, ma non lo richiede specificatamente per malloc , mentre lo richiede ovunque altrimenti sarebbe un’eccezione scomoda alle regole.


* “C with Classes” è il predecessore di C ++