I am trying to compile a small c++ program using clang with the default C++ standard library(4.6.2) on Fedora. Clang itself compiles okay and a test program using only compiles and runs fine.
My other program uses ropes which clang complains about.
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/ext/ropeimpl.h:433:2:
error: use of
undeclared identifier ‘_Data_allocate’
_Data_allocate(_S_rounded_up_size(__old_len + __len));
A bug was filed against clang for this error message and the resolution was clang is correct, the library code is invalid.
Clang is correct here. There are no type-dependent arguments in the
call to
_Data_allocate, so name lookup fails at template definition time.
The context for the failing code:
// 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;
}
My question is, if this code is not valid, is there an easy workaround? g++ compiles this okay.
Digging through the libstdc++ source, it appears that the definition of member function
_Data_allocateresults from an expansion of the__ROPE_DEFINE_ALLOCSmacro in the definition of template_Rope_base(note that template instantiationrope<_CharT, _Alloc>publicly extends_Rope_base<_CharT, _Alloc>).You could try qualifying the call to
_Data_allocatefurther. Instead of:Try:
Or simply:
because of the protected
typedef _Rope_base<_CharT, _Alloc> _Base;in the definition ofrope<_CharT, _Alloc>.EDIT: I don’t have Clang installed locally, but I tested this out with the online Clang 3.0 compiler demo.
This highly pared-down version fails to compile with Clang 3.0 (error: use of undeclared identifier ‘_Data_allocate’):
By qualifying the call to
_Data_allocatein either way suggested above, Clang 3.0 succeeds in compiling it.