On Fri, 26 Feb 2010 17:18:04 +0200, Nikodemus Siivola wrote:
> On 26 January 2010 19:20, Tamas K Papp <tkpapp@...> wrote:
>> In my code, I was relying on (log 0) signalling an error. It worked
>> fine. After a bit of development (basically a few hours), I noticed my
>> code misbehaving, and found that the cause is:
>>
>> CL-USER> (sb-int:get-floating-point-modes) (:TRAPS NIL :ROUNDING-MODE
>> :NEAREST :CURRENT-EXCEPTIONS (:INEXACT)
>> :ACCRUED-EXCEPTIONS (:INEXACT) :FAST-MODE NIL :PRECISION :53-BIT)
>>
>> I never explicitly unset the traps. Is there anything else in SBCL
>> that could unset them without my knowledge?
>
> One of the reason setting traps isn't supported is just this. :/ SBCL
> should not be unsetting them behind your back, but calls to libc may do
> so -- and SBCL doesn't notice if that happens.
What do you mean by calls to libc? I am not calling any libc functions
directly, does SBCL call anything indirectly? I am calling LAPACK
routines.
Would wrapping my code in the macro below be an acceptable way to find
when they are changed? Or could it be something outside my function
calls, called by SBCL itself?
(defun get-traps ()
(getf (sb-int:get-floating-point-modes) :traps))
(defmacro with-traps-checked (&body body)
"Check if floating point traps were changed during body."
(let ((traps-before (gensym "traps"))
(traps-after (gensym "traps")))
`(let ((,traps-before (get-traps)))
(multiple-value-prog1
(progn
,@body)
(let ((,traps-after (get-traps)))
(unless (equal ,traps-before ,traps-after)
(error "Floating point traps were changed from ~A to ~A."
,traps-before ,traps-after)))))))
Thanks,
Tamas
|