2012-02-25 13 views
8

In che modo (in GCC/"GNU C") si dichiara un puntatore a funzione che punta a una funzione __attribute__((const))? L'idea è che voglio che il compilatore eviti di generare più chiamate alla funzione chiamata attraverso il puntatore della funzione quando può memorizzare nella cache il valore restituito da una chiamata precedente.Funzione puntatore alla funzione __attribute __ ((const))?

+0

mai fatto che e quasi addormentarsi alla ricerca, ma provate avvolgendo una chiamata per indirizzo di tale funzione con la funzione esplicitamente dichiarato che ha attributo const ed accetta che il puntatore come parametro Se gcc può determinare che l'indirizzo del puntatore stesso e gli argomenti non cambiano, dovrebbe eliminare le chiamate non necessarie. –

+1

@Vlad: ci ho pensato anch'io, ma poi gcc si rifiuta di incorporare la funzione nei casi in cui lo desidero. Inizialmente avevo una funzione wrapper del genere, ma l'ho rimossa per correggere il comportamento di allineamento. Nel caso sia interessante, la funzione in questione è '((pthread_t (*) (void)) 0xffff0fe0)' (la funzione get-thread-pointer di Linux-ARM). –

+0

Interessante domanda. La risposta di Justin ha il risultato desiderato? – Praxeolitic

risposta

3
typedef void (*t_const_function)(void) __attribute__((const)); 

static __attribute__((const)) void A(void) { 
} 

static void B(void) { 
} 

int main(int argc, const char* argv[]) { 
    t_const_function a = A; 

    // warning: initialization makes qualified 
    // function pointer from unqualified: 
    t_const_function b = B; 

    return 0; 
} 

O semplicemente:

__attribute__((const)) void(*a)(void) = A; 
+0

Bleh, 'typedef' è sempre la soluzione quando hai un brutto tipo di puntatore a funzione. Accettato. Ma qualche idea se c'è un modo per scrivere il cast nel mio commento sulla domanda principale senza un 'typedef'? –

+0

@R. Sfortunatamente, io * non * so come avvolgere tutto in una sola istruzione senza un 'typedef' - non sembra possibile su GCC 4.2. '((__attribute __ ((const)) pthread_t (*) (void)) 0xffff0fe0)' è come penso che sarebbe fatto, ma è interpretato in modo diverso da quello che vuoi (sembra che GCC applichi l'attributo al tipo restituito, non la funzione). – justin

0

Anche se questo non è proprio la risposta alla tua domanda, probabilmente vogliono sapere questo:

Non è possibile nel caso generale si aspettano il compilatore per eseguire l'ottimizzazione che ci si aspetta qui. Il compilatore non può, nel caso generale, fare l'analisi alias necessaria per sapere che più usi di un puntatore di funzione corrispondono alla stessa funzione.

Una chiamata di funzione tra due invocazioni della funzione attraverso il puntatore potrebbe, nel caso generale, alterare il contenuto del puntatore, causando così la funzione invocata diversa nella seconda chiamata.

A causa della natura di C, l'analisi alias corretta è spesso intrattabile e non è probabile che questo tipo di ottimizzazione si verifichi.

+2

Questo è ciò che __attribute __ ((const)) fa - dice al compilatore che conosci meglio e dà il via libera a certe ottimizzazioni. –

+0

Nel mio caso può sapere, però, perché il puntatore è un letterale di indirizzo (un cast intero su un puntatore di funzione). Vedi i commenti. –

+2

@Vlad: Penso che il punto di Perry fosse che anche se la funzione puntata è 'const', il compilatore dovrebbe anche essere sicuro che il * puntatore * non sia cambiato tra le invocazioni. Ma non è troppo difficile da determinare, e nel mio caso non è possibile dal momento che è un indirizzo letterale assoluto. –

Problemi correlati