2012-12-06 15 views
8

Scrivo sempre più applicazioni in C, e ora mi chiedo qualcosa sui cast. In C++, un cast dinamico è un'operazione molto costosa (ad esempio un down-cast), ma non so nemmeno per quello statico.Cosa fa veramente un cast di Do?

In C, ho dovuto scrivere qualcosa di simile:

assert (p); /* p is void* */ 
int v = *(int*)p; 

Si tratta di una «C dinamico-fusione»? È esattamente lo stesso del static_cast<int*>(p) di C++? Quanto costa?

Grazie in anticipo.

+2

... per le definizioni appropriate di "molto" ... – DevSolar

+0

Eventuali duplicati di [Come C/C++ compilatori gestire tipo di fusione tra i tipi con diversi intervalli di valori?] (https://stackoverflow.com/questions/340413/how-do-cc-compilers-handle-type-casting-between-types-with-different-value-ra) – jww

risposta

7

Un cast in C è solo significativo in fase di compilazione, perché dice al compilatore come si desidera manipolare un pezzo di dati. Non cambia il valore reale dei dati. Ad esempio, (int*)p dice al compilatore di trattare p come un indirizzo di memoria in un numero intero. Tuttavia questo non costa nulla in fase di esecuzione, il processore tratta solo i numeri grezzi nel modo in cui vengono assegnati ad esso.

+8

Questo non è corretto per tutti i cast. '(float) 0.3' cambia il valore sui sistemi IEEE754. Non è più uguale a '0.3'. –

+0

Questo è vero, grazie. – jazzbassrob

8

A C cast di un puntatore è più simile a un C++ reinterpret_cast. Indica al compilatore di trattare una variabile come di un tipo diverso e non costa nulla in fase di esecuzione.

+1

È quando si esegue il cast da un tipo di puntatore a un altro, ma in questo caso un 'reinterpret_cast' fa la stessa cosa di un' static_cast'. Il casting, per esempio, un doppio di un intero fa il vero lavoro e non è niente come un reinterpret_cast. Per me il confronto con 'static_cast' sembra molto più appropriato di' dynamic_cast'. – sepp2k

+0

@ sepp2k Ho aggiornato la mia risposta per includere il punto sui cast di tipi di puntatore. Non sono sicuro di essere d'accordo con te su statico e reinterpretare le conversioni come identiche per i tipi di puntatore - il compilatore non controlla che i cast statici siano tra tipi compatibili? (Questo forse sta andando in tangente anche se ... Sono d'accordo e ho preso nota del tuo punto principale) – simonc

+0

Hai ragione, 'static_cast' è identico a' reinterpret_cast' ** se ** compila. – sepp2k

2

puntatori sono i puntatori - lanciare un puntatore è una noop.

E 'stata un indirizzo di memoria, prima, si tratta di un indirizzo di memoria in seguito.

Si tratta essenzialmente di una frase "supponiamo che assuma che questo sia un puntatore per digitare x per il controllo del tipo futuro".

Così si potrebbe chiamare questo un reinterpret_cast in termini di C++, in quanto non esegue più momento della compilazione controllo di tipo che per esempio dynamic_cast o static_cast fa.

Non credo che C ha equivalenti di un dynamic_cast ("controllo di tipo runtime inserto qui") o un static_cast ("eseguire i controlli di tipo fase di compilazione in più qui").

Si noti che per i punti di riferimento le cose si comporteranno in modo leggermente diverso.

int b = 1; 
double a = (double) b; 

non è tanto un cast, ma un esplicito tipo conversione.

+0

Si noti che lo standard si riserva esplicitamente il diritto di avere puntatori a tipi diversi di larghezza diversa ... mentre questo è un caso esotico nel mondo odierno delle architetture float IEEE a doppio complemento a 8 bit, gli avvocati della lingua potrebbero seguirti per l'osservazione "noop". ;-) – DevSolar

+0

Ok capito. Quindi è più un suggerimento _compiler_ ** ** di qualsiasi altra cosa? – phaazon

+0

Non proprio un "suggerimento" per il compilatore: - non aiuta il compilatore ad ottimizzare nulla. Ma è una cosa * programmatore *. Non permetto al compilatore * di indovinare * questo è corretto, ma io * dichiaro esplicitamente * che questo dovrebbe essere lanciato, e non è un refuso; dice semplicemente al compilatore che questo non è "un errore, ma intendeva in questo modo". –

5

Un cast di C è più simile a tutti i cast di stile C++ trannedynamic_cast combinato. Quindi, quando lanci un int a un altro tipo intero, è static_cast. Quando lanci puntatori ad altri tipi di puntatori o a tipi interi o viceversa, è reinterpret_cast. Se lanci uno const, è const_cast.

C non ha qualcosa di simile a dynamic_cast poiché ha il concetto di tipi di oggetti e non avrebbe alcun uso per loro come C++ (nessuna funzione virtuale ...). I tipi relativi all'interpretazione dei bit di un oggetto diventano importanti solo se combinati con espressioni che si riferiscono ad oggetti, in C. Gli oggetti non hanno tipi.