Como evitar o aviso do GCC na extensão do Python C ao usar py_begin_allow_threads
-
23-09-2019 - |
Pergunta
A maneira mais simples de manipular o GIL nas extensões Python C é usar as macros fornecidas:
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;
}
Isso funciona muito bem, deixando-me liberar o GIL para a maior parte do meu código, mas recolocando-o para pequenos bits de código que precisam dele.
O problema é quando eu compilar isso com o GCC, entendo:
ext/engine.c:548: warning: '_save' might be used uninitialized in this function
Porque py_begin_allow_threads é definido assim:
#define Py_BEGIN_ALLOW_THREADS { \
PyThreadState *_save; \
_save = PyEval_SaveThread();
Então, três perguntas:
- É possível suprimir o aviso do GCC,
- Alguém tem alguma ideia de por que o GCC pensa
_save
pode ser usado não inicializado, pois é atribuído imediatamente após sua declaração, e - Por que a macro não teria sido definida para declarar e inicializar a variável em uma declaração para evitar o problema?
(Os dois últimos são realmente apenas para minha própria curiosidade).
Posso evitar o problema por não usar as macros e fazer tudo sozinho, mas eu prefiro não.
Solução
- Sim, é possível suprimir avisos não inicializados usando o prefixo -wno-.
-Wall -Wno-uninitialized
Se você quiser remover apenas este aviso, você pode simplesmente inicializar _save
Para um ponteiro nulo, para que não dependa de um valor de retorno de função ... essa linha de código e um comentário fazem sentido para mim:
PyThreadState *_save;
_save = 0; /* init as null pointer value */
_save = PyEval_SaveThread();
Outras dicas
Meus dois centavos:
- Você pode suprimir avisos específicos, mas acho que você já sabia disso.
- Diz poderia Seja indiializado :-)
- A única razão pela qual posso imaginar é a compatibilidade com os compiladores C mais antigos.
Eu tentei cavar a fonte, mas não conseguiu encontrar boas pistas.
Ned, você pode tentar um desses:
#pragma GCC diagnostic warning "-Wno-unitialized"
#pragma GCC diagnostic error "-Wno-uninitialized"
#pragma GCC diagnostic ignored "-Wno-uninialized"
Ou ignorar -Wuninitialized
? De acordo com a documentação, você deve fazer isso antes que quaisquer dados ou funções sejam definidos. Talvez isso permita que você desative o aviso apenas para esse arquivo?