Search code examples
pythongccgilcextension

How to avoid gcc warning in Python C extension when using Py_BEGIN_ALLOW_THREADS


The simplest way to manipulate the GIL in Python C extensions is to use the macros provided:

my_awesome_C_function() 
{
    blah;

    Py_BEGIN_ALLOW_THREADS

    // do stuff that doesn't need the GIL

    if (should_i_call_back) {
        Py_BLOCK_THREADS
        // do stuff that needs the GIL
        Py_UNBLOCK_THREADS
    }

    Py_END_ALLOW_THREADS

    return blah blah;
}

This works great, letting me release the GIL for the bulk of my code, but re-grabbing it for small bits of code that need it.

The problem is when I compile this with gcc, I get:

ext/engine.c:548: warning: '_save' might be used uninitialized in this function

because Py_BEGIN_ALLOW_THREADS is defined like this:

#define Py_BEGIN_ALLOW_THREADS { \
        PyThreadState *_save; \
        _save = PyEval_SaveThread();

So, three questions:

  1. Is it possible to suppress gcc's warning,
  2. Does anyone have any idea why gcc thinks _save might be used uninitialized, since it is assigned to immediately after its declaration, and
  3. Why wouldn't the macro have been defined to declare and initialize the variable in one statement to avoid the issue?

(the last two are really just for my own curiosity).

I can avoid the issue by not using the macros and doing it all myself, but I'd rather not.


Solution

    1. Yes, it is possible to suppress uninitialized warnings using the -Wno- prefix.

    -Wall -Wno-uninitialized

    If you want to remove just this warning, you could simply initialize _save to a null pointer so that it doesn't rely on a function return value... that one line of code and a comment makes sense to me:

    PyThreadState *_save; 
    _save = 0; /* init as null pointer value */
    _save = PyEval_SaveThread();