Reputation: 81
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?
Upvotes: 3
Views: 105
Reputation: 109219
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
andc
will outlive that ofmy_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;
Upvotes: 1