This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: C++ automatic template instantiation?



  On Wednesday, 19 April 2000, Mike Stump wrote:
> > The existing -frepo in 2.95.2 appears to miss lots of used symbols.
> 
> Ok.  Sounds like a bug, bugs should be reported.

I thought this is a well known problem, our C++ code has tons of
explicit instantiations required because -frepo misses lots of
symbols, especially in STL code.

What is even more annoying is that the symbols that are missed are not
only symbols that are used explicity in the code, but tons of symbols
that are used internally by the STL.  To make the matters worse, these
symbols change from version to version, and lots of #ifdefs based on
the GCC version need to go into the code in order to handle this.
Finally, even for the same version of gcc, the same code compiled on
different platforms yields different undefined symbols.  We used
egcs-1.1.2 & gcc-2.95.2 on ix86 and mips and we had files in which 30%
of the code was with template instantiations.

Internal STL symbols are tedious to resolve from the linker error
messages, mostly because they end up being fully expanded (for
instance string is replaced by something like
basic_string<your_life_story_here>).  In many cases the symbol
reported comes in the form of a C++ mangled string that I cannot
demangle with c++filt, and I have to blindly guess it, which takes a
lot of time, greping through the STL header files, etc.

Libraries are another ugly story, because the libraries are not
"recompiled" when some code that uses them is missing a certain
symbol.  I believed that was also a known problem.

Another weird behavior is the fact that sometimes, if I define the
symbol twice in 2 different files (by mistake), gcc gets stuck in an
infinite loop, recompiling the 2 files.

Finally, I have cases where the same code compiles fine w/o debug
info, but fails with undefined symbols _once_ when compiling w/ debug
info.  _Once_ means that if I type make a second time, it will resume
and compile/link ok.

I'll try to come up with some small examples.  It won't be easy,
because the code is large and I'm not sure that I'll be able to
reproduce all the problems described above.  I'll give it a try
though.

Regards,
Tudor

P.S.

This is what we usually end up doing because of missed symbols (this
is after we dropped the suport for egcs-1.1.2, where _Hashtable_node
was defined as hashtable_node or something):

#if defined USE_REPO && defined __GNUG__
template class vector<int>;
template struct hash_string<ExchangeObject>;
template struct hash_string<ExchangeAttribute>;
template struct equal_string<ExchangeObject>;
template struct equal_string<ExchangeAttribute>;
template class ExchangeAttributeTemplate<string>;
template class ExchangeAttributeTemplate<int>;
template bool ExchangeObject::parse<eString>(
    eString& attribute, string& line);
template bool ExchangeObject::parse<eInt>(
    eInt& attribute, string& line);
template class hash_set<
    ExchangeObject*,
    hash_string<ExchangeObject>,
    equal_string<ExchangeObject> >;
template class hash_set<
    const ExchangeAttribute*,
    hash_string<ExchangeAttribute>,
    equal_string<ExchangeAttribute> >;
template class hashtable<
    ExchangeObject*,
    ExchangeObject*,
    hash_string<ExchangeObject>,
    identity<ExchangeObject*>,
    equal_string<ExchangeObject> >;
template class hash_set<
    ExchangeAttribute const*,
    hash_string<ExchangeAttribute>,
    equal_string<ExchangeAttribute> >;
template class hashtable<
    ExchangeAttribute const*,
    ExchangeAttribute const*,
    hash_string<ExchangeAttribute>,
    identity<ExchangeAttribute const*>,
    equal_string<ExchangeAttribute> >;
template vector<_Hashtable_node<ExchangeObject*>*,
    __default_alloc_template<true, 0> >;
template vector<_Hashtable_node<ExchangeAttribute const*>*,
    __default_alloc_template<true, 0> >;
template _Hashtable_const_iterator<
    ExchangeObject*,
    ExchangeObject*,
    hash_string<ExchangeObject>,
    _Identity<ExchangeObject*>,
    equal_string<ExchangeObject>,
    allocator<ExchangeObject*> >&
    _Hashtable_const_iterator<
	ExchangeObject*,
	ExchangeObject*,
	hash_string<ExchangeObject>,
	_Identity<ExchangeObject*>,
	equal_string<ExchangeObject>,
	allocator<ExchangeObject*> >::operator++(void);
template _Hashtable_const_iterator<
    ExchangeAttribute const*,
    ExchangeAttribute const*,
    hash_string<ExchangeAttribute>,
    _Identity<ExchangeAttribute const*>,
    equal_string<ExchangeAttribute>,
    allocator<ExchangeAttribute const*> >&
    _Hashtable_const_iterator<
	ExchangeAttribute const*,
	ExchangeAttribute const*,
	hash_string<ExchangeAttribute>,
	_Identity<ExchangeAttribute const*>,
	equal_string<ExchangeAttribute>,
	allocator<ExchangeAttribute const*> >::operator++(void);
template hashtable<
    ExchangeObject*,
    ExchangeObject*,
    hash_string<ExchangeObject>,
    _Identity<ExchangeObject*>,
    equal_string<ExchangeObject>,
    allocator<ExchangeObject*> >;
template vector<
    _Hashtable_node<const ExchangeAttribute*>*,
    allocator<const ExchangeAttribute*> >;
template vector<
    _Hashtable_node<ExchangeObject*>*,
    allocator<ExchangeObject*> >;
template hashtable<
    const ExchangeAttribute*,
    const ExchangeAttribute*,
    hash_string<ExchangeAttribute>,
    _Identity<const ExchangeAttribute*>,
    equal_string<ExchangeAttribute>,
    allocator<const ExchangeAttribute*> >;
template void fill<
    _Hashtable_node<const ExchangeAttribute*>**,
    _Hashtable_node<const ExchangeAttribute*>*>(
	_Hashtable_node<const ExchangeAttribute*>**,
	_Hashtable_node<const ExchangeAttribute*>**,
	_Hashtable_node<const ExchangeAttribute*>* const&);
template _Hashtable_node<ExchangeAttribute const*>** fill_n<
    _Hashtable_node<ExchangeAttribute const*>**,
    unsigned int,
    _Hashtable_node<ExchangeAttribute const*>*>(
	_Hashtable_node<ExchangeAttribute const*>**,
	unsigned int,
	_Hashtable_node<ExchangeAttribute const*>* const&);
template pair<string, AttributeTypeId>* fill_n<
    pair<string, AttributeTypeId>*,
    unsigned int,
    pair<string, AttributeTypeId> >(
	pair<string, AttributeTypeId>*,
	unsigned int,
	pair<string, AttributeTypeId> const&);
template pair<string, AttributeTypeId>* __uninitialized_fill_n_aux<
    pair<string, AttributeTypeId>*,
    size_t,
    pair<string, AttributeTypeId> >(
	pair<string, AttributeTypeId>*,
	size_t,
	const pair<string, AttributeTypeId>&,
	__false_type);
template class vector<AttributeInfo>;
template class pair<string, AttributeTypeId>;
template void fill<AttributeInfo*, AttributeInfo>(
    AttributeInfo*, AttributeInfo*, const AttributeInfo&);
template AttributeInfo*
    __uninitialized_copy_aux<AttributeInfo*, AttributeInfo*>(
	AttributeInfo*,
	AttributeInfo*,
	AttributeInfo*,
	__false_type);
template AttributeInfo*
    __uninitialized_copy_aux<const AttributeInfo*, AttributeInfo*>(
	const AttributeInfo*,
	const AttributeInfo*,
	AttributeInfo*,
	__false_type);
template void fill<int*, int>(int*, int*, int const&);
template int* fill_n<int*, unsigned int, int>(int*, unsigned int, int const&);

#if defined __mips
#else
template _Hashtable_node<ExchangeObject*>** fill_n<
    _Hashtable_node<ExchangeObject*> **,
    unsigned int,
    _Hashtable_node<ExchangeObject*>*>(
	_Hashtable_node<ExchangeObject*>**,
	unsigned int,
	_Hashtable_node<ExchangeObject*>* const&);
template void fill<
    _Hashtable_node<ExchangeObject*>**,
    _Hashtable_node<ExchangeObject*>*>(
	_Hashtable_node<ExchangeObject*>**,
	_Hashtable_node<ExchangeObject*>**,
	_Hashtable_node<ExchangeObject*>* const&);
#endif // __mips

#endif // USE_REPO && __GNUG__


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]