Take the 2-minute tour ×

The following source code compiles correctly with Visual Studio 2010:

namespace NS
   class X
   X Y(X str);

void myFun()
   NS::X x;

(this is reduced code where all my own class and function names have been replaced by X, Y, ...)

I would expect that the line Y(x) would fail to compile, since it should be NS::Y(x).

This source code is compiled with the following command

cl /c file.cpp

There are no other files included here, no other command line options.

Why does this file compile? Bug in VS2010? Or something that I (and my 3 other colleagues) overlooked?

share|improve this question
tried this with g++ and got undefined reference to NS::Y(NS::X)' - so maybe it might be a bug in VS.. –  WeaselFox Mar 22 '12 at 9:53
ideone.com/WzC6V –  Ivaylo Strandjev Mar 22 '12 at 9:59
@WeaselFox: completely unrelated. Your error is a linker error because NS::Y is not defined. It is typical, and would probably be defined in another file on a complete setup. –  Matthieu M. Mar 22 '12 at 10:52
@MatthieuM. - yeah, I realize this, thanks. –  WeaselFox Mar 22 '12 at 11:33
add comment

2 Answers

up vote 9 down vote accepted

What you are experiencing is due to ADL (Argument Dependent Lookup).

There is nothing wrong with your snippet (besides the fact that the linker will probably complain about NS::Y isn't defined), but it should compile - VS2012 is handling the snippet as it should.

The compiler will find NS::Y due to the fact that the type of parameter x (NS::X) is in the appropriate scope.

3.4.2 Argument-dependent name lookup [basic.lookup.argdep]

  1. When an unqualified name is used as the postfix-expression in a function call (5.2.2), other namespaces not considered during the usual unqualified lookup (3.4.1) may be searched, and in those namespaces, namespace-scope friend function declarations (11.4) not otherwise visible may be found.

    These modifications to the search depend on the types of the arguments (and for template template arguments, the namespace of the template argument).

  2. For each argument type T in the function call, there is a set of zero or more associated namespaces and a set of zero or more associated classes to be considered.

    The sets of namespaces and classes is determined entirely by the types of the function arguments (and the namespace of any template template argument).

share|improve this answer
You're right, I just also found it on Wikipedia. Tricky. I didn't expect this to work. –  Patrick Mar 22 '12 at 10:00
So is it a bug in MSVS or gcc? –  Luchian Grigore Mar 22 '12 at 10:01
@LuchianGrigore There is no bug, the snippet compiles. The linker just can't find the definition of NS::Y. There are several steps when building an executable. –  Filip Roséen - refp Mar 22 '12 at 10:03
@LuchianGrigore Neither. MSVC is not erroring as it is only compiling to an object file. The g++ error is coming from the linker, not the compiler. –  Michael Anderson Mar 22 '12 at 10:04
Oh, my bad, I though it compiled with MSVS and not gcc. Totally misunderstood the question. The linker error was obvious, not what I had doubts about. –  Luchian Grigore Mar 22 '12 at 10:06
add comment

It is valid C++ code. It is compiled since argument-dependent lookup applies here.

share|improve this answer
add comment

Your Answer


