Nehmen Sie das folgende Beispiel constexpr:Warum kann ich nach dem Erhöhen von -fconstexpr-steps keinen konstanten Ausdruck auflösen?
#include <iostream>
constexpr int fib(const int i)
{
if (i == 0) return 0;
if (i == 1) return 1;
return fib(i-1) + fib(i-2);
}
int main(){
std::cout << fib(45) << '\n';
}
Trotz constexpr zu sein, ist es nicht bei der Kompilierung ausgewertet.
Der Trick, den ich gelernt habe, die Kompilierung Auswertung zu erzwingen ist, wie folgt:
#include <iostream>
#include <type_traits>
#define COMPILATION_EVAL(e) (std::integral_constant<decltype(e), e>::value)
constexpr int fib(const int i)
{
if (i == 0) return 0;
if (i == 1) return 1;
return fib(i-1) + fib(i-2);
}
int main(){
std::cout << COMPILATION_EVAL(fib(45)) << '\n';
}
Dies funktioniert ist g ++, jedoch bekomme ich den folgenden Fehler in Klirren ++:
clang++-3.9 --std=c++1z -o main main.cpp
main.cpp:14:33: error: non-type template argument is not a constant expression
std::cout << COMPILATION_EVAL(fib(45)) << '\n';
^~~~~~~
main.cpp:4:66: note: expanded from macro 'COMPILATION_EVAL'
#define COMPILATION_EVAL(e) (std::integral_constant<decltype(e), e>::value)
^
main.cpp:9:3: note: constexpr evaluation hit maximum step limit; possible infinite loop?
if (i == 1) return 1;
^
main.cpp:10:21: note: in call to 'fib(7)'
return fib(i-1) + fib(i-2);
^
main.cpp:10:21: note: in call to 'fib(9)'
main.cpp:10:10: note: in call to 'fib(11)'
return fib(i-1) + fib(i-2);
^
main.cpp:10:10: note: in call to 'fib(12)'
main.cpp:10:10: note: in call to 'fib(13)'
main.cpp:10:21: note: (skipping 23 calls in backtrace; use -fconstexpr-backtrace-limit=0 to see all)
return fib(i-1) + fib(i-2);
^
main.cpp:10:10: note: in call to 'fib(41)'
return fib(i-1) + fib(i-2);
^
main.cpp:10:10: note: in call to 'fib(42)'
main.cpp:10:10: note: in call to 'fib(43)'
main.cpp:10:10: note: in call to 'fib(44)'
main.cpp:14:33: note: in call to 'fib(45)'
std::cout << COMPILATION_EVAL(fib(45)) << '\n';
^
1 error generated.
Ich habe versucht, die constexpr-Schritten zu erhöhen, aber Klappern noch den Code nicht kompilieren:
clang++-3.9 -fconstexpr-depth=99999999 -fconstexpr-backtrace-limit=9999999 -fconstexpr-steps=99999999 --std=c++1z -o main main.cpp
Was muss ich für Klirren tun, um diesen Code zu kompilieren wie?
Klirren ++:
clang version 3.9.0-svn267343-1~exp1 (trunk)
g ++:
g++ (Ubuntu 5.1.0-0ubuntu11~14.04.1) 5.1.0
Ich denke, die Tiefe ist wichtig. Funktioniert 'std :: array arr;' auch? fib (45) benötigt ungefähr 6 Sekunden, um auf meiner Maschine zu laufen. Es wird zur Kompilierungszeit nicht ausgewertet. –
Ich habe eine Antwort auf das mögliche Problem gepostet, aber ich denke, es könnte tatsächlich ein Bug im Klirren sein. Siehe [constexpr-Tiefenbegrenzung mit clang (fconstexpr-depth scheint nicht zu funktionieren)] (https://stackoverflow.com/questions/24591466/constexpr-depth-limit-with-clang-fconstexpr-depth-doesnt-seem-to- Arbeit) –
@sleeptightpupper Ich sehe keinen Fehler. Ein fehlendes Feature (um conetexpr-Funktionen zu memotisieren), vielleicht. –