[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