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:

#include <iostream>
#include <boost/multiprecision/gmp.hpp>

namespace bm = boost::multiprecision;

template <std::size_t N>
struct factorial2
{
    const bm::mpz_int value = N * factorial2<N-1>().value;
};

template<>
struct factorial2<0>
{
    const bm::mpz_int value = 1;
};

int main()
{
    std::cout << factorial2<3>().value << '\n';
    return 0;
}


On Mon, Feb 8, 2016 at 10:58 AM, <mbw_bst@mailbox.org> wrote:
Dear all,

this is my first post on this mailing list, so hopefully this will all be
by the book.
Executing the following minimal working example, which is supposed to
calculate "3! == 6" via
(1) a template function
(2) a class template

and save the result in a boost::multiprecision::mpz_int, results in
unexpected behavior for clang++3.6.0,
with the version of my boost library being 1.59.0.

The program displays the correct result using g++4.9.2 however:


#include <iostream>
#include <boost/multiprecision/gmp.hpp>

namespace bm = boost::multiprecision;

template <std::size_t N>
bm::mpz_int factorial()
{
    return N * factorial<N-1>();
}

template<>
bm::mpz_int factorial<0>()
{
    return 1;
}

template <std::size_t N>
struct factorial2
{
    static const bm::mpz_int value;
};
template<std::size_t N>
const bm::mpz_int factorial2<N>::value = N * factorial2<N-1>::value;

template<>
struct factorial2<0>
{
    static const bm::mpz_int value;
};
const bm::mpz_int factorial2<0>::value = 1;

    int
main ()
{
    std::cout << factorial<3>() << '\n';
    std::cout << factorial2<3>::value << '\n';
    return 0;
}

The output for clang, having been compiled via

clang++ -std=c++14 -stdlib=libc++ -DNDEBUG -o main main.cpp -lgmp

will result in:

6
0

However, omitting the NDEBUG flag will trigger an assertion failure:

main: /usr/include/boost/multiprecision/gmp.hpp:1296: const mpz_t
&boost::multiprecision::backends::gmp_int::data() const: Assertion
`m_data[0]._mp_d' failed.
Aborted (core dumped)

Compiling the same program with g++4.9.2 (with or without "-DNDEBUG")
yields the expected result:

6
6

What did I miss? Can this behavior indeed be traced down to
Boost.Multiprecision, or does it have to do with the initialization order
of static const class members? Or something else?
Additionally, both variants work correctly with clang when using a
built-in type like 'int'.

Any help in understanding the problem on hand would be greatly
appreciated!


Best Regards,

mbw
_______________________________________________
Boost-users mailing list
Boost-users@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users