Reputation: 1577
I've been reading through the Python source code for kicks the last couple days, and I came across something I didn't understand. In the "abstract.c" file I found the below code snippet. I thought I understood how it worked, but then I realized I had no clue where the *v
and *w
come from. Could somebody please explain what is going on in this code, and an example of how you would use it?
#define BINARY_FUNC(func, op, op_name) \
PyObject * \
func(PyObject *v, PyObject *w) { \
return binary_op(v, w, NB_SLOT(op), op_name); \
}
BINARY_FUNC(PyNumber_Or, nb_or, "|")
BINARY_FUNC(PyNumber_Xor, nb_xor, "^")
BINARY_FUNC(PyNumber_And, nb_and, "&")
BINARY_FUNC(PyNumber_Lshift, nb_lshift, "<<")
BINARY_FUNC(PyNumber_Rshift, nb_rshift, ">>")
BINARY_FUNC(PyNumber_Subtract, nb_subtract, "-")
BINARY_FUNC(PyNumber_Divmod, nb_divmod, "divmod()")
Upvotes: 1
Views: 903
Reputation: 782305
v
and w
are not macro parameters, they're literal parts of the expansion. The macro expands into a function definition, and the function takes parameters -- they're always named v
and w
, and they're of type PythonObject *
. For example:
BINARY_FUNC(PyNumber_Or, nb_or, "|")
expands into:
PythonObject *
PyNumber_Or(PyObject *v, PyObject *w) {
return binary_op(v, w, NB_SLOT(nb_or), "|");
}
Upvotes: 2
Reputation: 12515
#define BINARY_FUNC(func, op, op_name) \
PyObject * \
func(PyObject *v, PyObject *w) { \
return binary_op(v, w, NB_SLOT(op), op_name); \
}
BINARY_FUNC(PyNumber_Or, nb_or, "|")
The BINARY_FUNC
defination I included above expands to:
PyObject *PyNumber_Or(PyObject *v, PyObject *w) {
return binary_op(v, w, NB_SLOT(nb_or), "|");
}
An entire function where the u
and v
pointers are part of the function. Of course, there is no parenthesis safety so it would be pretty darn easy to break when passing in "bad" values...
Upvotes: 0