sstream redeclared with public access compiler err

2019-07-17 10:29发布

问题:

I came across this error when running make on a large project using gcc5.4.0.

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

To me it seems like an issue with the compiler? Since the issue arises in a standard c++ library sstream? It does not make sense to me, am I using a wrong compiler?

Here are the code snippets the error messages refer to:

1.) sstream starting at line 67

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

2.) sstream at line 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}                                       
        {  

I know there cannot be anything wrong with the standard library so why is it throwing an error?

This is the closest I got to some answer: https://github.com/PacificBiosciences/pbbam/issues/14

And it seems the answer revolves around these "Dprivate" and "Dpublic" flags. Which I assume are compiler flags, but I'm not sure what they do.

回答1:

Although the thread at github hits the spot, it seems to miss the reason. You most likely are building some unit or other tests in your project that redefine the 'private' keyword like so:

#define private public

Or do the respective thing via command like (-Dprivate=public). This is a commonly used practice to expose private members for testing without making the tested code dependent on the testing code. However look at your snippets. The first one declares __xfer_bufptrs as private regardless of your definition of private. Next second snippet is surely (haven't checked though) in an explicit private block. Now if your definition of private is in place you will ned up with public in the second snippet which is a fault.

You have at least two options, other are surely also possible:

  1. You #undef the private definition before including system headers and define again after inclusion of those, or
  2. You use another macro to define your own private/public sections e.g.: #define my_public public which can be redefined at will. This solution seems icky though ;)

Oh and for the future in your own code always use explicit access qualification to avoid this sort of mess at least with your own code :)