سؤال

I was reading through the file methodobject.c, because I'm trying to learn about making C extensions for Python, when I saw the following code snippet:

PyObject *
PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw)
{
    PyCFunctionObject* f = (PyCFunctionObject*)func;
    PyCFunction meth = PyCFunction_GET_FUNCTION(func);
    PyObject *self = PyCFunction_GET_SELF(func);
    Py_ssize_t size;

    switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) {
    case METH_VARARGS:
        if (kw == NULL || PyDict_Size(kw) == 0)
           return (*meth)(self, arg);
        break;

The more I look at

    return (*meth)(self, arg);

the more I realize I don't understand it. I think it's returning a pointer to meth, which is a function that takes self (a locally declared pointer) and arg (a pointer passed externally into PyCFunctionCall). However, since it looks to me as though meth & self are allocated on the stack, once PyCFunctionCall exits, they will be freed, which will cause problems for whatever variables they are passed to.

What am I missing here?

هل كانت مفيدة؟

المحلول

It's returning the return value of meth(self, arg), not meth itself. Note that it's derferencing the pointer with (*meth), then passing in self and arg to the function at that location.

So meth(self, arg) will be completely evaluated before the return happens, and no stack variables will be returned.

Edit: when I say meth(self, arg), I mean the_function_pointed_to_by_meth(self, arg).

نصائح أخرى

meth is a function pointer. It's returning the result of the function at *meth (the address pointed by meth) with the arguments: (self, arg);

(*meth)(self, arg) is a function call.

It just so happens that the function pointer is a local variable. The return merely passes on whatever comes back from the call.

Function pointer syntax is confusing. :)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top