FAQ

g++ fall down, go boom.

Michael G Schwern
Mar 7, 2000 at 6:31 pm
Hi, I'm here. I figured it can't hurt to subscribe since the volume
is so low. I'm sorry to say my first post is going to be a "hey, is
this thing supposed to work?" report.


schwern@athens:/usr/local/src/topaz-0.10$ make
g++ -g -pipe -frtti -Iegcs -I. -c test_buffer.cc
In file included from test_buffer.cc:1:
Buffer.hh: In function `static class Perl::Buffer::Guts * Perl::Buffer::Guts::PtrPolicy<Perl::Buffer::Guts>::init()':
Counted.hh:104: instantiated from `Perl::CountedPtr<Perl::Buffer::Guts,Perl::Buffer::Guts::PtrPolicy<Perl::Buffer::Guts> >::CountedPtr()'
Buffer.hh:36: instantiated from here
Buffer.hh:131: Internal compiler error.
Buffer.hh:131: Please submit a full bug report.
Buffer.hh:131: See <URL:http://www.gnu.org/software/gcc/faq.html#bugreport> for instructions.
make: *** [test_buffer.o] Error 1
schwern@athens:/usr/local/src/topaz-0.10$ g++ --version
2.95.2

Bang.

I guess this is a Very Bad Thing, but more for g++. Still, I figured
you guys should know. My knowledge of C++ is pretty poor, and my
knowledge of compiler internals is even worse so I'm not the person to
debug this. :(

So, any trivial, inconsequential features I could muck around with?

--

Michael G Schwern http://www.pobox.com/~schwern/ schwern@pobox.com
<purl> Hey, Schwern! THERE IS A HUGE GAZORGANSPLATTEDFARTMONGERING-
LIGHTENINGBEASTASAURSOPOD BEHIND YOU! RUN, BEFORE IT GAFLUMMOXES YOUR
INNARDLYBITS!
reply

Search Discussions

3 responses

  • Chip Salzenberg at Mar 7, 2000 at 7:20 pm

    According to Michael G Schwern:
    Buffer.hh:131: Internal compiler error.
    Yeah, that'll happen.

    The good news is that g++ is under intensive development by several
    really good programmers.

    The bad news is that their labor is currently available only via CVS.

    The other good news is that if you're using Linux on an Intel
    processor, you can grab a binary snapshot of g++ and libstdc++v3 from

    ftp://topaz.sourceforge.net/pub/topaz/

    The current filename is "egcs-20000216-i686-linux.tar.bz2". It
    expects to be installed in "/usr/local/egcs". I'll make another
    snapshot RSN.
    --
    Chip Salzenberg - a.k.a. - <chip@valinux.com>
    "I wanted to play hopscotch with the impenetrable mystery of existence,
    but he stepped in a wormhole and had to go in early." // MST3K
  • John Porter at Mar 7, 2000 at 10:06 pm

    Michael G Schwern wrote:

    schwern@athens:/usr/local/src/topaz-0.10$ make
    g++ -g -pipe -frtti -Iegcs -I. -c test_buffer.cc
    In file included from test_buffer.cc:1:
    Buffer.hh: In function `static class Perl::Buffer::Guts * Perl::Buffer::Guts::PtrPolicy<Perl::Buffer::Guts>::init()':
    Counted.hh:104: instantiated from `Perl::CountedPtr<Perl::Buffer::Guts,Perl::Buffer::Guts::PtrPolicy<Perl::Buffer::Guts> >::CountedPtr()'
    Buffer.hh:36: instantiated from here
    Yall might want to see what the smart guys on ACE have to say about
    template instantiation and how some compilers (such as "older" gcc)
    have trouble with it, at:

    http://www.cs.wustl.edu/~schmidt/ACE_wrappers/docs/tutorials/templates.html

    although the particular error they've hit doesn't seem to be quite
    the same as the one above.

    --
    John Porter

    Papa! Es un gringo en la calle con su coche!
  • Chip Salzenberg at Mar 7, 2000 at 10:15 pm

    According to John Porter:
    Yall might want to see what the smart guys on ACE have to say about
    template instantiation and how some compilers (such as "older" gcc)
    have trouble with it, at:

    http://www.cs.wustl.edu/~schmidt/ACE_wrappers/docs/tutorials/templates.html

    although the particular error they've hit doesn't seem to be quite
    the same as the one above.
    The G++ documentation has a detailed description of the various
    template-instantiation approaches that work with G++, and their
    advantages and disadvantages. Unfortunately, I don't think it's
    up on the web right now. Hence I shall misuse the list thusly:

    -------------------------------------------------------------------------
    @node Template Instantiation
    @section Where's the Template?

    @cindex template instantiation

    C++ templates are the first language feature to require more
    intelligence from the environment than one usually finds on a UNIX
    system. Somehow the compiler and linker have to make sure that each
    template instance occurs exactly once in the executable if it is needed,
    and not at all otherwise. There are two basic approaches to this
    problem, which I will refer to as the Borland model and the Cfront model.

    @table @asis
    @item Borland model
    Borland C++ solved the template instantiation problem by adding the code
    equivalent of common blocks to their linker; the compiler emits template
    instances in each translation unit that uses them, and the linker
    collapses them together. The advantage of this model is that the linker
    only has to consider the object files themselves; there is no external
    complexity to worry about. This disadvantage is that compilation time
    is increased because the template code is being compiled repeatedly.
    Code written for this model tends to include definitions of all
    templates in the header file, since they must be seen to be
    instantiated.

    @item Cfront model
    The AT&T C++ translator, Cfront, solved the template instantiation
    problem by creating the notion of a template repository, an
    automatically maintained place where template instances are stored. A
    more modern version of the repository works as follows: As individual
    object files are built, the compiler places any template definitions and
    instantiations encountered in the repository. At link time, the link
    wrapper adds in the objects in the repository and compiles any needed
    instances that were not previously emitted. The advantages of this
    model are more optimal compilation speed and the ability to use the
    system linker; to implement the Borland model a compiler vendor also
    needs to replace the linker. The disadvantages are vastly increased
    complexity, and thus potential for error; for some code this can be
    just as transparent, but in practice it can been very difficult to build
    multiple programs in one directory and one program in multiple
    directories. Code written for this model tends to separate definitions
    of non-inline member templates into a separate file, which should be
    compiled separately.
    @end table

    When used with GNU ld version 2.8 or later on an ELF system such as
    Linux/GNU or Solaris 2, or on Microsoft Windows, g++ supports the
    Borland model. On other systems, g++ implements neither automatic
    model.

    A future version of g++ will support a hybrid model whereby the compiler
    will emit any instantiations for which the template definition is
    included in the compile, and store template definitions and
    instantiation context information into the object file for the rest.
    The link wrapper will extract that information as necessary and invoke
    the compiler to produce the remaining instantiations. The linker will
    then combine duplicate instantiations.

    In the mean time, you have the following options for dealing with
    template instantiations:

    @enumerate
    @item
    Compile your template-using code with @samp{-frepo}. The compiler will
    generate files with the extension @samp{.rpo} listing all of the
    template instantiations used in the corresponding object files which
    could be instantiated there; the link wrapper, @samp{collect2}, will
    then update the @samp{.rpo} files to tell the compiler where to place
    those instantiations and rebuild any affected object files. The
    link-time overhead is negligible after the first pass, as the compiler
    will continue to place the instantiations in the same files.

    This is your best option for application code written for the Borland
    model, as it will just work. Code written for the Cfront model will
    need to be modified so that the template definitions are available at
    one or more points of instantiation; usually this is as simple as adding
    @code{#include <tmethods.cc>} to the end of each template header.

    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 cause the instantiations to be
    generated as a side effect. Be warned, however, that this may cause
    conflicts if multiple libraries try to provide the same instantiations.
    For greater control, use explicit instantiation as described in the next
    option.

    @item
    Compile your code with @samp{-fno-implicit-templates} to disable the
    implicit generation of template instances, and explicitly instantiate
    all the ones you use. This approach requires more knowledge of exactly
    which instances you need than do the others, but it's less
    mysterious and allows greater control. You can scatter the explicit
    instantiations throughout your program, perhaps putting them in the
    translation units where the instances are used or the translation units
    that define the templates themselves; you can put all of the explicit
    instantiations you need into one big file; or you can create small files
    like

    @example
    #include "Foo.h"
    #include "Foo.cc"

    template class Foo<int>;
    template ostream& operator <<
    (ostream&, const Foo<int>&);
    @end example

    for each of the instances you need, and create a template instantiation
    library from those.

    If you are using Cfront-model code, you can probably get away with not
    using @samp{-fno-implicit-templates} when compiling files that don't
    @samp{#include} the member template definitions.

    If you use one big file to do the instantiations, you may want to
    compile it without @samp{-fno-implicit-templates} so you get all of the
    instances required by your explicit instantiations (but not by any
    other files) without having to specify them as well.

    g++ has extended the template instantiation syntax outlined in the
    Working Paper to allow forward declaration of explicit instantiations
    and instantiation of the compiler support data for a template class
    (i.e. the vtable) without instantiating any of its members:

    @example
    extern template int max (int, int);
    inline template class Foo<int>;
    @end example

    @item
    Do nothing. Pretend g++ does implement automatic instantiation
    management. Code written for the Borland model will work fine, but
    each translation unit will contain instances of each of the templates it
    uses. In a large program, this can lead to an unacceptable amount of code
    duplication.

    @item
    Add @samp{#pragma interface} to all files containing template
    definitions. For each of these files, add @samp{#pragma implementation
    "@var{filename}"} to the top of some @samp{.C} file which
    @samp{#include}s it. Then compile everything with
    @samp{-fexternal-templates}. The templates will then only be expanded
    in the translation unit which implements them (i.e. has a @samp{#pragma
    implementation} line for the file where they live); all other files will
    use external references. If you're lucky, everything should work
    properly. If you get undefined symbol errors, you need to make sure
    that each template instance which is used in the program is used in the
    file which implements that template. If you don't have any use for a
    particular instance in that file, you can just instantiate it
    explicitly, using the syntax from the latest C++ working paper:

    @example
    template class A<int>;
    template ostream& operator << (ostream&, const A<int>&);
    @end example

    This strategy will work with code written for either model. If you are
    using code written for the Cfront model, the file containing a class
    template and the file containing its member templates should be
    implemented in the same translation unit.

    A slight variation on this approach is to instead use the flag
    @samp{-falt-external-templates}; this flag causes template
    instances to be emitted in the translation unit that implements the
    header where they are first instantiated, rather than the one which
    implements the file where the templates are defined. This header must
    be the same in all translation units, or things are likely to break.

    @xref{C++ Interface,,Declarations and Definitions in One Header}, for
    more discussion of these pragmas.
    @end enumerate
    -------------------------------------------------------------------------

    --
    Chip Salzenberg - a.k.a. - <chip@valinux.com>
    "I wanted to play hopscotch with the impenetrable mystery of existence,
    but he stepped in a wormhole and had to go in early." // MST3K
Discussion Navigation
viewthread | post