2015-02-09 22 views

risposta

6

Esempio:

// Declaration: 
int square (int x) __attribute__ ((const)); 
// Definition: 
int __attribute__ ((const)) square (int x) 
{ 
    return x*x; 
} 

La sintassi per tutti gli attributi è più o meno lo stesso: __attribute__ ((<attribute-name>)) o __attribute__ ((<attribute-name> (<attribute-options>))). Citando la documentazione che si collega a:

La parola chiave __attribute__ consente di specificare attributi speciali quando si effettua una dichiarazione. Questa parola chiave è seguita da una specifica di attributo all'interno di doppie parentesi.

ci sono esempi nella documentazione si collega a per diversi altri attributi, tra cui pure:

int square (int) __attribute__ ((pure)); 

così tutto il necessario, la sintassi-saggio, per usare const, è cambiare pure a const:

int square (int) __attribute__ ((const)); 

Come sottolineato nei commenti: se lo si usa in una definizione, allora avete bisogno di mettere __attribute__ ((const)) in una posizione diversa:

int square (int) __attribute__ ((const)) { ... } // doesn't work 
int __attribute__ ((const)) square (int) { ... } // does work 

ma il const e pure attributi sono praticamente utile solo se sono applicati a dichiarazioni esterne, quindi non dovrebbe essere un problema. Se la definizione è visibile, GCC è in genere in grado di determinare se la funzione può essere considerata come const/pure senza il tuo aiuto.

5

Secondo questo this article, la sintassi corrisponde con quello che @hvd dice:

int square (int) __attribute__ ((pure)); 

Tuttavia, sembra che gcc non impone la proprietà di non esaminare lo stato globale quando compilo il seguente esempio.

#include <stdio.h> 

int square (int) __attribute__ ((pure)); 

int outerX = 7; 
int square(int x) { 
    return outerX * x; 
} 

int main(){ 
    printf("%d\n", square(5)); 
    return 0; 
} 

le seguenti stampe senza errori, e le piste di codice e produce 35.

gcc -Wall -Werror -pedantic -O3 Pure.c 


gcc --version 
gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1 

Ancora più stranamente, gcc anche non importa se mutare lo stato globale all'interno della funzione e restituiscono un valore diverso per ogni chiamata causa di una modifica ha causato nello stato globale.

#include <stdio.h> 

int square (int) __attribute__ ((pure)); 

int outerX = 7; 
int square(int x) { 
    outerX++; 
    return outerX * x; 
} 

int main(){ 
    printf("%d\n", square(5)); 
    printf("%d\n", square(5)); 
    printf("%d\n", square(5)); 
    return 0; 
} 

uscita:

40 
45 
50 
+0

Sì, la documentazione è un po 'fuorviante, penso: se una funzione è pura dipende da cosa fa, non da come lo fa. Se una funzione è pura anche se legge variabili globali (ad esempio, poiché tali variabili non cambiano mai), allora può essere dichiarata pura. Per questo motivo, il compilatore non può applicare l'attributo. – hvd

+0

Ha ancora senso con la tua modifica: 'int pure (void) __attribute __ ((pure)); int pure (void) {statico bool pureInited = false; static int pureValue; if (! pureInited) {pureValue = ...; pureInited = true; } return pureValue; } 'Penso che l'attributo' pure' possa essere applicato lì, anche se la funzione modifica le variabili con una durata di memorizzazione statica: l'effetto è comunque che la funzione restituisce sempre lo stesso valore. ('const' potrebbe avere senso anche qui, piuttosto che' pure'.) – hvd

+0

@hvd, pensi che il compilatore urlerà se la funzione restituisce valori diversi su ogni chiamata con gli stessi argomenti? – merlin2011

1

A partire da C++ 11 è possibile utilizzare uno attribute specifier sequence per specificare tali attributi. Per esempio:

[[ gnu::const ]] 
int square (int x) 
{ 
    return x * x; 
} 

Inoltre, a partire da C++ 17 tutti gli attributi sconosciuto a un compilatore vengono ignorati senza causare un errore. Quindi il codice sopra diventa portatile tra diversi compilatori e piattaforme.

Problemi correlati