首页 文章

这个c模板代码有效吗? g编译它但clang不会

提问于
浏览
2

我试图在Fedora上使用clang和默认的C标准库(4.6.2)编译一个小的c程序 . Clang本身编译好了,测试程序只使用编译并运行正常 .

我的另一个程序使用绳索抱怨 .

/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c /4.6.2/ext/ropeimpl.h:433:2:错误:使用未声明的标识符'_Data_allocate'Data_allocate(S_rounded_up_size( old_len __len));

针对此错误消息向clang提交了bug,并且解决方法是clang是正确的,库代码无效 .

Clang在这里是正确的 . 在调用_Data_allocate时没有类型相关的参数,因此名称查找在模板定义时失败 .

失败代码的上下文:

// Concatenate a C string onto a leaf rope by copying the rope data.
  // Used for short ropes.
  template <class _CharT, class _Alloc>
    typename rope<_CharT, _Alloc>::_RopeLeaf*
    rope<_CharT, _Alloc>::
    _S_leaf_concat_char_iter(_RopeLeaf* __r, const _CharT* __iter, size_t __len)
    {
      size_t __old_len = __r->_M_size;
      _CharT* __new_data = (_CharT*)
    _Data_allocate(_S_rounded_up_size(__old_len + __len));
      _RopeLeaf* __result;

      uninitialized_copy_n(__r->_M_data, __old_len, __new_data);
      uninitialized_copy_n(__iter, __len, __new_data + __old_len);
      _S_cond_store_eos(__new_data[__old_len + __len]);
      __try
    {
      __result = _S_new_RopeLeaf(__new_data, __old_len + __len,
                     __r->_M_get_allocator());
    }
      __catch(...)
    {
      _RopeRep::__STL_FREE_STRING(__new_data, __old_len + __len,
                      __r->_M_get_allocator());
      __throw_exception_again;
    }
      return __result;
    }

我的问题是,如果此代码无效,是否有一个简单的解决方法? g编译好了 .

1 回答

  • 4

    通过libstdc源代码,似乎成员函数 _Data_allocate 的定义是由模板 _Rope_base 定义中 __ROPE_DEFINE_ALLOCS 宏的扩展产生的(请注意,模板实例化 rope<_CharT, _Alloc> 公开扩展 _Rope_base<_CharT, _Alloc> ) .

    您可以尝试进一步将呼叫限定为 _Data_allocate . 代替:

    _Data_allocate(_S_rounded_up_size(__old_len + __len));
    

    尝试:

    _Rope_base<_CharT, _Alloc>::_Data_allocate(_S_rounded_up_size(__old_len + __len));
    

    或者干脆:

    _Base::_Data_allocate(_S_rounded_up_size(__old_len + __len));
    

    因为 rope<_CharT, _Alloc> 定义中受保护的 typedef _Rope_base<_CharT, _Alloc> _Base; .

    EDIT: 我没有在本地安装Clang,但我用online Clang 3.0 compiler demo测试了这个 .

    这个高度精简的版本无法使用Clang 3.0进行编译(错误:使用未声明的标识符'_Data_allocate'):

    #include <cstddef>
    #include <memory>
    
    template <typename _CharT, class _Alloc>
    class _Rope_base : public _Alloc
    {
    public:
        typedef typename _Alloc::template rebind<_CharT>::other _DataAlloc;
        static _CharT * _Data_allocate(std::size_t __n) {
            return _DataAlloc().allocate(__n);
        }
    };
    
    template <typename _CharT, class _Alloc = std::allocator<_CharT> >
    class rope : public _Rope_base<_CharT, _Alloc>
    {
    protected:
        typedef _Rope_base<_CharT, _Alloc> _Base;
    
    public:
        rope()
        {
            _Data_allocate(0);
        }
    };
    
    int main()
    {
        rope<char> r;
    }
    

    通过以上面建议的任何一种方式将调用限定为 _Data_allocate ,Clang 3.0成功编译它 .

相关问题