7

The following code compiles in Visual C++ 2013 but not under G++ 4.8.2:

template<class T>
int MyFunc(T& t)
{
    return static_cast<int>(CCodes::blah);
}

template<>
int MyFunc(float& t)
{
    return 0;
}

int main() {
    float f = 10.f;
    return MyFunc(f);
}

Visual C++ seems to ignore the general template function because only the specialisation MyFunc<float> is used. G++ parses the general function anyway and spots that the CCodes enumeration has not been defined.

Which is right? Or is this implementation-defined?

Tom
  • 7,269
  • 1
  • 42
  • 69

1 Answers1

8

GCC is correct, and every other compiler besides MSVC will do the same thing.

This is a major bug, which actually appeared on one MSVC future roadmap. It was in the "distant future" category. They will have to rewrite their template engine to fix it.

There is a line of argument that diagnosis of an ill-formed template is optional, because it's really a template with no well-formed instantiation, and those are not required to be flagged. However,

  1. The standard requires the template to be parsed, and failure to parse must be diagnosed regardless of instantiation.
  2. Every other compiler makes the diagnosis, so in effect not doing so leads MSVC users to produce unportable code. Complaining is a really good idea, even if it's not required.
Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
  • Hmm, §14.6 [temp.res]/p10 says "If a name does not depend on a template-parameter (as defined in 14.6.2), a declaration (or set of declarations) for that name shall be in scope at the point where the name appears in the template definition". Unlike the general "no valid specialization" rule, there's no "no diagnostic required" attached to this. – T.C. Jul 23 '14 at 07:14
  • @T.C. Right. Since C++ is a context-sensitive (not context-free) grammar, name lookup needs to be performed as part of parsing. This is part of what I meant by (1). – Potatoswatter Jul 23 '14 at 07:15
  • Actually the situation is somewhat worse than that - you can literally put almost any garbage in the body of an uninstantiated template function and the VC++ compiler will ignore it. So long as it doesn't contain the closing brace and doesn't upset the preprocessor, it seems it doesn't matter. – Tom Jul 23 '14 at 12:38
  • @Tom Yes, this is the conventional meaning of "parsing" and that's the remainder of what I meant by (1). Examples which are just line noise make the "optional diagnosis" justification harder to believe, but it had (and may still have) its proponents. – Potatoswatter Jul 23 '14 at 22:52
  • I'd have thought the maintainability implications were both obvious and horrendous - a template function can sit in a library, apparently compiling happily for years so long as no-one uses it. As soon as it gets used, the library has apparently "developed" a bug on its own. Who knows whether the person who wrote the code still works here, or ever worked here. – Tom Jul 24 '14 at 00:29
  • Not to mention the portability implications! – Tom Jul 24 '14 at 00:30