Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 381
Ned Batchelder Avatar asked Jan 27 '10 13:01

Ned Batchelder


2 Answers

  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();
like image 154
Jason Coon Avatar answered Nov 19 '22 11:11

Jason Coon


My two cents:

  1. You can suppress specific warnings, but I guess you already knew that.
  2. It says might be uninitialized :-)
  3. The only reason I can imagine is compatibility with older C compilers.

I tried digging into the source, but couldn't find any good clues.

like image 35
csl Avatar answered Nov 19 '22 10:11

csl