Ruby: include/ruby/internal/anyargs.h File Reference

Ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c52d4d35cc6a173c89eda98ceffa2dcf)

Macros
anyargs.h File Reference

Function overloads to issue warnings around ANYARGS. More...

`#include "ruby/internal/attr/maybe_unused.h"`
`#include "ruby/internal/attr/nonnull.h"`
`#include "ruby/internal/attr/weakref.h"`
`#include "ruby/internal/cast.h"`
`#include "ruby/internal/config.h"`
`#include "ruby/internal/has/attribute.h"`
`#include "ruby/internal/intern/class.h"`
`#include "ruby/internal/intern/vm.h"`
`#include "ruby/internal/method.h"`
`#include "ruby/internal/value.h"`
`#include "ruby/backward/2/stdarg.h"`
`#include "ruby/backward/cxxanyargs.hpp"`

Go to the source code of this file.

## Macros
#define | RUBY_METHOD_FUNC(func) RBIMPL_CAST((VALUE (*)(ANYARGS))(func))
| This macro is to properly cast a function parameter of *_define_method family. More...

## Detailed Description

Function overloads to issue warnings around ANYARGS.

Author
  Ruby developers ruby-.nosp@m.core.nosp@m.@ruby.nosp@m.-lan.nosp@m.g.org

Copyright
  This file is a part of the programming language Ruby. Permission is hereby granted, to either redistribute and/or modify this file, provided that the conditions mentioned in the file COPYING are met. Consult the file for details.

Warning
  Symbols prefixed with either `RBIMPL` or `rbimpl` are implementation details. Don't take them as canon. They could rapidly appear then vanish. The name (path) of this header file is also an implementation detail. Do not expect it to persist at the place it is now. Developers are free to move it anywhere anytime at will.

Note
  To ruby-core: remember that this header can be possibly recursively included from extension libraries written in C++. Do not expect for instance `__VA_ARGS__` is always available. We assume C99 for ruby itself but we don't assume languages of extension libraries. They could be written in C++98.

For instance rb_define_method takes a pointer to ANYARGS -ed functions, which in fact varies 18 different prototypes. We still need to preserve ANYARGS for storages but why not check the consistencies if possible. With those complex macro overlays defined in this header file, use of a function pointer gets checked against the corresponding arity argument.

### Q&A

- Q: Where did the magic number "18" came from in the description above?
- A: Count the case branch of `vm_method.c:call_cfunc_invoker_func()`. Note also that the 18 branches has lasted for at least 25 years. See also commit 200e0ee2fd3c1c006c528874a88f684447215524.
- Q: What is this `__weakref__` thing?
- A: That is a kind of function overloading mechanism that GCC provides. In this case for instance `rb_define_method_00` is an alias of rb_define_method, with a strong type.

- Q: What is this `__transparent_union__` thing?

  A: That is another kind of function overloading mechanism that GCC provides. In this case the attributed function pointer is either `VALUE(*)(int,VALUE*,VALUE)` or `VALUE(*)(int,const VALUE*,VALUE)`.

  This is better than `void*` or ANYARGS because we can reject all other possibilities than the two.

- Q: What does this rb_define_method macro mean?
- A: It selects appropriate alias of the rb_define_method function, depending on the last (arity) argument.
- Q: Why the special case for rb_f_notimplement ?
- A: Function pointer to rb_f_notimplement is special cased in `vm_method.c:rb_add_method_cfunc()`. That should be handled by the `__builtin_choose_expr` chain inside of rb_define_method macro expansion. In order to do so, comparison like `(func == rb_f_notimplement)` is inappropriate for `__builtin_choose_expr`'s expression (which must be a compile-time integer constant but the address of rb_f_notimplement is not fixed until the linker). Instead we are using `__builtin_types_compatible_p`, and in doing so we need to distinguish rb_f_notimplement from others, by type.

Definition in file anyargs.h.

## Macro Definition Documentation

## ◆ RUBY_METHOD_FUNC

#define RUBY_METHOD_FUNC | ( |  | func | ) | RBIMPL_CAST((VALUE (*)(ANYARGS))(func))

This macro is to properly cast a function parameter of *_define_method family.

It has been around since 1.x era so you can maximize backwards compatibility by using it.

rb_define_method(klass, "method", RUBY_METHOD_FUNC(func), arity);
RUBY_METHOD_FUNC
#define RUBY_METHOD_FUNC(func)
This macro is to properly cast a function parameter of *_define_method family.
Definition: anyargs.h:362
rb_define_method
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
Definition: cxxanyargs.hpp:653

Parameters

  func | A pointer to a function that implements a method.

Definition at line 362 of file anyargs.h.