最新版本的 python 2.7 (2.7.13) 包含一个 header unicodeobject.h
,它使用了 register
关键字。我的理解是 C++ 17 有 removed这个关键字。使用 C++ 17 针对此 header 进行编译时,毫不奇怪会触发一系列警告,包括:
/opt/anaconda/include/python2.7/unicodeobject.h:534:24: warning: ISO C++1z does not allow ‘register’ storage class specifier [-Wregister]
register PyObject *obj, /* Object */
^~~
/opt/anaconda/include/python2.7/unicodeobject.h:553:24: warning: ISO C++1z does not allow ‘register’ storage class specifier [-Wregister]
register PyObject *obj /* Object */
^~~
/opt/anaconda/include/python2.7/unicodeobject.h:575:29: warning: ISO C++1z does not allow ‘register’ storage class specifier [-Wregister]
register const wchar_t *w, /* wchar_t buffer */
^
/opt/anaconda/include/python2.7/unicodeobject.h:593:23: warning: ISO C++1z does not allow ‘register’ storage class specifier [-Wregister]
register wchar_t *w, /* wchar_t buffer */
也就是说,尽管有这些警告,我仍然能够编译和运行 python 扩展。继续这样做是否安全?有什么办法(除了明确忽略警告)来解决这些消息,例如升级到不同版本的 2.7(尽管如前所述,最新版本似乎仍在使用 register
关键字)?
最佳答案
register
的使用已经在这个头文件的 Python 3 版本中被删除,所以如果可能,你应该使用 Python 3 头文件(Python 2 将在几年内不再维护).
否则,您有几个选择。
- 如果您正在使用这些 header 的本地版本(例如随模块分发),您可以自己简单地删除
register
的使用(文件中只有四个)。如果您针对系统 header 进行编译,这显然是一个糟糕的解决方案 - CPython 实际上是用 C 而不是 C++ 编写的,并且 C 既没有弃用也没有删除
register
关键字,因此如果您正在编译的模块是用 C 编写的,您可以使用 C 编译器 (例如gcc
) 而不是 C++ 编译器。 (我希望该模块是用 C++ 编写的,所以这可能不是一个选项)。 - 忽略警告。正如我提到的,
register
关键字只有 4 次使用,因此您可以考虑使用它。 禁用注册警告。您可以通过在命令行上传递标志
-Wno-register
为整个项目执行此操作,或者您可以通过执行以下操作仅针对此 header 禁用它:#pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wregister"` #include <unicodeobject.h> // or whatever header includes unicodeobject.h #pragma GCC diagnostic pop
这将保存当前警告设置,忽略该 header 的
register
警告,然后在包含 header 后恢复原始警告设置。虽然 pragma 说的是 GCC,但 Clang 也会理解这个 pragma 并按照您的意愿行事。
关于python - C++ 17 与 Python 2.7 的兼容性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49692794/