How to Avoid FLOATING-POINT-INVALID-OPERATION Errors in CL-CFFI-GTK?
I’m experiencing FLOATING-POINT-INVALID-OPERATION errors when using CL-CFFI-GTK with Common Lisp. The error occurs when executing basic GTK operations like:
(gtk-widget-show-all (make-instance 'gtk-window
:type :toplevel
:title "hello"))
This results in:
; Evaluation aborted on #<FLOATING-POINT-INVALID-OPERATION {10021F69B3}>.
I’ve tried:
- Using different Lisp implementations (SBCL and ECL)
- Testing in various environments (standalone REPL, SLIME+Emacs)
- Exploring both CL-CFFI-GTK and CL-GTK4
- Attempting to use
sb-int:with-float-traps-maskedbut encountering errors like “unknown float trap kind: GTK:GTK-WIDGET-SHOW-ALL”
My system details:
- Debian 13 Trixie
- SBCL 2.5.2.debian
- ECL 24.5.10
The issue appears to be related to the CFFI bridge between Common Lisp and GTK’s underlying C functions. I’m looking for:
- A proper way to handle or prevent these floating-point errors
- Guidance on understanding the interaction between GTK and the CFFI bridge
- Best practices for avoiding such issues when working with CL-CFFI-GTK
How can I resolve these FLOATING-POINT-INVALID-OPERATION errors and ensure stable operation of GTK applications in Common Lisp?
The FLOATING-POINT-INVALID-OPERATION errors you’re encountering with CL-CFFI-GTK stem from Common Lisp implementations trapping floating-point exceptions during foreign function calls to GTK’s C code. This occurs because SBCL and other Lisp implementations have stricter floating-point error handling than C code, causing conflicts when calling GTK functions through the CFFI bridge.
Contents
- Understanding the Root Cause
- SBCL-Specific Solutions
- Portable Float Trap Handling
- ECL and Other Implementation Solutions
- Best Practices for Stable GTK Applications
- Debugging and Troubleshooting
Understanding the Root Cause
The fundamental issue lies in the different floating-point error handling strategies between Common Lisp and C. When you call GTK functions through CFFI, the underlying C code may perform operations that trigger floating-point exceptions that SBCL considers errors but C code typically ignores.
As SBCL bug #1519630 explains: “When making foreign function calls (with sb-alien or a wrapper such as cffi), sbcl will trap floating point errors that happen in the C code, and by default sbcl traps on errors that aren’t typically on in c code.”
This manifests as FLOATING-POINT-INVALID-OPERATION errors when seemingly innocent GTK operations like gtk-widget-show-all are executed, even though the same operations work fine in native C applications.
SBCL-Specific Solutions
Using sb-int:with-float-traps-masked
SBCL provides the sb-int:with-float-traps-masked macro to temporarily disable specific floating-point traps during foreign function calls. Based on the research findings, here’s the recommended approach:
(sb-int:with-float-traps-masked (:invalid :inexact :overflow :underflow :divide-by-zero)
(gtk-widget-show-all (make-instance 'gtk-window
:type :toplevel
:title "hello")))
This approach was mentioned in issue #28 as a potential workaround for similar problems.
Global Float Trap Configuration
For more comprehensive solutions, you can configure SBCL’s floating-point modes globally. As shown in the cl-cffi-gtk gtk.package.lisp:
#+sbcl
(when (and (find-package "SB-EXT")
(find-symbol "SET-FLOATING-POINT-MODES" (find-package "SB-EXT")))
(funcall (find-symbol "SET-FLOATING-POINT-MODES" "SB-EXT")
:traps '()))
This disables all floating-point traps globally, which may be necessary for full GTK compatibility.
Portable Float Trap Handling
For a more portable solution across different Common Lisp implementations, consider using the float-features library. This library provides a unified interface for handling floating-point traps across various implementations.
(float-features:with-float-traps-masked (:invalid :inexact :overflow :underflow :divide-by-zero)
;; Your GTK code here
(gtk-widget-show-all (make-instance 'gtk-window
:type :toplevel
:title "hello")))
The float-features documentation shows support for:
- ABCL (:overflow :underflow)
- CCL (:overflow :underflow :inexact :invalid :divide-by-zero)
- CLISP (:underflow)
- CMUCL T
- ECL (:underflow :overflow :inexact :invalid :divide-by-zero)
- MEZZANO T
- SBCL T
ECL and Other Implementation Solutions
ECL-Specific Handling
From the research, ECL 16.1.3 was also mentioned as having similar issues. ECL supports float trap masking but with different syntax:
;; ECL-specific floating-point trap handling
(ext:with-float-traps-masked (:invalid :inexact :overflow :underflow :divide-by-zero)
;; Your GTK code here
)
Clozure CL (CCL) Support
CCL also provides float trap handling capabilities:
(ccl:with-float-traps-masked (:invalid :inexact :overflow :underflow :divide-by-zero)
;; Your GTK code here
)
Best Practices for Stable GTK Applications
1. Wrap All GTK Operations
Create a wrapper macro that automatically handles float traps for all GTK operations:
(defmacro with-safe-gtk (&body body)
"Execute BODY with floating-point traps masked for safe GTK operations."
(float-features:with-float-traps-masked
(:invalid :inexact :overflow :underflow :divide-by-zero)
(progn ,@body)))
2. Initialize GTK with Proper Float Configuration
Configure floating-point modes during GTK initialization as shown in the cl-cffi-gtk package:
(glib:at-init ()
(eval-when (:compile-toplevel :load-toplevel :execute)
;; Configure floating-point modes for GTK compatibility
#+sbcl
(when (and (find-package "SB-EXT")
(find-symbol "SET-FLOATING-POINT-MODES" (find-package "SB-EXT")))
(funcall (find-symbol "SET-FLOATING-POINT-MODES" "SB-EXT")
:traps '()))
;; Add other implementation-specific configurations here
))
3. Error Handling Strategies
Implement robust error handling around GTK operations:
(defun safe-gtk-widget-show-all (widget)
"Show WIDGET with proper error handling for floating-point exceptions."
(handler-bind
((floating-point-invalid-operation
(lambda (c)
(warn "Floating-point error in GTK operation: ~a" c)
(continue c))))
(gtk-widget-show-all widget)))
Debugging and Troubleshooting
Identifying Problematic GTK Functions
When encountering floating-point errors, identify which specific GTK operations trigger them:
;; Debug wrapper to identify problematic operations
(defun debug-gtk-operation (operation &rest args)
"Wrap GTK OPERATION with debugging to identify floating-point issues."
(handler-bind
((floating-point-invalid-operation
(lambda (c)
(format t "Floating-point error in ~a with args: ~a~%" operation args)
(continue c))))
(apply operation args)))
Logging and Monitoring
Add logging to track when floating-point errors occur:
(setf *debug-io* *standard-output*)
(setf *error-output* *standard-output*)
(defparameter *gtk-debug* nil)
(defun log-gtk-error (condition)
"Log GTK-related errors for debugging."
(when *gtk-debug*
(format t "GTK Error: ~a~%" condition))
(continue condition))
;; Use error handler globally
(handler-case
(your-gtk-code)
(floating-point-invalid-operation (c)
(log-gtk-error c)))
Testing Different GTK Versions
The research suggests that different GTK versions may have varying floating-point behavior. Consider testing with different GTK versions to identify compatibility issues.
Conclusion
To resolve FLOATING-POINT-INVALID-OPERATION errors in CL-CFFI-GTK:
- Use proper float trap masking with implementation-specific or portable solutions like
float-features - Configure floating-point modes during GTK initialization, especially for SBCL
- Implement robust error handling around all GTK operations
- Create wrapper macros to ensure consistent float trap handling across your application
- Consider alternative implementations if issues persist with your current setup
The key insight is that this is a known issue in the Common Lisp ↔ GTK C interface, and proper floating-point trap configuration is essential for stable operation. Most users find success with either global float trap configuration or per-operation masking with with-float-traps-masked.
For ongoing development, monitor the cl-cffi-gtk GitHub repository for updates to floating-point handling, as this is an active area of improvement for the library.
Sources
- SBCL Bug #1519630 - Floating point traps are triggered by alien code
- cl-cffi-gtk Issue #28 - Division by zero error in GTK-MAIN
- cl-cffi-gtk gtk.package.lisp - Floating point configuration
- Float-Features Library Documentation
- Quickdocs cl-liballegro - Floating point error handling
- Quicklisp Issue #743 - Floating point errors with cl-cffi-gtk
- CLiki: cl-cffi-gtk - Library information
- GTK 3 Tutorial for Lisp - Installation and usage