Does the anonymous namespace enclose all namespaces? - c++

In C++ you specify internal linkage by wrapping your class and function definitions inside an anonymous namespace. You can also explicitly instantiate templates, but to be standards conforming any explicit instantiations of the templates must occur in the same namespace. AFAICT this should compile, but GCC fails on it:
namespace foo {
template<class T>
class bar {};
}
using namespace foo;
namespace {
template class bar<int>;
}
int main()
{
return 0;
}
With the error:
namespace_test.cpp:11: error: explicit instantiation of 'class bar<int>' in namespace '<unnamed>' (which does not enclose namespace 'foo')
Which is interesting because the anonymous namespace should just be specifying linkage, not really functioning as a namespace, and the global namespace definitely encloses foo, since it encloses every namespace. But even this doesn't work!:
template<class T>
class bar {};
using namespace foo;
namespace {
template class bar<int>;
}
int main()
{
return 0;
}
Which fails with the same error, just listing the global namespace instead:
namespace_test.cpp:11: error: explicit instantiation of 'class bar<int>' in namespace '<unnamed>' (which does not enclose namespace '::')
:/

An anonymous namespace is logically equivalent to
namespace _TU_specific_unique_generated_name
{
// ...
}
using namespace _TU_specific_unique_generated_name;
A namespace, anonymous or otherwise, has no effect on the linkage of its members. In particular members of an anonymous namespace do not magically get internal linkage.

First: You are explicitly instantiating a class template, you are not defining a new class template. What
template class bar<int>;
says is "please instantiate the class template bar for type int here". You cannot do that in another namespace, just as you cannot partially specialise a class template in another namespace. In particular, the template to be explicitly instantiated must have been defined, and in your example, there's no (anonymous namespace)::bar<>, only foo::bar<>.
Second: The anonymous namespace is a real namespace (it's distinct in every translation unit, though). It also doesn't magically change linkage. Everything declared inside namespace {} has still the default linkage, just like at any other namespace scope. IIRC, it was even added to allow for translation unit-private, yet external-linkage objects.

I think you have your answer - anonymous namespaces are distinct, unique namespaces. BTW, the compiler generates some random large integer to represent that namespace internally.

According to Stroustrup (section 8.2.5.1) the global namespace has access to the anonymous (unnamed) namespace, but it doesn't explicitly say the converse.
I expect you'd have to specify the namespace with a using statement or fully qualify references to other namespaces inside the unnamed namespace...

Related

Why do I have to qualify the namespace for a function passed a typedef of the functions templated parameter type?

In this example why do I need to qualify the function call B::F() with its namespace? As the typedef of QF should match the type Q as I thought it was an alias for it, not really a new type?
Is there an elegant way around this that doesn't require a using statement in every function body?
namespace A
{
template<class T> struct V {};
template<class T> struct Q {};
typedef Q<float> QF;
template<class T>
inline void F(V<T> v) {}
namespace B
{
template<class T>
inline void F(Q<T> q) {}
}
namespace C
{
void Test();
}
}
using namespace A;
using namespace A::B;
void A::C::Test()
{
QF q;
// using namespace A::B; // Uncomment will work
F(q); // Error, tries A::F() and can't find B::F()
B::F(q); // Ok it uses B::F() as intended
}
int main()
{
return 0;
}
I'll try to show in what ways clang interprets the draft differently than gcc and msvc. When you call F(q) inside the definition of void A::C::Test(), the compiler tries to look up the name F in the scopes in which that call is made, and will stop looking for larger scopes as soon as that name (name, not particular overload) is found. The body of void A::C::Test() is inside the namespace C which is inside A which is inside the global namespace. So when you write the using directive in the global scope, the relevant passage in the standard [basic.lookup.unqual]:
In all the cases listed in [basic.lookup.unqual], the scopes are searched for a declaration in the order listed in each of the
respective categories; name lookup ends as soon as a declaration is
found for the name. If no declaration is found, the program is
ill-formed.
The declarations from the namespace nominated by a using-directive become visible in a namespace enclosing the using-directive; see
[namespace.udir]. For the purpose of the unqualified name lookup rules
described in [basic.lookup.unqual], the declarations from the
namespace nominated by the using-directive are considered members of
that enclosing namespace.
by point 2 implies that the name F (coming from A::B::F) is visible as if it was declared in the global scope, but by point 1 name lookup will find a name F sooner, in namespace A and will not look further. So it only finds void F(V<T> v) and this declaration is not fit for the call.
The more interesting story is with the using directive put inside the body of the function. The difference in approach is whether the definition of void A::C::Test() (which is also a declaration) appears in the global namespace or in namespace A::C. If you take the view that this is the global namespace (as clang apparently does), then the namespace enclosing the using-directive written inside the function is the global namespace and we are back to the explanation above. But if you believe that it appears in namespace A::C, then you bring in (among others) the declaration of void F(Q<T>) into A::C and regular lookup finds it.
A bonus observation is why you would still be able to call F(V<double>{}) since now the declaration void F(Q<T>) is in a narrower scope - and the answer is argument-dependent lookup, the namespace where V<T> is declared is going to be looked at too.
That's a story to scare the learner, but if you want practical guidance, do not use the shortcut with namespaces, use
namespace A::C
{
void Test()
{
...
}
}
so that the namespace in which it is declared is not subject to debate and put using namespace A::B; either in namespace scope or in function scope.
(And I'll try to figure out what was the real intended scope of the void A::C::Test() declaration-definition with wiser people).

Class member function defined outside its namespace

The following code compiles perfectly with the latest MSVC, GCC and CLang available at godbolt online compiler explorer site. I wonder why:
namespace ns
{
struct Test
{
void foo();
};
}
using namespace ns;
// Alert! Member function defined outside its namespace!
void Test::foo()
{
}
int main()
{
ns::Test obj;
obj.foo();
return 0;
}
cppreference claims that if a member function is defined outside its class, then it must be defined at the namespace of that class. See the very top of the cppreference page about member functions.
But still, the compilers accept the code. It's really unlikely that all three independent compilers have the same bug, right? So, is there a good reason behind them accepting such code?
12.2.1 Member functions [class.mfct]
A member function may be defined (11.4) in its class definition, in which case it is an inline member function (10.1.6), or it may be defined outside of its class definition if it has already been declared but not defined in its class definition. A member function definition that appears outside of the class definition shall appear in a namespace scope enclosing the class definition.
This does not mean the definition must appear in the immediately surrounding scope. It can appear in any enclosing namespace, even if that is several layers up.
However, this would be illegal:
namespace a {
struct X {
void Y();
};
}
namespace b { // not an enclosing namespace
void X::Y()
{
std::cout << "Do a thing!\n";
}
}
Quoting C++17 (n4659) 12.2.1 [class.mfct]/1:
A member function definition that appears outside of the class definition
shall appear in a namespace scope enclosing the class definition.
This means it must be defined in the namespace which contains the class, or any parent namespace of that namespace. In your case, it's defined in the global namespace, which does indeed enclose (indirectly) the class definition.
using namespace ns;
5) using-directive: From the point of view of unqualified name lookup of any name after a using-directive and until the end of the scope in which it appears, every name from ns_name is visible as if it were declared in the nearest enclosing namespace which contains both the using-directive and ns_name.
It means that in the current scope ns can be omitted from addressing something inside that namespace.
As such when you write this code:
using namespace std;
vector<string> vectorofstrings;
You don't have to write
std::vector<std::string> vectorofstrings;
The namespace of a class is the name of the class. So if you have:
namespace aNamespace{
class aClass{
int aMember;
void aFunction();
};
}
Then the fully qualified lookup is ::aNamespace::aClass and a function must be defined as being part of void ::aNamespace::aClass::aFunction(){}

Why can't I forward-declare a type in a qualified namespace in C++?

I am trying to avoid including an auto-generated header (outside of my control), from inside my own headers. I therefore need to forward-declare a type Type that lives inside a namespace nm, which itself lives in the global namespace. Here is an example of MyHeader.h:
// My project defines two levels of nested namespaces
namespace foo { namespace bar {
namespace nm { struct Type; }
...
} }
Unfortunately this defines the new namespace foo::bar::nm and forward-declares the type foo::bar::nm::Type, which is not what I want. Ideally I would be able to forward-declare a type in the qualified namespace ::nm like this:
namespace foo { namespace bar {
namespace ::nm { struct Type; }
...
} }
My compiler complains I cannot use a qualified namespace here (using Intel ICC15 with C++11 settings). This forces me to put all such forward declarations at the beginning:
namespace nm { struct Type; }
namespace foo { namespace bar {
...
} }
In my case, this is inconvenient because I need to forward-declare many types and would prefer to do so alongside definitions of my own in various scattered places in my header. A workaround could be to constantly be "closing" and "re-opening" my nested namespace, which is not ideal.
Why can't I forward-declare a type in a qualified namespace ?
Because the C++ standard says so.
There is no real reason I know of. This is just not supported, probably, no one needed it and no one ever requested it. I see the benefit in your particular case, but since the forward declarations are expected to be provided in a separate file, you'd be better off by simply creating your own *_fwd.h with all the forward declarations inside it in the single namespace.
You can't because it's ambiguous. If you wrote:
extern int foo::bar;
Are you forward declaring an int named bar in namespace foo, or are you forward declaring an int named bar inside the class foo? There's no way for the compiler to know.

What does using mean in c++?

Like :
using ::size_t; using ::fpos_t; using ::FILE;
In fact it's a question inspired by the comment under this question:
When is .h not needed to include a header file?
This is called using declaration. There are actually two ways you can use the using keyword. There is a third special form of using declarations used inside class definitions, but i'll focus on the general using declaration here. (see below).
using declaration
using directive
These have two very different effects. A using declaration declares a name to be an alias to another declaration or a set of declarations (if you were to name a set of overloaded functions). The name is declared in the current scope. That is, you can use it inside blocks too
int main() {
using std::swap;
// ...
}
This is quite useful if you use a name very often locally and you don't want to prefix it in all uses, and it's also useful in implementing the swap using argment dependent lookup idiom.
A using directive names a namespace and does not declare any names. Instead it will modify name lookup to find names that aren't really declared where it thinks they are. For unqualified name lookup, it find names declared in the enclosing namespace that encloses both the using directive and the target namespace. All names that are declared in the target namespaces will be found:
int cout;
int main() {
using namespace std;
// cout << 1; ambiguous!
}
Here, cout will be thought as being declared twice in the global namespace, and causes an ambiguity (:: encloses both main and std). In qualified namelookup, it will build the transitive closure of a namespace with all the namespaces named in using directives.
using namespace foo;
int main() {
::c++;
}
c is not only looked up in the global namespace, but also in the namespace foo and in the namespaces that foo has using directives for and so on. If however the global namespace would contain a direct declaration (including a using declaration), that declaration will hide the declarations found indirectly by using directives:
using namespace foo;
int c;
int main() {
::c++; // not ambiguous!
}
Using declarations can appear in many places, including inside class definitions. Its meaning is similar to its meaning otherwhere with an important restriction: It declares a name to be an alias to one or more declarations, but the declarations must be members of a base class. This is very useful for making names visible in a derived class that would otherwise be hidden by the same name declared there
struct base {
void f();
};
struct derived : base {
using base::f; // name "f" declared in derived
void f(int); // overloads the using declaration
};
Now you can call d.f(). If there were no using declaration, then name lookup would only find one declaration of f in derived and stop lookup, not delving into the base class scope:
derived d;
d.f(); // invalid without the using declaration
d.f(0); // valid with or without the using declaration
// explicitly starting lookup in base: valid with or without the using declaration
d.base::f();
It also allows to change the accessibility of base-class members, although you should use that sparingly :)
In practice, i found it useful for making virtual member function re-visible:
struct base {
virtual void f();
virtual void f(int);
};
struct derived : base {
// using base::f; would solve it
virtual void f() { ... }
};
Oops - now d.f(0); is invalid because name lookup only finds the zero parameter f! The using directive would solve it. Notice that if you alias a function declaration that has the same parameter types and constness as an explicit declaration (like f() in this case), then the explicit declaration will still hide the one that the using declaration is an alias for - so both f() functions won't conflict in this case.
An alternative to solve this is using the non-virtual interface idiom
struct base {
void f() { do_f(); }
void f(int) { do_f(0); }
private:
virtual void do_f();
virtual void do_f(int);
};
struct derived : base {
private:
virtual void do_f() { ... }
};
struct derived1 : derived {
private:
virtual void do_f(int) { ... }
};
Now, both d.f(0) and d.f() are valid no matter on what object you call it.
Unfortunately the example you're looking at is obscure.
using ::_Filet;
As others have noted, the using declaration makes a name from the specified namespace available in the current namespace. In that file there appear to be no namespaces opened, so you'd assume the current namespace is the global namespace, and also the :: with nothing before it addresses the global namespace. So here we seem to be moving a name from the global namespace into the global namespace. What's up with that?
The answer is in the use of a macro:
_STD_BEGIN
This is defined as namespace std {. So what the using declarations are doing is making those names appear in the std namespace, where otherwise they would only be in the global namespace.
using <some symbol> pull a symbol from its namespace into the current namespace. Assume the following code:
namespace foo {
// Assume you want to use std::string, you can either do
std::string bar;
// or
using std::string;
string bar;
}
As you can see, you can either qualify the symbol using its namespace (first line of code) or the second way. For symbols you use quite often, pulling them into the namespace tends to make the code a little more readable but if you have a conflict (say, foo contains a string class of its own which is bad practise but might happen), qualifying it with the appropriate namespace will allow you to resolve the conflict.
The namespace :: is a special case as it refers to the global namespace; in this particular case, the functions you're referring to are C functions and C doesn't know about C++ namespaces, so they end up in the global namespace.
Namespaces in C++ are a very powerful mechanism to avoid symbol naming clashes and I'd strongly encourage any C++ programmer to use them.
The 'using' keyword allows you to bring names from a namespace into the current namespace.
If you would like to use a name inside a namespace without bringing them into your current namespace, you would have to use the <namespace name>::<name> format, as in the following:
std::cout &lt&lt "Hello World";
If cout is brought into the current namespace, then you can use it like below:
cout &lt&lt "Hello World";
The using keyword can be used the following ways:
As a using directive (using namespace <namespace name>;):
using namespace std;
This brings all names inside the std namespace into the current namespace.
As a using declaration (using <namespace>::<member name>;):
using std::cout;
This brings only the std::cout name into the current namespace.
using makes a name from the specified namespace available in the current namespace.

Is there a shorter way to forward declare a class in a namespace?

I can forward declare a function in a namespace by doing this:
void myNamespace::doThing();
which is equivalent to:
namespace myNamespace
{
void doThing();
}
To forward declare a class in a namespace:
namespace myNamespace
{
class myClass;
}
Is there a shorter way to do this? I was thinking something along the lines of:
class myNamespace::myClass;
No, however with a little reformatting
namespace myNamespace { class myClass; }
isn't much worse than
class myNamespace::myClass;
I've wanted to do the same thing before - it's not allowed. A namespace member must be declared in a namespace-body. They can only be "referred to" using the scope resolution operator.
See 3.3.5 "Namespace scope" in the standard.
Entities declared in a namespace-body are said to be members of the namespace, and names introduced by these declarations into the declarative region of the namespace are said to be member names of the namespace.
and
A namespace member can also be referred to after the :: scope resolution operator (5.1) applied to the name of its namespace or the name of a namespace which nominates the member’s namespace in a using-directive;
I don't think so.