使用 Py_BEGIN_ALLOW_THREADS 时如何避免 Python C 扩展中的 gcc 警告

发布于 08-19 12:00 字数 956 浏览 15 评论 0原文

在 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();

所以,三个问题:

  1. 是否有可能抑制 gcc 的警告,
  2. 有谁知道为什么 gcc 认为 _save 可能可以在未初始化的情况下使用,因为它是在声明后立即分配的,
  3. 为什么不定义宏来在一条语句中声明和初始化变量以避免出现问题?

(最后两个实际上只是出于我自己的好奇心)。

我可以通过不使用宏并自己完成这一切来避免这个问题,但我宁愿不这样做。

The simplest way to manipulate the GIL in Python C extensions is to use the macros provided:

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;
}

This works great, letting me release the GIL for the bulk of my code, but re-grabbing it for small bits of code that need it.

The problem is when I compile this with gcc, I get:

ext/engine.c:548: warning: '_save' might be used uninitialized in this function

because Py_BEGIN_ALLOW_THREADS is defined like this:

#define Py_BEGIN_ALLOW_THREADS { \
        PyThreadState *_save; \
        _save = PyEval_SaveThread();

So, three questions:

  1. Is it possible to suppress gcc's warning,
  2. Does anyone have any idea why gcc thinks _save might be used uninitialized, since it is assigned to immediately after its declaration, and
  3. Why wouldn't the macro have been defined to declare and initialize the variable in one statement to avoid the issue?

(the last two are really just for my own curiosity).

I can avoid the issue by not using the macros and doing it all myself, but I'd rather not.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

彼岸花ソ最美的依靠2024-08-26 12:00:35
  1. 是的,可以使用 -Wno- 前缀来抑制未初始化的警告。

-Wall -Wno-uninitialized

如果您只想删除此警告,只需将 _save 初始化为空指针,这样它就不会依赖于函数返回值...一行代码和一条注释对我来说很有意义:

PyThreadState *_save; 
_save = 0; /* init as null pointer value */
_save = PyEval_SaveThread();
  1. Yes, it is possible to suppress uninitialized warnings using the -Wno- prefix.

-Wall -Wno-uninitialized

If you want to remove just this warning, you could simply initialize _save to a null pointer so that it doesn't rely on a function return value... that one line of code and a comment makes sense to me:

PyThreadState *_save; 
_save = 0; /* init as null pointer value */
_save = PyEval_SaveThread();
断爱2024-08-26 12:00:35

我的两分钱:

  1. 你可以抑制特定的警告,但我想你已经知道了。
  2. 它说可能未初始化:-)
  3. 我能想象的唯一原因是与旧版C编译器的兼容性。

我尝试深入研究 来源,但找不到任何好的线索。

My two cents:

  1. You can suppress specific warnings, but I guess you already knew that.
  2. It says might be uninitialized :-)
  3. The only reason I can imagine is compatibility with older C compilers.

I tried digging into the source, but couldn't find any good clues.

dawn曙光2024-08-26 12:00:35

Ned,您可以尝试其中之一

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

或者忽略-Wuninitialized?根据文档,您必须在定义任何数据或函数之前执行此操作。也许它会让您禁用该文件的警告?

Ned, you can try one of these:

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

Or ignore -Wuninitialized? According to the documentation, you have to do this before any data or functions are defined. Maybe it will let you disable the warning just for that file?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文