This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: Experience with g++ 4.8 and -frepo?
- From: David Kastrup <dak at gnu dot org>
- To: Jonathan Wakely <jwakely at redhat dot com>
- Cc: libstdc++ at gnu dot org
- Date: Wed, 27 Aug 2014 14:18:49 +0200
- Subject: Re: Experience with g++ 4.8 and -frepo?
- Authentication-results: sourceware.org; auth=none
- References: <87fvgi6xn5 dot fsf at fencepost dot gnu dot org> <20140827105915 dot GA22778 at redhat dot com>
Jonathan Wakely <jwakely@redhat.com> writes:
> On 27/08/14 12:21 +0200, David Kastrup wrote:
>>To my untrained eye that looks like the link exclusively fails on
>>libstdc++ with everything in the application getting resolved.
>>Obviously libstdc++-dev is installed in non-user-writable directories.
>
> But all the undefined references are templates that should be
> instantiated in your program, not in the libstdc++ library.
>
>>Are there known issue with that kind of setup? If -frepo supposed to
>>work? This is actually a rather big application, so it is an actually
>>small number of problems for a broken feature, but still the problems
>>are non-zero.
>
> I have no idea if it still works or if it's expected to work with
> libstdc++.
>
> https://gcc.gnu.org/onlinedocs/gcc/Template-Instantiation.html does
> say that "For library code, if you want the library to provide all of
> the template instantiations it needs, just try to link all of its
> object files together; the link will fail, ..." but I've never
> bothered using -frepo so don't know any more than what I've just read
> there.
>
>>Now -frepo is probably a non-starter here because of its impact on
>>compile time. It conceivably helps code size, however,
>
> How? If you let the compiler do implicit instantiation the duplicate
> code will be discarded at link-time.
>
>> and it _does_
>>make a difference regarding some problems with template specializations.
>
> Which problems?
./out/book.o: In function `Smob_base<Book>::unchecked_unsmob(scm_unused_struct*)':
/usr/local/tmp/lilypond/lily/book.cc:103: multiple definition of `Smob_base<Book>::type_p_name'
./out/book-scheme.o:(.data+0x0): first defined here
./out/grob.o: In function `Grob::do_break_processing()':
/usr/local/tmp/lilypond/lily/grob.cc:206: multiple definition of `Smob_base<Grob>::type_p_name'
./out/grob-smob.o:(.data+0x0): first defined here
./out/spring.o: In function `Smob_base<Spring>::unchecked_unsmob(scm_unused_struct*)':
/usr/local/tmp/lilypond/lily/spring.cc:39: multiple definition of `Smob_base<Spring>::type_p_name'
./out/spring-smob.o:(.data+0x0): first defined here
collect2: error: ld returned 1 exit status
make[1]: *** [out/lilypond] Error 1
make[1]: Leaving directory `/usr/local/tmp/lilypond/lily'
make: *** [all] Error 2
The problem I have here is to have a specialization
lily/grob-smob.cc:template <> const char * Smob_base<Grob>::type_p_name = "ly:grob?";
of
lily/include/smobs.hh:template <class Super>
lily/include/smobs.hh:class Smob_base
lily/include/smobs.hh:{
[...]
lily/include/smobs.hh:public:
lily/include/smobs.hh: static const char *type_p_name;
[...]
that is included from
lily/include/smobs.tcc-template <class Super>
lily/include/smobs.tcc:const char *Smob_base<Super>::type_p_name = 0;
and I am currently searching for the right incantation in order not to
get errors at link time for multiple and/or inconsistent definitions.
Amusingly, the link time error disappears if I use const char* const
rather than const char * everywhere, but the compiler then produces at
least in one compilation unit code where
template <class Super>
void Smob_base<Super>::init ()
{
[...]
if (type_p_name)
{
SCM subr = scm_c_define_gsubr (type_p_name, 1, 0, 0,
(scm_t_subr) smob_p);
string fundoc = string("Is @var{x} a @code{") + typeid (Super).name ()
+ "} object?";
ly_add_function_documentation (subr, type_p_name, "(SCM x)",
fundoc);
scm_c_export (type_p_name, NULL);
}
[...]
is optimized away since it apparently assumes that type_p_name is 0 and
does not see the specialization.
It's funny that I don't get a link time error then (I'd expect two
different expansions for Smob_base<Super>::init () under the assumption
that this is the same error I otherwise get to see at link time).
At any rate, I need to tell all compilation units that a specialization
exists, and of course I can only define it in one compilation unit. And
I was surprised that the respective incantations appear to exist only
starting with C++11, with GCC providing them in C++98 mode already.
I mean, template specializations are in C++ how long now? 20 years or
so? How did people manage before C++11?
At any rate, g++ -frepo appears to get me rid of that inconsistent
specialization problem at the cost of tripping up libstdc++ usage (which
never was problematic without -frepo). Sometimes I wonder whether I am
the only one using some software... But maybe -frepo was pretty new in
g++-4.8.
--
David Kastrup