Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange boost cpp_Int behaviour when using auto type deduction

Tags:

c++

c++11

boost

I just noticed some really strange behaviour when using auto to store the result of a boost cpp_int operation

#include <boost/multiprecision/cpp_int.hpp>

int main() {
    using boost::multiprecision::cpp_int;
    cpp_int a = 1, b = 10 * a, d;
    auto c = 10 * a;
    d = c;
    std::cout << b << " " << c << " " << d << "\n";
}

which outputs:

10 0 0 

instead of:

10 10 10

can anybody explain this?

like image 433
hastri Avatar asked Dec 02 '25 10:12

hastri


1 Answers

The problem is that boost::multiprecision uses expression templates in an attempt to avoid computing intermediate results (the linked Boost page has a section explaining the reasons for doing so).

Because of that, the type of c in the following expression is not cpp_int

auto c = 10 * a;  // c is some internal implementation defined type

You can confirm this by comparing the types of say a and c.

#include <boost/type_index.hpp>
std::cout << boost::typeindex::type_id_with_cvr<decltype(c)>().pretty_name();

The Boost introduction even specifically mentions the pitfall of using auto to store an expression template

One other potential pitfall that's only possible in C++11: you should never store an expression template using:

 auto my_expression = a + b - c;

unless you're absolutely sure that the lifetimes of a, b and c will outlive that of my_expression.

In your case, one of the operands is a literal, which seems to affect the result of converting the expression template to cpp_int even though the lifetime of c matches that of a. What happens exactly is difficult to say without delving deeper into the implementation of operator*, but suffice to say that you're doing something you shouldn't be, and most likely your example has undefined behavior.

You can fix the problem in several ways, beginning with use cpp_int instead of auto. Or cast the result of the expression template to cpp_int.

auto c = cpp_int(10 * a);

Or store the 10 in a cpp_int; then the caveat mentioned in the Boost documentation applies, and your example produces the expected result.

cpp_int a = 1, b = 10 * a, d, e = 10;
auto c = e * a;
like image 75
Praetorian Avatar answered Dec 04 '25 23:12

Praetorian



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!