Boost logo

Boost :

Subject: [boost] constexpr, cmath functions and other functions and distributions
From: Paul A. Bristow (pbristow_at_[hidden])
Date: 2016-07-28 09:24:19

After much head scratching (and some head banging) - against a string of "Computer Says No" inscrutable diagnostic messages.

I believe that I have now produced a (partial) version of Boost.Math normal_distribution that can be a constexpr using GCC6.1.1.

(diagnosis has got to improve if constexprizing existing code is to become popular? )


constexpr normal_distribution<double> n01(0., 1.);


producing this code


960 .loc 1 47 0

961 000d 660FEFC0 pxor %xmm0, %xmm0 # tmp89

962 0011 F20F1145 movsd %xmm0, -32(%rbp) # tmp89, n01.m_mean

962 E0

963 0016 F20F1005 movsd .LC1(%rip), %xmm0 #, tmp90

963 80080000

 964 001e F20F1145 movsd %xmm0, -24(%rbp) # tmp90, n01.m_sd

964 E8


and more interestingly, a PDF can be calculated at compile-time


  constexpr double p = pdf(n01, 0.5);


965 .loc 1 56 0

966 0023 F20F1005 movsd .LC2(%rip), %xmm0 #, tmp91

966 88080000

 967 002b F20F1145 movsd %xmm0, -8(%rbp) # tmp91, p

967 F8


Perhaps the assembler whizzes can confirm that this looks like a compile-time computation?


This relies on lots of C++14 and 17 constexpr features, and


Most crucially it relies on being able to use several cmath functions as constexpr.


For a couple of trivially simple examples: abs(x) and isfinite(x).


  constexpr double ax42 = abs(-42.); // Unspecified version of abs.

  constexpr double ax42g = ::abs(-42.); // C double version?

  constexpr double ax42b = __builtin_abs(-42.); // builtin GCC only

  constexpr double ax42s = std::abs(-42.); // std:: version


Without most cmath functions it seems to me impossible to write any reasonable (so-called special or not) mathy function or

distribution that can be constexpr.

At present, only GCC 6.1.1 authors have foreseen this need and provided these so-called built_in_* cmath function versions that are
constexpr, see


(Aside on other compilers:


· Clang 3.8 has some problem deep inside type_traits that I haven't yet investigated.


· VS2015 update 3 still doesn't compile many essential C++17 features from my experiments so far, and doesn't provide any
constexpr cmath functions.



The many potential benefits of compiler-time computations are quite enticing to contemplate :-)


* No run-time where possible

* Errors caught at compile-time

* Improved code readability

* Reduce executable footprint


and potentially most important


* Avoid global initialization order issues

* Avoid initialization thread races




· Scott Schurr, C++ Developer, Ripple Labs


· Dietmar Khul Constant Fun
<> &v=T37ElKPICvo&app=desktop


Is there any support for making std::abs and friends constexpr where possible in future versions of the C++ Standard?




PS I can't conceive of any UDT using or providing floating-point without some function like frexp to get and set exponent and



I also note that making constexpr frexp and ldexp and other functions passing a pointer to a variable to be updated may be more


and is very likely to require at least initialization of the to-be-updated variable before calling frexp.


I've investigated overcoming this by writing a naïve new constexpr version of frexp returning a std::pair (significand and exponent)
but, of course, it can never be a 'drop-in' replacement because it has a different signature, so lots of code changes are


Paul A. Bristow
Prizet Farmhouse
Kendal UK LA8 8AB
+44 (0) 1539 561830

Boost list run by bdawes at, gregod at, cpdaniel at, john at