-
Notifications
You must be signed in to change notification settings - Fork 51
Description
Problem
rb-gsl fails to compile on Ruby 3.4 due to stricter function pointer type checking. Ruby 3.4 treats incompatible function pointer types as errors (via -Werror=incompatible-function-pointer-types), causing ~20+ compilation failures.
Root Causes
1. Incorrect argc values in rb_define_method/rb_define_module_function
Ruby's C API expects specific function signatures based on the argc parameter:
argc >= 0: Fixed args →VALUE func(VALUE self, VALUE arg1, ...)argc = -1: Variadic →VALUE func(int argc, VALUE *argv, VALUE self)
Many functions were registered with wrong argc values:
// BEFORE: argc=4 but function takes 3 VALUE args (self + 2)
rb_define_module_function(module, "ellint_D_e", rb_gsl_sf_ellint_D_e, 4);
// AFTER: argc=3 matches function signature
rb_define_module_function(module, "ellint_D_e", rb_gsl_sf_ellint_D_e, 3);2. Wrong parameter order for variadic functions
Functions registered with argc=-1 must have signature (int argc, VALUE *argv, VALUE self), but several had the parameters in wrong order:
// BEFORE: wrong order
static VALUE rb_gsl_sf_mathieu_a_array(VALUE module, int argc, VALUE *argv)
// AFTER: correct order for argc=-1
static VALUE rb_gsl_sf_mathieu_a_array(int argc, VALUE *argv, VALUE module)3. Double pointer typos
// BEFORE: VALUE *argv[] is double pointer
static VALUE rb_gsl_vector_complex_indgen_bang(int argc, VALUE *argv[], VALUE obj)
// AFTER: VALUE *argv is single pointer
static VALUE rb_gsl_vector_complex_indgen_bang(int argc, VALUE *argv, VALUE obj)4. Unused parameters in function signatures
// BEFORE: unused VALUE s parameter
static VALUE rb_gsl_rng_max(VALUE obj, VALUE s)
// AFTER: removed unused parameter
static VALUE rb_gsl_rng_max(VALUE obj)5. rb_rescue callback signature change
Ruby 3.4 requires rescue callbacks to accept 2 arguments:
// BEFORE: 1 argument
static VALUE rb_gsl_call_rescue(VALUE obj)
// AFTER: 2 arguments (data, exception)
static VALUE rb_gsl_call_rescue(VALUE obj, VALUE exc)
{
(void)exc;
return Qfalse;
}6. GSL 2.8 API changes
// BEFORE: accessing struct internals (no longer available)
B = gsl_vector_alloc(w->nbreak + w->k - 2);
// AFTER: use public API
B = gsl_vector_alloc(gsl_bspline_ncontrol(w));Also, gsl_matrix_complex_conjugate is now provided by GSL 2.8+, so the local definition causes a duplicate symbol error.
7. CLASS_OF() with wrong type
// BEFORE: passing C struct pointer
return Data_Wrap_Struct(CLASS_OF(h1), ...);
// AFTER: passing Ruby VALUE
return Data_Wrap_Struct(CLASS_OF(obj), ...);8. RARRAY_LEN with void pointer
// BEFORE: void* params
for (i = 0; (int) i < RARRAY_LEN(f->params); i++)
// AFTER: explicit VALUE cast
for (i = 0; (int) i < RARRAY_LEN((VALUE) f->params); i++)Files Requiring Changes
blas2.c- argc fixes for dsyr2/zher2bspline.c- GSL 2.8 API (gsl_bspline_ncontrol)gsl.c- rb_rescue callback signaturehistogram2d.c- CLASS_OF fixes, fscanf argcieee.c- printf argclinalg.c- removed unused flag params, argc fixesmatrix_complex.c- removed duplicate gsl_matrix_complex_conjugate, fixed indgen_bang signaturemonte.c- eval argcmultiroots.c- RARRAY_LEN VALUE castntuple.c- close/size argcodeiv.c- scaled_alloc argcpoly_source.h- reduce/deriv/integ argcrng.c- removed unused parameters from max/min/sizesf_bessel.c- sequence_Jnu_e argcsf_ellint.c- ellint_D_e argcsf_mathieu.c- array function parameter orderspline.c- eval_integ_e argcstats.c- weighted stats function argc valuesvector_complex.c- indgen_bang signature, matrix_view_with_tda argc
Testing
Verified fixes compile and pass full test suite with:
- Ruby 3.4.8
- GSL 2.8
- macOS (arm64-darwin)
755 tests, 1,514,054 assertions, 0 failures, 0 errors
Related: TypedData Migration (Separate Issue)
There are deprecation warnings about Data_Get_Struct / Data_Wrap_Struct:
warning: undefining the allocator of T_DATA class GSL::Vector
This requires migrating to TypedData_Wrap_Struct (~3,300 occurrences) and will be tracked as a separate issue. Users can suppress warnings with:
Warning[:deprecated] = false
require 'gsl'
Warning[:deprecated] = true