Bug #20908
closedRuby extension builds fail with GCC 15 which defaults to -std=gnu23
Description
Hi!
Upcoming GCC 15 defaults to C23 (-std=gnu23
). One thing C23 changes is removing unprototyped functions, so void foo()
now means void foo(void)
, rather than "any arguments".
Ruby extensions fail to build as a result with GCC 15. This was reported downstream in Gentoo at https://bugs.gentoo.org/943784 where brotli-0.6.0 is an example:
make: Entering directory '/var/tmp/portage/dev-ruby/brotli-0.6.0/work/ruby32/brotli-0.6.0/ext/brotli'
x86_64-pc-linux-gnu-gcc -I. -I/usr/include/ruby-3.2.0/x86_64-linux -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -DHAVE_BROTLI_DECODE_H -DHAVE_BROTLI_ENCODE_H -fPIC -O2 -pipe -march=native -fno-diagnostics-color -o brotli.o -c brotli.c
In file included from /usr/include/ruby-3.2.0/ruby/ruby.h:27,
from /usr/include/ruby-3.2.0/ruby.h:38,
from brotli.h:4,
from brotli.c:1:
brotli.c: In function ‘Init_brotli’:
/usr/include/ruby-3.2.0/ruby/internal/anyargs.h:363:45: error: passing argument 3 of ‘rb_define_singleton_method_m1’ from incompatible pointer type [-Wincompatible-pointer-types]
363 | # define RUBY_METHOD_FUNC(func) RBIMPL_CAST((VALUE (*)(ANYARGS))(func))
| ^
| |
| VALUE (*)(void) {aka long unsigned int (*)(void)}
/usr/include/ruby-3.2.0/ruby/internal/anyargs.h:308:144: note: in definition of macro ‘rb_define_singleton_method’
308 | #define rb_define_singleton_method(obj, mid, func, arity) RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method((arity), (func))((obj), (mid), (func), (arity))
| ^~~~
/usr/include/ruby-3.2.0/ruby/internal/anyargs.h:363:33: note: in expansion of macro ‘RBIMPL_CAST’
363 | # define RUBY_METHOD_FUNC(func) RBIMPL_CAST((VALUE (*)(ANYARGS))(func))
| ^~~~~~~~~~~
brotli.c:478:55: note: in expansion of macro ‘RUBY_METHOD_FUNC’
478 | rb_define_singleton_method(rb_mBrotli, "deflate", RUBY_METHOD_FUNC(brotli_deflate), -1);
| ^~~~~~~~~~~~~~~~
/usr/include/ruby-3.2.0/ruby/internal/anyargs.h:271:21: note: expected ‘VALUE (*)(int, union <anonymous>, VALUE)’ {aka ‘long unsigned int (*)(int, union <anonymous>, long unsigned int)’} but argument is of type ‘VALUE (*)(void)’ {aka ‘long unsigned int (*)(void)’}
271 | RBIMPL_ANYARGS_DECL(rb_define_singleton_method, VALUE, const char *)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/ruby-3.2.0/ruby/internal/anyargs.h:254:41: note: in definition of macro ‘RBIMPL_ANYARGS_DECL’
254 | RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _m1(__VA_ARGS__, VALUE(*)(int, union { VALUE *x; const VALUE *y; } __attribute__((__transparent_union__)), VALUE), int); \
| ^~~
The ANYARGS
macro can't work in its current form, as defined at e.g. https://github.com/ruby/ruby/blob/f127bcb8294fd417c253dd7acab3ff3b9f0bf555/parser_st.h#L45:
#ifndef ANYARGS
# ifdef __cplusplus
# define ANYARGS ...
# else
# define ANYARGS
# endif
#endif
... because of the change in C23 I mentioned above, i.e. (ANYARGS)
being ()
now means no arguments, not any.
I note that Ruby was adapted in part already for this change, see e.g. https://github.com/ruby/ruby/commit/4e64edb6cd8d1b444c591bfd50ec3d357e794f6e, but it appears that the headers that extensions need to build against aren't yet ready.