如何在使用Py_BEGIN_ALLOW_THREADS时避免Python C扩展中的gcc警告
在Python的C扩展中,处理全局解释器锁(GIL)最简单的方法就是使用提供的宏:
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
可能会被未初始化使用,因为它在声明后马上就被赋值了, - 为什么这个宏没有被定义成在一个语句中声明并初始化变量,以避免这个问题呢?
(最后两个问题其实只是出于我自己的好奇)。
我可以通过不使用这些宏,自己处理所有的事情来避免这个问题,但我更希望不这样做。
3 个回答
0
Ned,你可以试试这些方法:
#pragma GCC diagnostic warning "-Wno-unitialized"
#pragma GCC diagnostic error "-Wno-uninitialized"
#pragma GCC diagnostic ignored "-Wno-uninialized"
或者忽略-Wuninitialized
这个警告?根据说明,你需要在定义任何数据或函数之前这样做。也许这样可以让你只在那个文件中关闭这个警告?
1
我来分享一下我的看法:
- 你可以选择忽略特定的警告,不过我想你可能已经知道这一点了。
- 它说这个变量可能没有被初始化 :-)
- 我能想到的唯一原因是为了和老旧的C编译器兼容。
我尝试去查找一下源代码,但没找到什么有用的线索。
3
- 是的,可以通过使用 -Wno- 前缀来抑制未初始化的警告。
-Wall -Wno-uninitialized
如果你只想去掉这个警告,可以简单地把 _save
初始化为一个空指针,这样它就不需要依赖函数的返回值了……这一行代码和一个注释对我来说是有意义的:
PyThreadState *_save;
_save = 0; /* init as null pointer value */
_save = PyEval_SaveThread();