1

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()")
4

2 回答 2

2

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), "|");
}
于 2013-05-15T17:52:04.867 回答
0
#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...

于 2013-05-15T17:51:24.083 回答