[cfe-dev] Warn on template def after explicit instantiation?

John McCall rjmccall at apple.com
Fri Jan 4 16:53:39 PST 2013


On Jan 4, 2013, at 4:44 PM, "Robinson, Paul" <Paul.Robinson at am.sony.com> wrote:

> A client ran into the following situation. Suppose we have this:
> 
>  // Declarations from a header file.
>  template <class T> SomeTemplate {
>  public:
>    void Init();
>  };
>  class FooBar { };
>  // End of the header file.
> 
>  // Here's the initial source module.
>  // Explicitly instantiate SomeTemplate.
>  template SomeTemplate<FooBar>;
>  // Oops, forgot to define Init().
>  template <class T> SomeTemplate<T>::Init() { }
>  // Now we use the stuff.
>  SomeTemplate<FooBar> Obj;
>  void foo() {
>    Obj.Init();
>  }
> 
> This built cleanly. But, moving Obj and foo() to another source file
> caused a link-time error, because of an undefined reference to
> SomeTemplate<FooBar>::Init().  (Call this "version 2.")
> 
> The client understands that the original module worked because
> "Obj.Init()" implicitly instantiated SomeTemplate<FooBar>::Init() as a
> definition, because the template definition existed in the same
> compilation unit. And moving the same code to a separate module
> implicitly instantiated Init() as a declaration, because that's all 
> that was in the header file.  The "template SomeTemplate<FooBar>;"
> didn't instantiate a definition of Init() because that definition hadn't
> happened yet; hence, the link-time error. The fix was to move the
> explicit instantiation down past the template method definitions.
> (Call that one "version 3.")
> 
> His question is: Can we have a warning for the situation where a
> template definition of a method follows an explicit instantiation of
> its containing class?  (Or maybe, if a template definition follows an
> explicit instantiation of its declaration?)  He argues that while it's
> well-defined by the standard, it's probably a mistake on the
> programmer's part (as it was for his code), and a compile-time
> diagnostic would have made it a lot easier to figure out.

I'd be skeptical of such a warning.  It's certainly reasonable for a
user who's decided to play careful explicit-instantiation games to
be intentionally defining a member after the explicit instantiation
to avoid the instantiation of a particular member.  That makes it
hard to justify this warning being default-on — and I can't
really imagine it doing much good being default-off.

John.



More information about the cfe-dev mailing list