So noticed from this page that none of the math functions in c++11 seems to make use of constexpr, whereas I believe all of them could be. So that leaves me with two questions, one is why did they choose not to make the functions constexpr. And two for a function like sqrt I could probably write my own constexpr, but something like sin or cos would be trickier so is there a way around it.
3 Answers
Actually, because of old and annoying legacy, almost none of the math functions can be constexpr, since they all have the side-effect of setting errno on various error conditions, usually domain errors.
7 Comments
errno is really not a good reason.errno are two very different beasts. The C standard math functions are specified to modify errno, not throw an exception. So I don't understand your point.errno situation to you?From "The C++ Programming Language (4th Edition)", by B. Stroustrup, describing C++11:
"To be evaluated at compile time, a function must be suitably simple: a constexpr function must consist of a single return-statement; no loops, and no local variables are allowed. Also, a constexpr function may not have side effects."
Which means that it must be inline, without for, while and if statements and local variables. Side effects are also forbidden (ex: changing of errno). Another problem is that most of math functions are FPU instructions which are not represented in pure c/c++ (they are written in assembler code). That's why non of cmath function is declared as constexpr.
6 Comments
awsome::sqrt(3e13) . Have you tried to implement sin, cos, tanh, or similar functions? I know that there are algorithms for such functions, but do you think that constexpr_sin(x) == sin(x)?So noticed from this page that none of the math functions in c++11 seems to make use of constexpr, whereas I believe all of them could be. So that leaves me with two questions, one is why did they choose not to make the functions constexpr.
This part is very well answered by Sebastian Redl and Adam Szaj so won't be adding anything to it.
And two for a function like sqrt I could probably write my own constexpr, but something like sin or cos would be trickier so is there away around it.
Yes, you can write your own version of constexpr sin, cos by using the taylor series expansions of these functions. Have a look at this super cool github repo which implements several mathematical functions as constexpr functions Morwenn/static_math
6 Comments
smath::cos(20.). Cosine greater than 3... It's hard enough to implement a decent non-constexpr trig function, let alone constexpr one.<stdexcept>, thus not compiling without tweaks; 2) seems to do only trivial range reduction, so that e.g. compile_time::cos(200.) differs considerably from std::cos(200.) on x86_64 gcc, while for argument of 2. the results are more or less the same. Even worse for long double. But yes, it does appear to at least attempt to do range reduction, unlike static_math.2**17 ULP, which is no good for IEEE754 64-bit double.
constexpris that the compiler then has to do what would otherwise be a runtime computation, and that means having a C++ interpreter built in to the compiler. It's a big job...constexprfunctions in pure C++. At least given the restrictions onconstexprfunctions in C++11. On the other hand, the math functions are a very well-known finite set of functions that a compiler could easily provide as builtins and evaluate at compile-time. This mixing of core language features and library functions might be considered ugly, but also worth the thing. Also see Alisdair Meredith's talk on CppCon 2014.