C++ 17与Python 2.7的兼容性

mcg*_*uip 6 c++ python python-2.7 c++17

最新版本的python 2.7(2.7.13)包含一个unicodeobject.h使用该register关键字的标头.我的理解是C++ 17 删除了这个关键字.使用C++ 17编译此头文件时,会触发一系列警告,包括:

/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 */
Run Code Online (Sandbox Code Playgroud)

也就是说,尽管有这些警告,我仍然可以编译和运行python扩展.继续这样做是否安全?是否有任何方法(除了明确忽略警告)解决这些消息,如升级到2.7的不同版本(虽然提到最新版本似乎仍然使用register关键字)?

SJL*_*SJL 6

采用register已经在Python 3版本的这个头的被删除,所以如果可能的话,你应该使用Python 3头(Python 2里将不再保持在几年内).

否则,您有几个选择.

  • 如果您使用这些标头的本地版本(例如随模块一起分发),您只需删除register自己的使用(文件中只有四个).如果您正在编译系统头文件,这显然是一个糟糕的解决方案
  • CPython实际上是用C语言编写的,而不是C++,C既没有弃用也没有删除register关键字,因此如果要编译的模块是用C语言编写的,则可以使用C编译器(例如gcc)代替C++编译器.(我希望模块是用C++编写的,所以这可能不是一个选项).
  • 忽略警告.正如我所提到的,register关键字只有4种用法,所以你可以考虑使用它.
  • 禁用注册警告.您可以通过在-Wno-register命令行上传递标志来为整个项目执行此操作,或者您可以通过执行以下操作为此标头禁用它:

    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wregister"`
    #include <unicodeobject.h> // or whatever header includes unicodeobject.h
    #pragma GCC diagnostic pop
    
    Run Code Online (Sandbox Code Playgroud)

    这将保存当前警告设置,忽略该register标头的警告,然后在包含标头后恢复原始警告设置.虽然pragma说GCC,但Clang也会理解这个pragma并表现出你的喜好.