Come rendere ovvio che si accede a una funzione dall'esterno?


9

Questa è una domanda specifica C. Sto cercando di mantenere tutto il possibile all'interno dei confini dell'unità di traduzione, esponendo solo alcune funzioni attraverso il .hfile. Cioè, sto dando un staticcollegamento ad oggetti a livello di file.

Ora, un paio di funzioni devono essere chiamate da altri moduli, ma non direttamente. Il mio modulo / file / unità di traduzione si abbona agli altri moduli, passando un puntatore a una funzione. Quindi, su un evento specifico, il puntatore viene chiamato con alcuni argomenti.

Quindi mi chiedo come rendere molto ovvio che quelle funzioni sono chiamate da una posizione oscura.

  • Dovrebbero essere statico extern(ed esporli nel .h)?
  • Dovrei includere qualche suggerimento nel nome delle funzioni?
  • O è sufficiente inserire un commento "chiamato da X"?

1
Questa è un'ottima domanda. La mia soluzione (con la quale non sono per niente troppo felice, ecco perché lo sto solo inserendo in un commento) è quella di creare più file di intestazione, con un nome ragionevole e funzioni di raggruppamento nell'ambito che desidero che abbiano. Per la libreria AStar che ho realizzato ho AStar.h, AStar_private.h, AStar_packagePrivate.h, ecc ...
Shivan Dragon

Risposte:


2

Dal punto di vista dell'unità di compilazione (file), l'unica cosa di cui dovresti preoccuparti è se la funzione è disponibile all'esterno. Renderlo disponibile significa che doveva essere chiamato e si dovrebbe operare supponendo che tali chiamate avverranno. La tua preoccupazione per la funzione stessa inizia nel suo punto di ingresso. Il modo in cui il controllo ci arriva in primo luogo è importante solo per il codice che lo rende possibile.

Poiché il collegamento in ogni implementazione di CI noto è simbolico, tutto ciò che chiama una funzione deve fare riferimento al suo simbolo:

foo();  /* Direct */

some_function_pointer_t funcs[] = { &foo, &bar, &baz };  /* Indirect */

Se dichiari erroneamente foo()di esserlo static, il tuo programma non si collegherà. Se lo dichiarate non- static, avete una funzione esposta che non viene chiamata. Le domande sull'utilizzo o meno di una funzione possono essere risolte scaricando le tabelle dei simboli dei file degli oggetti o cercandole nei sorgenti.


1

Quindi sto vagando su come rendere molto ovvio che quelle funzioni sono chiamate da una posizione oscura.

Definisci "oscuro".
I metodi dovrebbero essere esposti attraverso "interfacce" ben definite e, come ha già suggerito Shivan Dragon, quelle "interfacce" sono i tuoi file .h. Se non si assegna a un altro programma il file di intestazione "corretto", non è possibile chiamare il metodo.

Dovrebbero essere statici o esterni (ed esporli in .h)?

static potrebbe essere OK fintanto che non hai alcuna classe [-come costrutti] che contenga dati di istanza.
externsignifica che non lo implementi affatto; un'implementazione viene "acquisita" da altrove durante il processo di collegamento.

Dovrei includere qualche suggerimento nel nome delle funzioni?

O è sufficiente inserire un commento "chiamato da X"?

Assolutamente no.

Commenti come questo, non importa quanto ben intenzionati, sono obsoleti nel momento in cui finisci di scriverli.


Rivolgendosi al primo punto, le funzioni sono chiamate come segue. Il mio componente include un .hfile esterno . Chiama una funzione da lì e dà ad essa un puntatore a una delle funzioni del modulo. Successivamente il codice esterno chiama qualunque cosa si trovi a quel puntatore. Quindi la mia funzione viene chiamata da qualcuno, che non include il mio file di intestazione, piuttosto includo il suo.
Vorac,

1
Per quanto riguarda il secondo punto, per quanto mi risulta, l' oggetto, definito nell'ambito del file, ha un collegamento esterno di default; pertanto la externparola chiave è ridondante » .
Vorac,

0

Se le funzioni di callback sono definite all'interno del tuo modulo e l'utente non ne fornirà mai una propria, penso che puoi usare un segnaposto durante la fase di inizializzazione. Il segnaposto è in genere un elemento enumche viene quindi tradotto internamente nella staticfunzione corretta .


0

Li farei comunque static(non sono destinati a essere collegati e chiamati da chiunque) e contrassegnerei il loro scopo come callback forniti a funzioni esterne nel loro nome.

static perché cerco di nascondere ciò che posso nascondere, per quanto posso nasconderlo.

Contrassegnali nel loro nome, perché a), i commenti non sono aggiornati eb), diventa evidente nel punto in cui viene fornito il callback che questa funzione è destinata a essere utilizzata in questo modo: questo in pratica lo rende una bandiera rossa per prendere l'indirizzo di una funzione che non segue la convenzione di denominazione.


0

I modificatori di ambito dovrebbero essere usati principalmente come informazioni per il compilatore, non come forma di documentazione "abbastanza vicina". L'uso di staticin particolare consente a un compilatore C di rendere inutilizzabile la funzione dall'esterno del modulo, incluso come callback, non ciò che si desidera, anche se può funzionare con il compilatore corrente.

Ovviamente dovresti aggiungere un commento al codice, dato che puoi vedere che è una situazione potenzialmente confusa. Qualunque cosa insolita o inaspettata ha bisogno di un commento adeguato. Ma, come affermato in altre risposte, i commenti possono non essere letti o diventare obsoleti.

Pertanto, l'unica opzione rimasta è denominare la funzione per indicare che è una richiamata. La maggior parte degli esempi che ho visto usare _callbacko _cbcome suffisso o cb_come prefisso. Utilizzare la forma lunga se i callback sono insoliti nel codice, la forma breve se sono comuni.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.