2009-11-11 7 views
8

Sto cercando di capire cosa fa il seguente codice in C?Spiegazione complicata del cast C

((void(*)())buf)(); 

dove 'BUF' è una matrice char.

+5

Cerca un programma chiamato "cdecl". Scaricalo. Incollare la dichiarazione in esso. Sii illuminato –

+0

@Paul: Ci proverò e spero che non uccida la mia macchina! –

+1

Questo codice potrebbe essere ragionevolmente visualizzato in un JIT o nel sistema operativo in un linker/loader dinamico. Come altri hanno già detto, è roba spaventosa, ma solo se l'hai incontrata in un'applicazione tipica. Al suo posto giusto, non è roba spaventosa, solo cose difficili. –

risposta

21

Facciamo un passo alla volta.

void(*)() 

Questo è un puntatore a una funzione che accetta argomenti non specificati e non ha alcun valore di ritorno.

(void(*)())buf 

imposta semplicemente buf a questo tipo di puntatore di funzione. Infine,

((void(*)())buf)(); 

chiama questa funzione.

Quindi l'intera istruzione è "interpretare buf come puntatore a una funzione void senza argomenti e chiamare tale funzione".

+3

Lanciare un buffer di caratteri in una funzione e chiamarlo è malvagio. È un tentativo di modifica del codice, oppure è un intento malevolo fare un qualche tipo di exploit. Ad ogni modo, evitalo a tutti i costi. –

+0

Correggetemi se ho torto, ma non è il valore del puntatore (l'indirizzo dell'array) che viene trattato come una funzione, non il contenuto dell'array? "interpret * il valore * in buf" suona un po 'come stai dicendo che i contenuti sono interpretati come un puntatore a una funzione. –

+3

-1 (non proprio): accetta argomenti non specificati in C – pmg

9

Inserisce buf in un puntatore di funzione di tipo void(*)() (una funzione che restituisce nulla/non valido e che accetta argomenti non specificati) e la chiama.

Lo standard ANSI non consente realmente il cast dei normali puntatori di dati ai puntatori di funzione, ma la piattaforma può consentirlo.

+0

Come mai puoi lanciare un array su un puntatore a funzione ?? C'è qualche articolo che lo spiega? –

+0

Un puntatore è solo una raccolta di byte come qualsiasi altro valore (che può quindi essere presentato in C come una matrice di caratteri). Probabilmente troverai che altrove nel programma è stato eseguito il contrario di questo: 'char * buf = (char *) function;' o qualcosa di simile. – Wernsey

+0

Puoi farlo perché è C - puoi fare quello che vuoi. È una pessima idea, ma puoi farlo. – Clyde

1

Direi che in molte circostanze, si blocca la macchina. Altrimenti, considera la matrice come un puntatore a una funzione che restituisce nulla e la invoca.

2

Inserisce buf in un puntatore a funzione, che accetta argomenti non specificati e lo chiama.

+1

-1 (non proprio): accetta argomenti non specificati in C – pmg

+0

@ pmg, grazie. Ho modificato la risposta. –

4

Questo lancia buf al tipo void (*)(), un puntatore a una funzione che accetta parametri non specificati e non restituisce nulla. Quindi chiama la funzione a quell'indirizzo (le due parentesi più a destra).

+0

-1 (non proprio): accetta argomenti non specificati in C – pmg

+0

@ pmg, buon punto. –

0

chiama un puntatore a funzione. la funzione non ha argomenti.

Function Pointer - Wikipedia

+1

-1 (non proprio): la funzione ha argomenti non specificati in C – pmg

+0

La funzione ha (viene fornito) nessun argomento. Il tipo di funzione ha parametri non specificati. –

+0

Certo, viste le altre risposte lascerò il post così com'è. – segy

2
 
((void(*)())buf)(); 
\------------/   cast `buf` to 
\---------/   type: pointer to function accepting a fixed but 
           unspecified number of arguments and 
           returning void 
\----------------/  and call that "function" 
+0

+1 Sei corretto sul numero di parametri non specificato. Se avessi chiarito con un esempio, probabilmente avresti ottenuto più apprezzamento per la tua comprensione :) – Andomar

5

Tendo ad usare il comando "cdecl" quando mi imbatto in una dichiarazione da capogiro. Esempio:

[[email protected]]$ cdecl 
Type `help' or `?' for help 
cdecl> explain (void(*)())buf 
cast buf into pointer to function returning void 

Anche se ci sono casi in cui mi auguro che ci sia uno strumento là fuori che spiega l'uscita di "cdecl":/