5

我在使用 gcc5.4.0 在大型项目上运行 make 时遇到了这个错误。

/usr/include/c++/5/sstream:300:14: error: '__xfer_bufptrs' redeclared with 'public' access
      struct __xfer_bufptrs
             ^
/usr/include/c++/5/sstream:67:14: note: previously declared 'private' here
      struct __xfer_bufptrs;

对我来说,这似乎是编译器的问题?由于问题出现在标准 c++ 库 sstream 中?这对我来说没有意义,我是否使用了错误的编译器?

以下是错误消息引用的代码片段:

1.) sstream 从第 67 行开始

class basic_stringbuf : public basic_streambuf<_CharT, _Traits>                                   
    {                                                                                                 
      struct __xfer_bufptrs;                                                                          
    public:                                                                                           

2.) sstream 在第 300 行

#if _GLIBCXX_USE_CXX11_ABI                                                                            
      // This type captures the state of the gptr / pptr pointers as offsets                          
      // so they can be restored in another object after moving the string.                           
      struct __xfer_bufptrs                                                                           
      {                                                                                               
        __xfer_bufptrs(const basic_stringbuf& __from, basic_stringbuf* __to)                          
        : _M_to{__to}, _M_goff{-1, -1, -1}, _M_poff{-1, -1, -1}                                       
        {  

我知道标准库不可能有任何问题,那为什么会抛出错误?

这是我得到的最接近的答案: https ://github.com/PacificBiosciences/pbbam/issues/14

似乎答案围绕着这些“Dprivate”和“Dpublic”标志。我假设是编译器标志,但我不确定它们是做什么的。

4

1 回答 1

12

github上的帖子虽然说中了,但似乎漏掉了原因。您很可能正在项目中构建一些单元或其他测试,这些测试重新定义了“private”关键字,如下所示:

#define private public

或者通过 ( -Dprivate=public) 之类的命令执行相应的操作。这是一种常用的做法,用于公开私有成员进行测试,而不会使测试代码依赖于测试代码。但是看看你的片段。无论__xfer_bufptrs您对private. 下一个第二个片段肯定(虽然尚未检查)在一个显式private块中。现在,如果您对私有的定义已经到位,那么您将public在第二个片段中遇到问题,这是一个错误。

您至少有两个选择,其他当然也是可能的:

  1. #undef在包含系统标头之前的私有定义并在包含这些标头后再次定义,或者
  2. 您使用另一个宏来定义您自己的私有/公共部分,例如:#define my_public public可以随意重新定义。这个解决方案似乎很恶心;)

哦,对于您自己的代码的未来,请始终使用显式访问限定来避免这种混乱,至少在您自己的代码中:)

于 2018-02-05T14:16:42.707 回答