Lo standard C viene scritto in modo da assumere che i puntatori a tipi di oggetto diversi, e in particolare i puntatori a funzionare in contrapposizione ai tipi di oggetto, potrebbero avere rappresentazioni differenti. Questo è il motivo per cui, in generale, non vuoi mescolare i puntatori, o se fai un compilatore moderno ti avviserà, e se vuoi silenziare gli avvertimenti in genere usi un cast esplicito.
dlsym
, d'altra parte, per la sua stessa esistenza presuppone che tutti i puntatori sono praticamente la stessa, perché si suppone di essere in grado di restituire voi qualsiasi puntatore a qualsiasi tipo di dati - oggetto o funzione - nel vostro file oggetto.
In altre parole, il codice che utilizza dlsym
è intrinsecamente non portabile, nel senso che non è ampiamente portatile, nel senso che è portatile "solo" per quelle macchine in cui tutti i puntatori sono interconvertibili in modo sicuro. (Che è, naturalmente, praticamente tutte le macchine popolari oggi.)
Quindi, sì, è necessario lanciare i puntatori per silenziare gli avvertimenti, e così facendo si potrebbe rendere il codice meno portabile alle macchine dove tutti i puntatori non sono uguali (e dove gli avvertimenti, se non controllati, ti informerebbero correttamente che il tuo codice non funzionerà), ma dlsym
non funzionerà mai (o nemmeno esisterebbe nella sua forma attuale) su quelle macchine, comunque .
(E se gcc -pedantic
si mette in guardia anche un cast esplicito da void *
a un tipo di puntatore a funzione, non c'è molto che si può fare tranne che passare a una versione diversa di gcc
, o, naturalmente, non utilizzare -pedantic
.)
Addendum: La mia risposta ha fatto sembrare che la conversione tra i puntatori a diversi tipi di dati potrebbe essere un problema, ma generalmente non è un problema. Il tipo void *
è ben definito per essere il puntatore di dati generico: è ciò che restituisce malloc
ed è definito per essere tranquillamente convertibile in qualsiasi tipo di puntatore di oggetto, ovvero, non si suppone che sia necessario un cast. Quindi è quasi una buona scelta per il tipo di ritorno di dlsym
, eccetto per il piccolo problema dei puntatori di funzione. malloc
non ha mai questo problema (non avresti quasi mai provato a mallocare un puntatore a una funzione), mentre dlsym
ha sempre questo problema (i simboli che in genere stai cercando di accedere nei file oggetto caricati dinamicamente sono codice almeno tanto spesso quanto sono dati). Ma i puntatori di funzione non sono garantiti per la conversione da void *
, quindi è molto probabile che riceverai avvertimenti, motivo per cui sono necessari i cast e potresti ricevere avvertimenti in -pedantic
anche con i cast.
Vorrei sottolineare che ho trovato la pagina man di 'dlsym()' un po 'opaca in questo senso, ma se qualcuno mi può illuminare sulla pagina di manuale che potrebbe anche aiutare. –
"La rettifica tecnica del 2013 al POSIX.1-2008 (alias POSIX.1-2013) ha migliorato le cose richiedendo che le implementazioni conformi supportino il lancio di" void * "su un puntatore di funzione, tuttavia alcuni compilatori (ad esempio, gcc con '- 'opzione pedante') potrebbe lamentarsi del cast usato in questo programma. " Quando eseguo la compilazione senza cast, al momento 'gcc' e' clang' si lamentano. –
a meno che il compilatore non si lamenti di non volerlo trasmettere. Se si lamenta, assicurati di lanciarlo perché non vede alcun danno nel farlo. – Pradheep