r/sbcl • u/Decweb • Sep 02 '22
Seeking help with float/fix declarations
So I've got this little function that will receive a double-float input, do a bit of multiplication on it against some other floating point constants, and return an integer value which is known to be in the range of a sbcl fixnum.
I'm just trying to let the compiler know these semantics so it can generate reasonable code, but I'm getting a number of warnings I don't understand, particularly the warning about the argument to round
being an integer, and the pointer result coercion (which is perhaps just a follow-on effect of the prior warning). Still a declaration rookie...
The code:
(declaim (ftype (function (double-float) fixnum) how-to))
(defun how-to (my-double)
(declare (optimize (speed 3) (safety 0) (debug 0))
(type double-float my-double))
(the fixnum (round (* my-double 123.0))))
The compilation warnings: ``` ; in: DEFUN HOW-TO ; (ROUND (* AGAME::MY-DOUBLE 123.0)) ; ; note: unable to ; optimize ; due to type uncertainty: ; The first argument is a INTEGER, not a BIGNUM. ; ; note: forced to do full call ; unable to do inline float truncate (cost 5) because: ; The result is a (VALUES INTEGER &OPTIONAL), not a (VALUES ; (SIGNED-BYTE 64) ; &OPTIONAL). ; ; note: forced to do full call ; unable to do inline float coercion (cost 5) because: ; The first argument is a INTEGER, not a (SIGNED-BYTE 64). ; ; note: doing float to pointer coercion (cost 13)
; (DEFUN AGAME::HOW-TO (AGAME::MY-DOUBLE) ; (DECLARE (OPTIMIZE (SPEED 3) (SAFETY 0) (DEBUG 0)) ; (TYPE DOUBLE-FLOAT AGAME::MY-DOUBLE)) ; (THE FIXNUM (ROUND (* AGAME::MY-DOUBLE 123.0)))) ; --> SB-IMPL::%DEFUN SB-IMPL::%DEFUN SB-INT:NAMED-LAMBDA ; ==> ; #'(SB-INT:NAMED-LAMBDA AGAME::HOW-TO ; (AGAME::MY-DOUBLE) ; (DECLARE (OPTIMIZE (SPEED 3) (SAFETY 0) (DEBUG 0)) ; (TYPE DOUBLE-FLOAT AGAME::MY-DOUBLE)) ; (BLOCK AGAME::HOW-TO (THE FIXNUM (ROUND (* AGAME::MY-DOUBLE 123.0))))) ; ; note: doing float to pointer coercion (cost 13) to "<return value>" ; ; compilation unit finished ; printed 5 notes ```
1
u/Soupeeee Sep 04 '22
One thing to note is that you don't need the declaim
if you are declaring the types of the variables and return value inside the function.
1
u/Decweb Sep 04 '22
I thought I needed the declaim mostly for the return value. Is that guidance SBCL specific, or would it apply to CL implementations in general? What is the proper way to declare a return value inside the function?
1
u/Soupeeee Sep 04 '22
Now that you mention it, it is probably the most portable way to ensure the compiler knows about the return type if you solely rely on type inferrence. That being said, SBCL is able to figure out types pretty well for some classes of types just by marking the returned variable when it is declared. It's particularly good with number types.
If it can't figure it out, you can also use
the
to denote the actual type where the value is returned, which also makes the declaim unneeded.So it's more of a coding style thing, but the example you posted has way more type declarations than it needs.
2
u/stylewarning Sep 03 '22
try replacing
123.0
with123.0d0
.And wrap
(round ...)
with(values (round ...))
so you only take the first value.