[Boost-bugs] [Boost C++ Libraries] #4964: Annoying assert from runtime library when calling a function from boost::numeric::interval<double>

Subject: [Boost-bugs] [Boost C++ Libraries] #4964: Annoying assert from runtime library when calling a function from boost::numeric::interval<double>
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2010-12-08 12:26:27


#4964: Annoying assert from runtime library when calling a function from
boost::numeric::interval<double>
---------------------------------------------------------------+------------
 Reporter: Torsten Hauska <torsten.hauska@…> | Owner: bgubenko
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: interval
  Version: Boost 1.45.0 | Severity: Cosmetic
 Keywords: |
---------------------------------------------------------------+------------
 The following code sequence creates an assert in _control87():

 boost::numeric::interval<double> i(0.0, 0.0);
 boost::numeric::interval<double> i2 = 60.0 - i;

 The assert dialog states the following:

 ---------------------------
 Microsoft Visual C++ Debug Library
 ---------------------------
 Debug Assertion Failed!

 Program: ...
 File: amd64\ieee.c
 Line: 109

 Expression: (mask&~(_MCW_DN|_MCW_EM|_MCW_RC))==0

 For information on how your program can cause an assertion
 failure, see the Visual C++ documentation on asserts.

 (Press Retry to debug the application)
 ---------------------------
 Abbrechen Wiederholen Ignorieren
 ---------------------------

 This happens on Windows 7 64 Bit using Vc8, Vc9 or Vc10 and creating x64
 debug binaries. 32 bit builds are not affected.

 The problem seems to be that _control87 doesn't accept _MCW_PC or _MCW_IC
 as mask bits in 64 bit mode. Removing those bits from the mask let the
 assert vanish.

 I simply modified set_rounding_mode() in
 "boost\numeric\interval\detail\msvc_rounding_control.hpp":

   static void set_rounding_mode(const rounding_mode mode)
   {
      _control87(
         hard2msvc(mode),
   #if defined(_M_AMD64)
         _MCW_EM | _MCW_RC
   #else
         _MCW_EM | _MCW_RC | _MCW_PC | _MCW_IC
   #endif
         );
   }

 Microsoft says on MSDN (when you google for _control87):
 "On the x64 architecture, changing the floating point precision is not
 supported. If the precision control mask is used on that platform, an
 assertion and the invalid parameter handler is invoked, as described in
 Parameter Validation."

 The same seems to be true for _MCW_IC.

 You can verify the fact with a simply command line program like:

    #include <float.h>

    int _tmain(int argc, _TCHAR* argv[])
    {
       unsigned int cur = _control87(0, 0);
       _control87(_MCW_EM | _PC_64 | _RC_UP | _IC_AFFINE,
          _MCW_EM | _MCW_RC | _MCW_PC | _MCW_IC);
       _control87(cur, _MCW_EM | _MCW_RC | _MCW_PC | _MCW_IC);
       return 0;
    }

 You will get an assert in both calls to _control87 when you compile this
 in debug mode for the x64 platform.

 Kind regards,
 Torsten

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/4964>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:05 UTC