Opened 12 years ago

Closed 8 years ago

#4964 closed Bugs (fixed)

Annoying assert from runtime library when calling a function from boost::numeric::interval<double>

Reported by: Torsten Hauska <torsten.hauska@…> Owned by: Boris Gubenko
Milestone: Boost 1.58.0 Component: interval
Version: Boost 1.57.0 Severity: Problem
Keywords: Cc: prabhu.swain@…

Description

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

Change History (6)

comment:1 by prabhu.swain@…, 12 years ago

Cc: prabhu.swain@… added

comment:2 by anonymous, 12 years ago

Thanks for your post, you saved my day...

comment:3 by fkonvick, 10 years ago

Is this getting any attention? I can reproduce the same here with MSVC 2012.

comment:4 by filip.konvicka@…, 10 years ago

Is there any chance of integrating the fix provided above by Torsten to 1.52? I would definitely say the severity is not Cosmetic.

I can generate the patchfile if needed. Otherwise I will need to keep applying the patch to all boost releases....

comment:5 by fkonvick, 8 years ago

I have issued a pull-request on this.

comment:6 by fkonvick, 8 years ago

Milestone: To Be DeterminedBoost 1.58.0
Resolution: fixed
Severity: CosmeticProblem
Status: newclosed
Version: Boost 1.45.0Boost 1.57.0

This is now fixed on master, commits 362724ba91c1ff36b94af425e889cd6cfb0bca78 and e172bd645b4263fbee20a85d4aedd2da44c4967c. Should be available in Boost 1.58.

Note: See TracTickets for help on using tickets.