We know that C++ template metaprogramming is Turing complete, but preprocessor metaprogramming is not.
C++11 gives us a new form of metaprogramming: computation of c
tl;dr: constexpr in C++11 was not Turing-complete, due to a bug in the specification of the language, but that bug has been addressed in later drafts of the standard, and clang already implements the fix.
constexpr, as specified in the ISO C++11 international standard, is not Turing-complete. Sketch proof:
constexpr function f's result (or non-termination) on a particular sequence of arguments, a..., is determined only by the values of a...[basic.types]p10 is either:
a... which f can receive is finite, so any finitely-described constexpr system is a finite state machine, and thus is not Turing-complete.However, since the publication of the C++11 standard, the situation has changed.
The problem described in Johannes Schaub's answer to std::max() and std::min() not constexpr was reported to the C++ standardization committee as core issue 1454. At the February 2012 WG21 meeting, we decided that this was a defect in the standard, and the chosen resolution included the ability to create values of class types with pointer or reference members that designate temporaries. This allows an unbounded quantity of information to be accumulated and processed by a constexpr function, and is sufficient to make constexpr evaluation Turing-complete (assuming that the implementation supports recursion to an unbounded depth).
In order to demonstrate the Turing-completeness of constexpr for a compiler that implements the proposed resolution of core issue 1454, I wrote a Turing-machine simulator for clang's test suite:
http://llvm.org/svn/llvm-project/cfe/trunk/test/SemaCXX/constexpr-turing.cpp
Trunk versions of both g++ and clang implement the resolution of this core issue, but g++'s implementation currently is unable to process this code.
Have a look at these. I compiled the examples and they work in GCC 4.6: Compile-time computations, Parsing strings at compile-time - Part I, Parsing strings at compile-time - Part II
If we take in account restrictions of real computer - such as finite memory and finite value of MAX_INT - then, of course, constexpr (and also the whole C++) is not Turing-complete.
But if we will remove this restriction - for example, if we will think about int as a completely arbitary positive integer - then yes, constexpr part of C++ will be Turing complete. It is easy to express any partial recursive function.
0, S(n) = n+1 and selectors I_n^m(x_1, ..., x_n) = x_m and superposition obviously can be expressed using constexpr.
Primitive recursion can be done it straight way:
constexpr int h(int x1, ..., int xn, int y) {
return (xn == 0) ? f(x1, ..., xn) : g(x1, ..., xn, y-1, h(x1, ..., xn, y-1));
}
And for partial recursion we need a simple trick:
constexpr int h(int x1, ... int xn, int y = 0) {
return (f(x1, ... xn, y) == 0) ? y : h(x1, ..., xn, y+1);
}
So we get any partial recursion function as a constexpr.