2014-11-03 12 views
7

Sto studiando il linguaggio di programmazione C++ e in un capitolo mio libro mi introduce il concetto di costante:Qual è un valore noto al momento della compilazione?

una costante simbolica constexpr deve essere dato un valore che è noto al momento della compilazione

Qual è un valore noto al momento della compilazione? Perché abbiamo bisogno di loro?

+3

ad esempio: 'int x = 3.0f;', il valore di 'x' è noto al momento della compilazione. – Borgleader

+4

La definizione è fuorviante: un constexpr (in C++ 11) è un valore o una funzione che può essere valutata in fase di compilazione. –

+0

Relativo a ["Espressioni costanti" precedenti a C++ 11] (http://stackoverflow.com/q/26024942/170880) ... nella mia risposta c'è un sacco di lavoro a terra che può essere utile. Ciò che definisce un'espressione costante è difficile da definire in un modo semplice. –

risposta

1

Significa che il programma non deve essere eseguito per calcolare la costante. Per esempio:

int num = 4; 

Hai bisogno di questi valori in modo che il compilatore di inserire le variabili in tabelle di simboli, dove possono essere riferimento il programma e utilizzati. Nel caso delle costanti, il compilatore simbolizza le costanti come valori che non possono essere modificati. Quindi, se si dichiara una costante come qualcosa che viene determinata in fase di esecuzione, non funzionerà, perché se una costante non è definita in fase di compilazione, lo rimane indefinito. Spero che abbia senso.

4

Che cos'è un valore noto al momento della compilazione?

Penso che abbia più senso parlare di espressioni costanti. Un'espressione costante ha un valore che è noto al momento della compilazione. In parole povere, può essere semplicemente un letterale, il nome di un'altra variabile (il cui valore è di nuovo noto al momento della compilazione) o un'espressione complessa che coinvolge sottoespressioni con valori noti al momento della compilazione.

La citazione afferma che l'inizializzatore di una variabile dichiarata con constexpr deve essere un'espressione costante. In particolare ci sono dei requisiti che un'espressione deve soddisfare per essere un'espressione costante; Questi sono elencati here.

Esempi sono

constexpr int i = 54; 
constexpr float f = 684; // Compile-time conversion from int to float 

constexpr int func(int i) 
{ 
    return i*47 % 23; 
} 

constexpr auto value = func(i * f); // Okay; constexpr function called 
            // with arguments that, when substituted inside, 
            // yield constant expressions 

volte un valore non è effettivamente noto al momento della compilazione, ma l'espressione non è una costante uno secondo standard. Che include

int i = 43; 
constexpr int j = reinterpret_cast<int>(i); // Shouldn't compile. (Does with GCC) 

Ci sono casi erano il compilatore può fare costante pieghevole - alcuni valori possono essere calcolati in fase di compilazione, ma non devono essere.

int i = 0; 

for (int j = 1; j != 10; ++j) 
    i += j; 

return i; 

Il compilatore può eliminare completamente i loop e inizializzare i con 55 (o semplicemente restituire 55 ed eliminare i troppo) finché il comportamento rimane lo stesso. Questo è noto come the as-if rule.

+0

In tal caso, rendere un rapporto sui difetti al compilatore o allo standard [isocpp] (https://isocpp.org/). – Surt

+0

@ Surt Penso che gli sviluppatori di GCC lo sappiano bene. – Columbo

+0

Stavo pensando che dovrebbe essere compilato, dal momento che alla fine valuta a i e se 'constexpr int j = i;' è OK, quindi dovrebbe essere anche l'espressione che hai fatto. – Surt

5

A constant expression Un'espressione che può essere valutata in fase di compilazione (vale a dire prima dell'esecuzione del programma, durante la compilazione) da parte del compilatore.

Un'espressione costante può essere utilizzata per inizializzare una variabile contrassegnata con constexpr (referring to the C++11 concept). Tale variabile fornisce al compilatore il suggerimento che potrebbe essere valutata in fase di compilazione (e che potrebbe risparmiare preziosi cicli di esecuzione), ad es.

#include <iostream> 

constexpr int factorial(int n) // Everything here is known at compile time 
{ 
    return n <= 1 ? 1 : (n * factorial(n - 1)); 
} 

int main(void) 
{ 
    constexpr int f = factorial(4); // 4 is also known at compile time 
    std::cout << f << std::endl; 
    return 0; 
} 

Example

Se non si forniscono un'espressione costante, non c'è modo che il compilatore può realmente fare tutto questo lavoro a tempo di compilazione:

#include <iostream> 

constexpr int factorial(int n) // Everything here is known at compile time 
{ 
    return n <= 1 ? 1 : (n * factorial(n - 1)); 
} 

int main(void) 
{ 
    int i; 
    std::cin >> i; 
    const int f = factorial(i); // I really can't guess this at compile time.. 
           // thus it can't be marked with constexpr 
    std::cout << f << std::endl; 
    return 0; 
} 

Example

Il guadagno nel fare la compilazione -tempo di lavoro extra invece del lavoro di runtime è aumento delle prestazioni poiché il programma compilato potrebbe essere in grado di utilizzare valori precalcolati invece di doverli calcolare da zero ogni volta. Più è costosa l'espressione costante, maggiore è il guadagno ottenuto dal programma.

+0

@pieroborrelli è necessario studiare meglio C++, non ho scritto cose complesse. In parole semplici: se hai bisogno di una funzione che calcola qualcosa e sai che potrebbe essere fatta in fase di compilazione invece che in fase di esecuzione, C++ può aiutarti a farlo e precalcolare il valore di quella funzione. Avere il risultato immediatamente durante la compilazione è più efficiente del dover calcolarlo quando il programma è in esecuzione. ** Non riesco a spiegarlo più semplicemente di questo ** –

+0

@ Marco A. OK grazie, solo una domanda: quando uso una variabile inizializzata senza la notazione di constexpr, è quella variabile creata in memoria in fase di esecuzione? –

+0

@pieroborrelli Dipende dal tipo di memoria della variabile (ad esempio statico, automatico, ecc.) Ma non può apparire in un'espressione di constexpr. –

Problemi correlati