Как избежать предупреждения gcc в расширении Python C при использовании Py_BEGIN_ALLOW_THREADS
-
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();
Итак, три вопроса:
- Возможно ли подавить предупреждение gcc,
- У кого-нибудь есть какие-нибудь идеи, почему gcc думает
_save
может использоваться неинициализированным, поскольку он присваивается сразу после его объявления, и - Почему макрос не был определен для объявления и инициализации переменной в одном операторе, чтобы избежать проблемы?
(последние два на самом деле просто для моего собственного любопытства).
Я могу избежать этой проблемы, не используя макросы и делая все это сам, но я бы предпочел этого не делать.
Решение
- Да, можно подавить неинициализированные предупреждения, используя префикс -Wno-.
-Wall -Wno-uninitialized
Если вы хотите удалить только это предупреждение, вы могли бы просто инициализировать _save
к нулевому указателю, чтобы он не полагался на возвращаемое функцией значение...эта одна строка кода и комментарий имеют для меня смысл:
PyThreadState *_save;
_save = 0; /* init as null pointer value */
_save = PyEval_SaveThread();
Другие советы
Мои два цента:
- Вы можете подавить определенные предупреждения, но я думаю, вы уже знали это.
- В нем говорится мог бы быть неинициализированным :-)
- Единственная причина, которую я могу себе представить, - это совместимость со старыми компиляторами C.
Я попытался покопаться в источник, но не смог найти никаких хороших подсказок.
Нед, ты можешь попробовать один из этих:
#pragma GCC diagnostic warning "-Wno-unitialized"
#pragma GCC diagnostic error "-Wno-uninitialized"
#pragma GCC diagnostic ignored "-Wno-uninialized"
Или игнорировать -Wuninitialized
?Согласно документации, вы должны сделать это до того, как будут определены какие-либо данные или функции.Может быть, это позволит вам отключить предупреждение только для этого файла?