Как избежать предупреждения gcc в расширении Python C при использовании Py_BEGIN_ALLOW_THREADS - PullRequest
7 голосов
/ 27 января 2010

Самый простой способ манипулировать 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. Почему бы не определить макрос для объявления и инициализации переменной в одном операторе, чтобы избежать проблемы?

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

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

Ответы [ 3 ]

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

-Wall -Wno-uninitialized

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

PyThreadState *_save; 
_save = 0; /* init as null pointer value */
_save = PyEval_SaveThread();
1 голос
/ 27 января 2010

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

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

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

0 голосов
/ 27 января 2010

Нед, вы можете попробовать один из этих :

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

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

...