In C++11 is std::sqrt
defined as constexpr
, i.e. can it legally be used from other constexpr
functions or in compile-time contexts like array sizes or template arguments? g++ seems to allow it (using -std=c++0x
), but I'm not sure I can take that as authoritative given that c++0x/c++11 support is still incomplete. The fact that I can't seem to find anything on the Internet makes me unsure.
It seems like this should be something one could easily find out using Google, but I've tried (for 40 minutes now...) and couldn't find anything. I could find several proposals for adding constexpr to various parts of the standard library (like for example this one), but nothing about sqrt
or other math functions.
If we look at the closest draft standard to C++11 N3337 we can see that
sqrt
is not marked constexpr, from section26.8
c.math:none of the changes include adding constexpr to
sqrt
.We can see from the question Is gcc considering builtins of non-constant expression functions to be constant expressions, that
gcc
marks many math functions as constexpr as an extension. This extension is a non-conforming extension, as I note in my answer to the linked question whengcc
implemented this it looked like it would be a conforming extension but this changed andgcc
is likely to fix this this extension to be conforming.Below is a constexpr square root implementation that uses binary search. It works correctly up to 2^64 with gcc and clang, other simpler versions often fail for numbers > 2^32 because compilers limit the recursion depth to e.g. 200.
Below is a nicer version (for integer constants) which requires C++14, it is similar to the one presented in Baptiste Wicht's blog post. C++14 constexpr functions are allowed to use local variables and if statements.
Just in case anyone is interested in a meta integer square root function, here is one I wrote while a ago:
std::sqrt
is not defined asconstexpr
, according to section 26.8 of N3291: the C++11 FDIS (and I doubt they added it to the final standard after that). One could possibly write such a version, but the standard library version is notconstexpr
.Here is a fast and efficient constexpr implementation for
double
floating point numbers. You may adapt it tofloat
too, if needed: