
Hello again and thanks for your replies! Taking the following two statements into account:
For type int, the values are computed recursively at compile time, for a user-defined-type the values are computed at runtime and you hit initialization-order issues.
Seems to be that Multiprecision relies on static data that haven't (necessarily) been initialized before your own static members. Works fine if the members are made non-static:
Does that mean that, since a) boost::multiprecision::number<gmp_int> is not constexpr enabled, and b) static initialization can't happen at compile-time for user-defined types, that there is no way for me to initialize a variable of this type at compile-time? Does b) follow logically from a) ? I (believe to have) confirmed runtime-initialization by running valgrind, which showed the presence of dynamic memory allocations (and also jumps depending on uninitialized variables, which probably corresponds to the assertion failure). I am mentioning this because initially my little test program looked somewhat like this: #include <iostream> #include <vector> #include <boost/multiprecision/gmp.hpp> namespace bm = boost::multiprecision; template<std::size_t N> struct factorial { static const bm::mpz_int value; static void add_values(std::vector<bm::mpz_int>& vec) { factorial<N-1>::add_values(vec); vec.push_back(value); } }; template<std::size_t N> const bm::mpz_int factorial<N>::value = N * factorial<N-1>::value; template<> struct factorial<std::size_t{0}> { static const bm::mpz_int value; static void add_values(std::vector<bm::mpz_int>& vec) { vec.push_back(value); } }; const bm::mpz_int factorial<0>::value = 1; int main () { std::vector<bm::mpz_int> fac_table{}; factorial<10'000>::add_values(fac_table); std::cout << "Enter a number between 0 and 10'000 to calculate factorial:"; std::size_t number; std::cin >> number; std::cout << '\n' << number << "! == " << fac_table[number] << '\n'; return 0; } This still includes the "unsafe" static initialization of a user-defined type. However it compiles and runs via g++ -ansi -std=c++14 -O3 -Wall -Wextra -pedantic -static -save-temps -ftemplate-depth-50000 -DNDEBUG -o main main.cpp -lgmp -pthread This was what made me believe in the compile-time computation of the factorials in the first place, since using this version, valgrind does not show any dynamic memory allocation at all. On the other hand, I don't understand what's going on here really, especially since std::vector<> is supposed to allocate memory at run-time. Now I'm not sure whether the last example has anything to do with Boost.Multiprecision anymore, so while it would really make my day if you could help me better understand this, I will understand if this is not the right place to ask these questions. Thanks again for your replies so far, they have been of great help! Cheers, Max