This is the mail archive of the gcc-patches@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]
Other format: [Raw text]

Re: [Darwin] Patch c++/15428



On May 20, 2004, at 10:34 AM, Jason Merrill wrote:


On Wed, 19 May 2004 16:54:11 -0700, Matt Austern <austern@apple.com> wrote:

*************** do_type_instantiation (tree t, tree stor
*** 10789,10795 ****
          get unresolved symbols at link time. */

       explicitly_instantiate_members =
!       TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY
         && previous_instantiation_extern_p && ! extern_p
         && ! TYPE_FOR_JAVA (t);

--- 10789,10795 ----
          get unresolved symbols at link time. */

       explicitly_instantiate_members =
!       !TARGET_WEAK_NOT_IN_ARCHIVE_TOC
         && previous_instantiation_extern_p && ! extern_p
         && ! TYPE_FOR_JAVA (t);

Why are/were you checking the macro here?

It's the general rule: on Darwin, you should never make something weak unless you know that it will be emitted in every translation unit where it will be used. If something is weak, but is only emitted in one translation unit, then in the presence of static archives you'll get unresolved symbols.


The case where this matters: you've got an explicit instantiation of an extern template. Remember, extern templates are a GNU extension that syntactically looks like a template instantiation. It tells the compiler: don't do this particular instantiation implicitly, even if you think you need to, because I promise I'll have an explicit instantiation somewhere else.

OK, so here' s a specific code example. Suppose we have a header file x.h with the following declarations:
template <typename T> struct X { void foo(); };
template <typename T> void X<T>::foo() { };
extern template struct X<int>;


Now we include that header file into two source files, a.cc and b.cc. In a.cc we use X<int>::foo(), but we don't have an explicit instantiation. In b.cc we do have an explicit instantiation. a.o will have an unresolved reference to _ZN1XIiE3fooEv, which is expected to be defined elsewhere. b.o will have a definition.

The point is that we need to make sure that the definition of _ZN1XIiE3fooEv in b.o isn't weak. So we do two things. First, we do explicit instantiations, not implicit, for member functions of explicitly instantiated class templates. (Arguably that's what the standard calls for anyway; as you may have noticed from the reflector thread, John Spicer thinks so.) Second, we make explicit instantiations ordinary symbols, not weak. This is acceptable, because you only need weak symbols when you might have more than one definition, and the standard says that you may not have more than one explicit instantiation in a program. It mean that gcc on Darwin violates the Itanium C++ ABI specification, but that's OK too. There are lot of platforms where we have to make ABI compromises.

I actually mentioned this in the comment just above the code fragment that you quoted. I'm not quite sure how I could modify the comment to be clearer without getting too verbose. Any suggestions?

--Matt


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