Как избежать предупреждения gcc в расширении Python C при использовании Py_BEGIN_ALLOW_THREADS

Самый простой способ манипулировать GIL в расширениях Python C — использовать предоставленные макросы:

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;
}

Это прекрасно работает, позволяя мне выпустить GIL для основной части моего кода, но повторно захватить его для небольших фрагментов кода, которые в нем нуждаются.

Проблема в том, что когда я компилирую это с помощью gcc, я получаю:

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

потому что Py_BEGIN_ALLOW_THREADS определяется так:

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

Итак, три вопроса:

  1. Можно ли подавить предупреждение gcc,
  2. Кто-нибудь знает, почему gcc считает, что _save может использоваться неинициализированным, поскольку он назначается сразу после его объявления и
  3. Почему бы не определить макрос для объявления и инициализации переменной в одном выражении, чтобы избежать проблемы?

(последние два на самом деле просто для моего собственного любопытства).

Я могу избежать этой проблемы, не используя макросы и делая все сам, но я бы этого не хотел.


person Ned Batchelder    schedule 27.01.2010    source источник


Ответы (3)


  1. Да, можно подавить неинициализированные предупреждения с помощью префикса -Wno-.

-Wall -Wno-uninitialized

Если вы хотите удалить только это предупреждение, вы можете просто инициализировать _save нулевым указателем, чтобы он не полагался на возвращаемое значение функции... эта одна строка кода и комментарий имеют смысл для меня:

PyThreadState *_save; 
_save = 0; /* init as null pointer value */
_save = PyEval_SaveThread();
person Jason Coon    schedule 27.01.2010
comment
Я надеялся найти очень локализованный способ отключить только одно предупреждение в этой строке. Я бы предпочел не отключать все неинициализированные предупреждения. - person Ned Batchelder; 27.01.2010
comment
если вы хотите предотвратить только это предупреждение, добавьте строку перед вызовом PyEval_SaveThread(), чтобы инициализировать _save нулевым указателем (см. обновленный ответ выше) - person Jason Coon; 27.01.2010

Мои два цента:

  1. Вы можете подавить определенные предупреждения, но я думаю, вы уже это знаете.
  2. Он говорит, что может быть не инициализирован :-)
  3. Единственная причина, которую я могу себе представить, это совместимость со старыми компиляторами C.

Я пытался копаться в источник, но не смог найти никаких подсказок.

person csl    schedule 27.01.2010
comment
1. Я знал, что могу отключить целые классы предупреждений в командной строке, но я надеялся на прагму, которая могла бы отключить только это одно предупреждение. - person Ned Batchelder; 27.01.2010

Нед, вы можете попробовать один из следующих:

#pragma GCC diagnostic warning "-Wno-unitialized"
#pragma GCC diagnostic error "-Wno-uninitialized"
#pragma GCC diagnostic ignored "-Wno-uninialized"

Или игнорировать -Wuninitialized? Согласно документации, вы должны сделать это до того, как будут определены какие-либо данные или функции. Может быть, это позволит вам отключить предупреждение только для этого файла?

person joeforker    schedule 27.01.2010