2016-06-27 19 views
5

Come esperimento, ho appena messo insieme un po 'di codice per generare un std::array<uint32_t, 256> in fase di compilazione. I contenuti della tabella sono una tipica tabella di ricerca CRC - l'unica novità è l'uso delle funzioni constexpr per calcolare le voci anziché mettere una tabella magica autogenerata direttamente nel codice sorgente.Limiti pratici sulla quantità di calcolo di constexpr

In ogni caso, questo esercizio mi ha incuriosito: ci sarebbero state delle limitazioni pratiche sulla quantità di calcolo che un compilatore sarebbe disposto a fare per valutare una funzione constexpr o una definizione di variabile al momento della compilazione? per esempio. qualcosa come il parametro -ftemplate-depth di gcc che crea limiti pratici sulla quantità di valutazione della metaprogrammazione del modello. (Mi chiedo anche se ci potrebbero essere limitazioni pratiche per la lunghezza di un pacchetto parametro - che limiterebbe la dimensione di una fase di compilazione std::array creato utilizzando un oggetto intermedio std::integer_sequence.)

+0

Se ricordo erroneamente, sì, c'è un limite, ma si suppone che sia di ordine di grandezza più grande del ricorsivo limite di istanziazione. – MikeMB

risposta

3

Raccomandazioni per tale possono essere trovati in [implimits] ¶2:

(2.35)   —   Recursive constexpr function invocations [512]

(2.36)   —   Full-expressions evaluated within a core constant expression [1 048 576]

GCC e Clang permettono una regolazione tramite -fconstexpr-depth (che è la bandiera che stavi cercando).

La valutazione delle espressioni costanti viene eseguita praticamente in una sandbox, perché undefined behavior must be preempted by the implementation. Con questo in mente, non vedo perché l'implementazione non possa utilizzare l'intera risorsa della macchina host. Inoltre, non consiglierei di scrivere programmi la cui compilazione richiede gigabyte di memoria o altre risorse irragionevoli ...

+0

OK, "Argomenti modello in una dichiarazione modello [1 024]" contano anche le lunghezze dei pacchetti di parametri? (Sto indovinando sì, altrimenti potresti solo imbatterti in quel limite con codice C++ scritto in modo estremamente mal funzionante.) In tal caso, ciò significherebbe costruire una tabella di ricerca 'std :: array ' per elaborare due byte a un tempo probabilmente non sarebbe pratico. –

+0

@DanielSchepler Non capisco. – Columbo

+0

Alla fine, la tabella viene creata da una funzione 'template constexpr std :: array crc_table_impl (uint32_t crc_poly, std :: integer_sequence ) {return {crc_table_entry (crc_poly, I) ...}; } 'viene passato un' integer_sequence' contenente da 0 a 255. Quindi, se provassi a fare la stessa cosa con 'uint16_t', ci sarebbe un modello intermedio con 65537 argomenti. –