This is the mail archive of the 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: Missing concept check instantiations when optimizing

On Fri, Jun 27, 2003 at 04:15:08PM -0300, Brad Spencer wrote:

[Worries about concept-inst.o missing symbols . . .]

> Sure enough, it appears that the command lines are
> _different_ when I run things in these two ways.  The 16-symbol
> (broken) object's build line contains "-g -O2", while the 156-symbol
> (ok?) object's build line has neither.  Removing "-g" had no effect,
> but removing the "-O2" flag brought in all 156 symbols.  Uh-oh.  Going
> to "-O3" brought the count down to 14.

Yes, I'm replying to myself, but I think I've identified the core
issue here.  Consider this small program.  It contains the technique
that drives much of the concept checks (taking a pointer to a member
in an inline function, marking that pointer as being unused, and then
not using it).

  template<typename _Test>
  class X
    void x() {}

  template<typename _Test>
  void f()
    void (X<_Test>::* x)() __attribute__ ((__unused__)) = &X<_Test>::x;

  template<typename _Test>
  void g() { f<_Test>(); }

  template void g<float>();
Compiling this with either the sparc-sun-solaris2.8 cross compiler (on
i686-pc-linux-gnu) or with the i686-pc-linux-gnu natively gives
interesting results.

$ g++ -Wall -O0 -fimplicit-templates -c -o a.o
$ nm a.o
a.o:00000000 W void f<float>()
a.o:00000000 W void g<float>()
a.o:00000000 W X<float>::x()

Ok, all symbols are there, even if implicitly used.  This corresponds
with what the documentation for -fno-implicit-templates says: "Never
emit code for non-inline templates which are instantiated implicitly
(i.e. by use); only emit code for explicit instantiations."  We have
implicitly used X<float>, so it was instantiated. 

Now, turn on the optimizer:

$ g++ -Wall -O2 -fimplicit-templates -c -o a.o
$ nm a.o
a.o:00000000 W void f<float>()
a.o:00000000 W void g<float>()

It appears that the optimizer has decided that X<float> really isn't
used and therefore it has not instantiated it implicitly, and so
-fimplicit-templates does not emit it in the object file!  Funnily
enough, this is exactly the behaviour we would want in order to prevent
the concept checks from growing object size and so on.  However, it
also means that the -fimplicit-templates trick used to compile will only work if the library and user code are
compiled with the same optimizations.  I have not tested this last
claim, but consider a.o to be optimized library code linked against a
non-optimized user code b.o that assumes X<float> exists somewhere. 

The question I have is whether the compiler is allowed to consider
X<float> as not being implicitly instantiated or not, given the impact
that has on the symbols emitted!  Perhaps the compiler needs to emit
the instantiation anyway even if no code is generated to use it?
Should I submit a compiler bug report, or should we bring this up on
the gcc list?  Or is it libstdc++'s problem, assuming too much about
the power of -fimplicit-templates?

Brad Spencer - - "It's quite nice..."
Systems Architect | InfoInterActive Corp. | A Canadian AOL Company

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