2014-03-05 12 views
12

Betrachten Sie den folgenden Code ein:Sind nicht-terminierende consExpr-Funktionen klar definiert?

constexpr unsigned f(unsigned x) 
{ 
    while (x & 1) x *= 3; 
    return x; 
} 

int main() 
{ 
    char a[f(2)]; 
    char b[f(1)]; 
} 

Falls es nicht auf der Hand: für ungerade Zahlen x, die Funktion f endet nie.

Wenn ich das obige Programm kompilieren with clang on coliru, scheint b ein VLA zu sein, aber nicht a:

warning: variable length arrays are a C99 feature [-Wvla-extension] 

char b[f(1)]; 

Gibt es eine gut definierte Grenze, bei der der Compiler Auswertung eines konstanten Ausdruck zu stoppen entscheidet? Oder wäre es vollkommen in Ordnung, wenn ein kompilierender Compiler in eine Endlosschleife geht? Ergibt f(1) UB?

+1

Alternativtitel: "Löst constexpr das Anhalteproblem?" (Witze, natürlich) – stefan

Antwort

7

Es gibt eine Reihe von Dingen, was bedeutet, dass ein Ausdruck keine Kern konstanter Ausdruck ist

- ein Aufruf einer Funktion oder ein constexprconstexpr Konstruktor, der die Implementierung definierte Rekursion überschreiten würde Grenzen;

(fünfter Punkt in §5.19/2.). Das Limit ist also die Implementierung definiert.

+4

Es stellt sich heraus, dass C++ 14 dies nur zu "einem Ausdruck geändert hat, der die von der Implementierung definierten Grenzen überschreiten würde", um auch nicht-rekursive Grenzen abzudecken, in diesem Fall "Ausgewertete Ausdrücke innerhalb einer core constant expression " –

+0

Siehe Anhang B:" In einem Kernkonstantenausdruck ausgewertete Volltexte [1 048 576]. " –

+0

@ JohannesSchaub-litb Ja. Ich begann zu schauen und verlor dann den ursprünglichen Ausdruck. Es ist eine gute Frage: Es muss Grenzen geben, oder der Compiler wird nie aufhören. –