2010-05-09 17 views
28

puro è un attributo di funzione che indica che una funzione non modifica alcuna memoria globale.
const è un attributo di funzione che indica che una funzione non legge/modifica alcuna memoria globale.attributi di funzione pure/const in diversi compilatori

Data questa informazione, il compilatore può fare alcune ottimizzazioni aggiuntive.

Esempio per GCC:

float sigmoid(float x) __attribute__ ((const)); 

float calculate(float x, unsigned int C) { 
    float sum = 0; 
    for(unsigned int i = 0; i < C; ++i) 
     sum += sigmoid(x); 
    return sum; 
} 

float sigmoid(float x) { return 1.0f/(1.0f - exp(-x)); } 

In questo esempio, il compilatore potrebbe ottimizzare la funzione calcolare a:

float calculate(float x, unsigned int C) { 
    float sum = 0; 
    float temp = C ? sigmoid(x) : 0.0f; 
    for(unsigned int i = 0; i < C; ++i) 
     sum += temp; 
    return sum; 
} 

Oppure, se il compilatore è abbastanza intelligente (e non così severo su galleggianti):

float calculate(float x, unsigned int C) { return C ? sigmoid(x) * C : 0.0f; } 

Come posso contrassegnare af unzione in tal modo per i diversi compilatori, ad esempio GCC, Clang, ICC, MSVC o altri?

+1

Per quelli di noi che non utilizzano gcc su base regolare, forse è possibile pubblicare una spiegazione di ciò che è l'attributo pure/const. Se si tratta di un'ottimizzazione di qualche tipo, sarebbe utile anche un esempio di codice C o C++ per il quale aiuta il compilatore a generare un assemblaggio più ottimale. –

+0

Non sono uno scrittore di compilatori, ma mi sembra che tale attributo non sarebbe necessario se la definizione della funzione 'sigmoid()' fosse disponibile per il compilatore * prima di * parsing 'calculate()' nella stessa unità di traduzione. Indipendentemente da ciò, questi attributi potrebbero certamente essere utili quando le definizioni delle funzioni sono in unità di traduzione diverse. – Void

+0

Sì, GCC (e altri compilatori) aggiungono automaticamente questo attributo internamente esattamente in quel caso. E poi, in base all'attributo, possono fare ulteriori ottimizzazioni (come nel mio esempio). E si colpisce esattamente uno dei motivi principali per specificarlo esplicitamente: Se il compilatore non vede la definizione in quel punto o se la definizione non è affatto disponibile o se si pensa che sia sicuro se il compilatore riduce la quantità di chiama alla funzione. – Albert

risposta

26

In generale, sembra che quasi tutti i compilatori supportino gli attributi GCC. MSVC è finora l'unico compilatore che non li supporta (e che non ha alternative).

+1

MSVC non ha inoltre intenzione di aggiungere il supporto per tali attributi: https://connect.microsoft.com/VisualStudio/feedback/details/804288/msvc-add-const-and-pure-like-function-attributes. Dicono che non ne hanno bisogno, il che ha senso per le applicazioni, ma non per le biblioteche. – bcmpinc

+2

Pensa a GNU C come a un dialetto o a una serie di estensioni della lingua. Puoi testare la disponibilità di una specifica caratteristica GNU C in qualsiasi compilatore usando '#if __GNUC__> 4 || ... 'o simile, come raccomandato [nel manuale] (https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html). Clang (e altri compilatori) pubblicizzano solo una versione '__GNUC__' e' __GNUC_MINOR__' che supportano pienamente. L'implementazione potrebbe essere diversa da gcc's (ad es.clang's '__builtin_constant_p()' non propaga costanza in funzione args di funzioni inline), ma il tuo codice verrà compilato. –

+1

In altre parole, clang e ICC potrebbero supportare una nuova funzione da gcc 6.0, ma definirà solo '__GNUC__' a 6 e' __GNUC_MINOR__' a 0 nelle versioni che supportano * tutte * le estensioni di lingua che gcc6.0 fa. –

Problemi correlati