From: Paul Brannan Date: 2001-10-25T03:28:26+09:00 Subject: [ruby-talk:23214] () vs (...) in header files There is a serious problem with including ruby.h and intern.h in C++ extensions under gcc 3.0.1 (we are getting ready to move to 3.0.1 here VERY soon, so this is a big issue for us). I have a patch for Ruby 1.6.5 available at: http://rm-f.net/~cout/ruby/ruby_unspecified_params_fix.patch but I am not confident that I have done everything properly. The biggest problem I had was that rb_gc_mark takes a void*, but very often it is called with a VALUE; I'm not sure what to do about this (for now, I just cast VALUE to void*, but perhaps the opposite is more correct). C has a (deprecated) "feature" that allows me to do this: int foo(); int bar() { return foo(1, 2, 3); } int foo(int a, int b, int c) { return 42; } The first line there tells the compiler that foo() has unspecified parameters. If it were possible, then (I think) this would be the same as: int foo(...); (this is not really legal ANSI C, since the standard requires at least one argument in front of (...)). C++ does not allow unspecified arguments using (). Instead, int foo(); in C++ is the same as; int foo(void); In g++ 2.95.3, int foo() in a C header file is interpreted as int foo(...), so RUBY_DATA_FUNC and RUBY_METHOD_FUNC work as expected. However, in g++ 3.0.1, even in a C header file int foo() is interpreted as int foo(void). This means that I have to (wrongly) cast my methods to VALUE(*)(void) before I can pass them to rb_define_method(). Functions that have this problem include (but are not limited to): rb_protect_inspect rb_define_method_id rb_define_protected_method rb_define_private_method rb_define_singleton_method rb_define_private_method rb_protect rb_set_end_proc rb_thread_create posix_signal rb_glob rb_globi rb_define_variable rb_define_virtual_variable rb_define_hooked_variable rb_define_method rb_define_module_function rb_define_global_function rb_iterate rb_rescue rb_rescue2 rb_ensure rb_catch Also note that there are many methods in intern.h that have unspecified parameters. This is bad, since it allows me to pass wrong parameters (or even no parameters at all) to such functions. Functions that have this problem include (but are not limited to): rb_thread_select rb_gc_mark_maybe rb_gc_mark rb_thread_wait_for Possible solutions: 1) Have rb_define_method() and friends take (...) if __cplusplus is defined, and take () if it is not (since (...) is not legal C). 2) Have rb_define_method() and friends take _((VALUE, ...)). This seems a good solution to me, since all METHOD_FUNCs take a parameter of self anyway, and this would help to enforce that. Not all the functions listed above do take a parameter, so those that don't should take _((void)). Please note the use of the _ for compatibility with pre-ANSI compilers. 3) A cross between the above solutions seems like a good compromise, since it is (a) safe when compiling C++ extensions and (b) requires fewer changes to the *.c files (it's a pain to have to had (RUBY_METHOD_FUNC)foo to every line that calls rb_define_method). This is the what I've done in my patch: I've added a new macro, ___, which uses unspecied parameters when compiling as C and specified parameters when compiling as C++, but whenever possible, parameters are fully specified. Comments? Suggestions? Paul