2016-07-14 94 views
5

Considerate questo codice:In quale unità di compilazione vive una variabile constexpr?

struct foo 
{ 
    static constexpr int value = 42; 
}; 

void bar(const int* value) { std::cout << *value; } 
int main() { bar(&foo::value); } 

Questo compila avvertimenti fini e senza sotto il couple di online compilers ho provato. Dato che non esiste un singolo file .cpp che definisce il valore constexpr, il valore del puntatore potrebbe essere diverso se il metodo bar viene richiamato da diverse unità di compilazione? Oppure lo standard garantisce che il valore finisca assegnato solo una volta su tutte le unità di compilazione (cioè un implicito _declspec(selectany))?

+0

Hai appena compilato, o anche collegato il programma? –

+1

Non appena l'utente [utilizza effettivamente] (http://ideone.com/Bi5oEt), è necessario fornire una definizione. –

+0

Questo codice viola la regola a una definizione, ma poiché questo comportamento non è definito, i compilatori non devono emettere alcun avviso. – cpplearner

risposta

9

Non funziona per me --- Ottengo un errore di linker. http://coliru.stacked-crooked.com/a/59e2cf56122733d0

Se fate non ODR-utilizzare il membro constexpr statico, si può immaginare che si tratta di inline laddove richiesto e non vive in ogni unità di compilazione. Se si do odr-utilizzarlo, come è stato fatto nel programma, è necessario impostare .

+0

E come lo definisci? Ho pensato che il valore necessario per essere assegnato alla dichiarazione fosse utilizzabile come constexpr. Lo assegni sia alla dichiarazione che alla definizione? – Trillian

+0

@Trillian Se lo si inizializza nella dichiarazione, non lo si inizializza nella definizione. – Brian

+0

Sì, ma constexpr richiede l'inizializzazione all'inizializzazione di dichiarazione e odr alla definizione? – Trillian

1

Generalmente l'indirizzo di un oggetto costituisce un uso di odr, che richiederebbe la definizione dell'oggetto da qualche parte (causando errori di linker se non lo è). Tuttavia, l'assunzione di indirizzi può essere considerata non un uso odr se l'espressione risultante è un valore scartato. Probabilmente il tuo utilizzo potrebbe essere trattato da alcuni compilatori come rientranti nell'esenzione in quanto viene passato come parametro a una funzione che immediatamente lo elimina.

4

Le altre risposte sono corrette ma la situazione cambierà in C++ 17, con l'adozione di inline variables (p0386). constexpr sarà quindi implicito in linea.

+1

Per essere chiari, solo 'constexpr' su un membro dati classe statici implicherà inline :-) –

Problemi correlati