2011-08-18 24 views
21

Con il nuovo standard C++ 11, quando devo usare la parola chiave inline sulla parola chiave constexpr? La parola chiave constexpr offre un'ulteriore ottimizzazione oltre inline oppure asserisce semplicemente che le cose devono essere calcolate in fase di compilazione?inline vs. constexpr?

Perché il constexpr funziona nel GCC in alcuni casi in cui la chiamata non è costante, ad esempio chiamando foo(x) su una variabile non constexpr? Si tratta di un bug nel GCC o è effettivamente parte dello standard?

risposta

26

Asserire che qualcosa può essere calcolato in fase di compilazione è un tipo piuttosto forte di ottimizzazione.

Inlining rimuove semplicemente una chiamata di funzione, copiando/incollando il corpo della funzione nel sito di chiamata. Il corpo della funzione deve essere ancora eseguito, è sufficiente salvare l'overhead di una chiamata di funzione.

Ma se si esegue la valutazione dello stesso codice in fase di compilazione, è libero in fase di esecuzione.

Ma né inlineconstexpr sono principalmente sull'ottimizzazione. scopo principale inline s' è quella di sopprimere quella definizione-regola, in modo che le funzioni possono essere definite nelle intestazioni (che è utile per i modelli, e tra l'altro, rende anche l'ottimizzazione inlining più facile)

E constexpr è lì perché è utile nella metaprogrammazione e, incidentalmente, può aiutare il compilatore a ottimizzare meglio il codice, spostando più calcoli in fase di compilazione.

+5

In base a [questa domanda] (http://stackoverflow.com/q/7065200/636019), quando le funzioni 'constexpr' non vengono utilizzate in un contesto che richiede un'espressione costante, il compilatore non è obbligato a calcolare l'espressione in fase di compilazione. – ildjarn

+0

ma ancora specifica che il calcolo * può * essere eseguito in fase di compilazione. Così come con 'inline', non si tratta di ottimizzazione, ma può fornire informazioni aggiuntive che il compilatore può utilizzare per ottimizzare. – jalf

+0

Giusto, stavo solo prendendo in giro l'uso della parola "must". : -] – ildjarn

1

citare wikipedia:

C++ 0x introdurrà la parola constexpr, che permette all'utente di garanzia che un costruttore funzione o un oggetto è una fase di compilazione costante.

Contrassegna le funzioni in linea se sono super brevi. Mark funziona come constexpr se i risultati sono richiesti in fase di compilazione. (Parametri del modello o dimensioni dell'array). Credo che una funzione possa essere sia se necessaria.

È possibile chiamare una funzione di espressione costante o un costruttore con i parametri non-constexpr . Proprio come un letterale intero constexpr può essere assegnato a una variabile non-constexpr, così anche una funzione constexpr può essere chiamata con parametri non-constexpr e i risultati memorizzati nelle variabili non-constexpr . La parola chiave consente solo la possibilità di costanza in fase di compilazione quando tutti i membri di un'espressione sono constexpr.

Quindi, GCC non è corretto in questo.

-2

Mentre inline dice al compilatore "Questa funzione viene utilizzata da qualche parte in questa unità di traduzione e non è pubblica per altri file oggetto", è probabile che il compilatore inserisca il corpo della funzione nel chiamante. Le funzioni constexpr dicono al compilatore "Questa funzione non ha effetti collaterali e non dipende da precondizioni diverse dal parametro stesso."

constexpr le variabili dicono solo" Questa variabile non cambia ei suoi dati possono essere inclusi nel codice. "Tuttavia fa la differenza se si definisce una variabile di constexpr in una funzione statica o non statica, ad esempio se constexpr array è non statico, gcc solo sposta i dati con hardcoded mov -Le istruzioni in pila, mentre static constexpr memorizza solo i dati nel .text -sezione.

lambda espressioni senza cattura assegnati a una variabile possono essere constexpr diverso con cattura, perché senza hanno bisogno di memoria per salvare l'acquisizione e funzionano come una classe vuota con sovraccarico operator() (ma possono anche essere castati per la semplice funzione p unguenti con un unario semplice plus: +[]{}).

+0

'inline' non implica il collegamento interno come sembra che tu stia dicendo nel tuo primo paragrafo –