C++ 单元测试 访问控制小坑

error: 'struct std::basic_stringbuf<_CharT, _Traits, _Alloc>::__xfer_bufptrs' redeclared with different access struct __xfer_bufptrs 总么肥四? 系统库报错啦? 粗bug啦?

总么肥四?

在编写 c++ 单元测试时, 为了方便访问私有属性/方法, 常用#define private public 将private 替换为 public, 或 编译时加入 -Dprivate=public。 这时, 在 gcc 高版本可能会出现如下报错

/usr/include/c++/7/sstream:348:7: error: 'struct std::basic_stringbuf<_CharT, _Traits, _Alloc>::__xfer_bufptrs' redeclared with different access
   struct __xfer_bufptrs

这是由于 c++ 访问控制的原由, 建议在编译时使用-fno-access-control 来实现私有成员的访问。

系统库bug?让我康康

  1. 根据报错信息,查找 sstream, 看到目标 struct __xfer_bufptrs, 结构体定义

     struct __xfer_bufptrs
     {
     __xfer_bufptrs(const basic_stringbuf &, basic_stringbuf *) {}
     };
    
  2. 上翻, 发现这个结构体是类内的私有定义

     private:
    
     ........
    
     // This type does nothing when using Copy-On-Write strings.
     struct __xfer_bufptrs
     {
     __xfer_bufptrs(const basic_stringbuf &, basic_stringbuf *) {}
     };
    
  3. 文件内查找 __xfer_bufptrs,发现定义没有访问限定符,em…私有的

     template <typename _CharT, typename _Traits, typename _Alloc>
     class basic_stringbuf : public basic_streambuf<_CharT, _Traits>
     {
         struct __xfer_bufptrs;
    
         ........
    

😯 ~~, 编译器发现在类开始声明了一个 私有的 struct __xfer_bufptrs, 下面定义竟变成了public! 年轻人不讲武德,乱改我的private, 报个 Error 先…

坑在这, 通过宏定义覆盖private为public后,方便了在单元测试时直接访问私有成员,但对于类前并没有显示声明public的成员无效,甚至会出现如上问题导致编译不过,所以在测试中使用编译参数 -fno-access-control 关闭访问控制才是正确的套路!

End.