NeuroAgent

How to Fix FLOATING-POINT-INVALID-OPERATION Errors in CL-CFFI-GTK

Learn how to resolve FLOATING-POINT-INVALID-OPERATION errors in CL-CFFI-GTK with SBCL and ECL. Discover proper float trap handling and best practices for stable GTK applications in Common Lisp.

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:

lisp
(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-masked but 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:

  1. A proper way to handle or prevent these floating-point errors
  2. Guidance on understanding the interaction between GTK and the CFFI bridge
  3. 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?

NeuroAgent

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

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:

lisp
(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:

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.

lisp
(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:

lisp
;; 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:

lisp
(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:

lisp
(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:

lisp
(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:

lisp
(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:

lisp
;; 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:

lisp
(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:

  1. Use proper float trap masking with implementation-specific or portable solutions like float-features
  2. Configure floating-point modes during GTK initialization, especially for SBCL
  3. Implement robust error handling around all GTK operations
  4. Create wrapper macros to ensure consistent float trap handling across your application
  5. 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

  1. SBCL Bug #1519630 - Floating point traps are triggered by alien code
  2. cl-cffi-gtk Issue #28 - Division by zero error in GTK-MAIN
  3. cl-cffi-gtk gtk.package.lisp - Floating point configuration
  4. Float-Features Library Documentation
  5. Quickdocs cl-liballegro - Floating point error handling
  6. Quicklisp Issue #743 - Floating point errors with cl-cffi-gtk
  7. CLiki: cl-cffi-gtk - Library information
  8. GTK 3 Tutorial for Lisp - Installation and usage