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

Robinson, Paul Paul.Robinson at am.sony.com
Fri Jan 4 17:58:48 PST 2013



________________________________________
> From: John McCall [rjmccall at apple.com]
> 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.

It's true that a template-savvy coder could devise something where some
methods did not exist for certain specializations.  But...
I should think the more common use-case is somebody porting code from
MSVC or other less-careful compiler to Clang, and running into this
unintentionally.

As a parallel example, Clang now complains if I fail to parenthesize
expressions with multiple operators where it thinks I might not be
getting the precedence right.  This is not exactly expert-friendly
either.  I think this is another example in the same vein.
--paulr




More information about the cfe-dev mailing list