1

I've spent the better part of the day tracking a problem down to this example:

#include <boost/multiprecision/cpp_dec_float.hpp>

#include <iostream>

int main () 
{
  
  typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<50>> float_t;
  //typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<50>, boost::multiprecision::expression_template_option::et_off> float_t; // <--- this works ok, too!

  float_t dependency = 2.0;

  auto const val = dependency / 2;
  //float_t const val = dependency / 2; // <--- this works ok!


  std::cout << val << std::endl;
  dependency = val - 2;
  std::cout << val << std::endl;
  dependency = val - 2;
  std::cout << val << std::endl;
  dependency = val - 2;

  return 0;
}

outputs

1
-0.5
-1.25

It seems as though the dependency of val on dependency breaks the const promise.

  1. Changing the auto const to float_t const fixes the problem.

  2. Using cpp_bin_float fixes the problem

  3. On random suspicion, disabling expression templates fixes the problem

This occurs on multiple VS versions, mingw8.1, and Coliru.

Could anyone more familiar with the internal workings explain what is going on?

namezero
  • 2,203
  • 3
  • 24
  • 37
  • 1
    The `auto` uses the type of the expression. The expression is an `boost::multiprecision::detail::expression, (boost::multiprecision::expression_template_option)1>, int, void, void>`, which is not what you want here. It does convert to a `float_t`, which is why `float_t` works. – Eljay Dec 10 '20 at 18:40
  • @Eljay Thank you for the clarification. You are right about the type. This makes the expression turn into `dependency = dependency/2- 2` every time. This is very surprising behavior. Sometimes boost static asserts on this (that's where the ET's became suspicious), but not in this case. I've adjusted the title to reflect this. – namezero Dec 10 '20 at 18:50

0 Answers0