Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-existing identifier used as default argument in non-instantiated function template

Today I found a piece of code equivalent to the following:

enum X
{
    x1 = 0,
    x2 = 1
};

template<typename T>
void bar(T obj, X x = x3) { }
//                    ^^
//                    This identifier is bogus!

int main() { }

Both VC10 and VC12 happily compile it. Both clang 3.4 and GCC 4.8.1 reject it (which is what I would expect).

Is this a bug, or is VC's behavior actually allowed by the Standard? If so, which are the relevant paragraphs?

like image 408
Andy Prowl Avatar asked Feb 05 '14 15:02

Andy Prowl


1 Answers

It's a well-known fact that VC doesn't have two-phase lookup. That means it accepts all sorts of bogosity in templates, as long as it at least looks like syntactically valid C++ and it is not actually instantiated.

This is just one more of those instances.

As you can see in their conformance roadmap, two-phase lookup is planned for sometime after the post-RTM CTP, which I guess would mean you will have access to it after you pay for the next iteration of the Visual Studio suite.

As for the Standard references, 14.6/9-10 say:

When looking for the declaration of a name used in a template definition, the usual lookup rules (3.4.1, 3.4.2) are used for non-dependent names. [...]

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.

like image 164
R. Martinho Fernandes Avatar answered Nov 15 '22 15:11

R. Martinho Fernandes