Processing of uninstantiated template functions
Asked Answered
G

1

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?

Garbe answered 23/7, 2014 at 6:46 Comment(4)
In either way, malformed code is still malformed code.Bursa
So I guess my question could be reworded: Is this malformed code? Or is the compiler allowed not to parse uninstantiated template definitions?Garbe
@Garbe What happens if you write return static_cast<int>(CCodes::blah);?Gleam
My bad missing the return, but the result is the same. I've edited the question to reflect this.Garbe
S
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.
Somite answered 23/7, 2014 at 7:4 Comment(6)
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.Lenin
@Lenin 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).Somite
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.Garbe
@Garbe 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.Somite
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.Garbe
Not to mention the portability implications!Garbe

© 2022 - 2024 — McMap. All rights reserved.