Boost logo

Boost Users :

Subject: Re: [Boost-users] [Multiprecision] Runtime assertion failure with clang++3.6.0 but not g++4.9.2
From: John Maddock (jz.maddock_at_[hidden])
Date: 2016-02-09 05:12:15


> 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?

Correct - this is primarily a limitation of GMP which dynamically
allocates memory for each number.

Type cpp_int when used at fixed precision (ie
boost::multiprecision::int128_t etc) has support for constexpr
initialization, but only from literals, there's still no constexpr
arithmetic (that would be really hard!).

HTH, John.

> 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
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net