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

StackOverflow https://stackoverflow.com/questions/2147029

  •  23-09-2019
  •  | 
  •  

Вопрос

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

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

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

Это было полезно?

Решение

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

-Wall -Wno-uninitialized

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

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

Другие советы

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top