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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Experience with g++ 4.8 and -frepo?


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


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