Is It a Good Idea to Wrap an #Include in a Namespace Block

Is it a good idea to wrap an #include in a namespace block?

No, it’s a bad idea. With C++ declarations, it's likely to introduce linker errors as identifiers get declared in the wrong namespace. With C declarations, it works, but it may hide clashes between identifiers in the global namespace (which you were trying to avoid, I guess) until link time; it doesn't really put the identifiers in a namespace.

A better idea would be to put your own identifiers in a namespace and avoid defining anything but main in the global one.

shielding #include within namespace { } block?

Just think of #including as copying and pasting the contents of the included file to the position of the #include directive.

That means, yes, everything in the included file will be inside the namespace.

#includes within a namespace, to embed prewritten stuff in namespace

I know this is an old question, but I want to give a more detailed answer anyway. Also, give a real answer to the underlying problem.

Here's just a few things that can go wrong if you include a header from within a namespace.

  1. The header includes other headers, which are then also included from within the namespace. Then a different place also wants to include these headers, but from outside the namespace. Because the headers have include guards, only one of the includes actually goes in effect, and the actual namespace of the stuff defined in the headers suddenly subtly depends on the order you include other headers.

  2. The header, or any of its included headers, expects to be in the global namespace. For example, standard library headers will very often (in order to avoid conflicts) refer to other standard stuff (or implementation details) as ::std::other_stuff, i.e. expect std to be directly in the global namespace. If you include the header from within a namespace, that's no longer the case. The name lookup for this stuff will fail and the header will no longer compile. And it's not just standard headers; I'm sure there are some instances of this e.g. in the Boost headers too.

  3. If you take care of the first problem by ensuring that all other headers are included first, and the second problem by making sure no fully qualified names are used, things can still go wrong. Some libraries require that other libraries specialize their stuff. For example, a library might want to specialize std::swap, std::hash or std::less for its own type. (You can overload std::swap instead, but you can't do that for std::hash and std::less.) The way to do this is close your library-specific namespace, open namespace std, and put the specialization there. Except if the header of the library is included in arbitrarily deeply nested namespaces, it cannot close those namespaces. The namespace std it attempts to open won't be ::std, but ::YourStuff::std, which probably doesn't contain any primary template to specialize, and even if it did, that would still be the wrong thing to do.

  4. Finally, things in a namespace simply have different names than things outside. If your library isn't header-only but has a compiled part, the compiled part probably didn't nest everything in the namespace, so the stuff in the library has different names than the stuff you just included. In other words, your program will fail to link.

So in theory, you can design headers that work when included within a namespace, but they're annoying to use (have to bubble up all dependencies to the includer) and very restricted (can't use fully qualified names or specialize stuff in another library's namespace, must be header-only). So don't do it.

But you have an old library that doesn't use namespaces, and you want to update it to use them without breaking all your old code. Here's what you should do:

First, you add a subdirectory to your library's include directory. Call it "namespaced" or something like that. Next, move all the headers into that directory and wrap their contents in a namespace.

Then you add forwarding headers to the base directory. For each file in the library, you add a forwarder that looks like this:

#ifndef YOURLIB_LEGACY_THE_HEADER_H
#define YOURLIB_LEGACY_THE_HEADER_H

#include "namespaced/the_header.h"
using namespace yourlib;

#endif

Now the old code should just work the way it always did.

For new code, the trick is not to include "namespaced/the_header.h", but instead change the project settings so that the include directory points at the namespaced subdirectory instead of the library root. Then you can simply include "the_header.h" and get the namespaced version.

should we move #include into namespace?

You must not include <iostream> inside your namespace. You will get linker errors.

I would not suggest including any headers within a namespace.

The only exception would be where you have a header which defines only extern "C" functions (and no C++ functions or classes), you can usually include that in a namespace without causing linker problems. But it is still probably not a good idea.

Is it OK to put a standard, pure C header #include directive inside a namespace?

No, the solution that you are considering is not allowed. In practice what it means is that you are changing the meaning of the header file. You are changing all of its declarations to declare differently named functions.

These altered declarations won't match the actual names of the standard library functions so, at link time, none of the standard library functions will resolve calls to the functions declared by the altered declarations unless they happen to have been declared extern "C" which is allowed - but not recommended - for names which come from the C standard library.

ISO/IEC 14882:2011 17.6.2.2/3 [using.headers] applies to the C standard library headers as they are part of the C++ standard library:

A translation unit shall include a header only outside of any external declaration or definition[*], and shall include the header lexically before the first reference in that translation unit to any of the entities declared in that header.

[*] which would include a namespace definition.

Should I wrap all my c++ code in its own namespace?

Many C++ developers do not use namespaces, sadly. When I started with C++, I didn't use them for a long time, until I came to the conclusion that I can do better using namespaces.

Many libraries work around namespaces by putting prefixes before names. For example, wxWidgets puts the characters "wx" before everything. Qt puts "Q" before everything. It's nothing really wrong with that, but it requires you to type that prefix all over again, even though when it can be deduced from the context which declarations you mean. Namespaces have a hierarchic order. Names that are lexically closer to the point that reference them are found earlier. So if you reference "Window" within your GUI framework, it will find "my::gui::Window", instead of "::Window".

Namespaces enable some nice features that can't be used without them. For example, if you put your class into a namespace, you can define free functions within that namespace. You then call the function without putting the namespace in front by importing all names, or selectively only some of them into the current scope ("using declaration").

Nowadays, I don't do any project anymore without using them. They make it so easy not to type the same prefix all over again, but still have good organization and avoidance of name-pollution of the global namespace.

Pulling C/C++ standard library into your project namespace, good idea?

This is a bad idea. Do not do things this way. Put the namespace declarations inside each header file. Never have a #include directive inside the scope of a namespace.

Never is a strong word, and there are very rare cases in which you might want to do this. If the file you're #includeing also has #include directives, you almost certainly do not want to be doing this, even more so than if they didn't.

If you need to be able to easily rename your namespace or use the same header to declare the same symbols in several different namespaces depending on context, use the preprocessor to change the namespace name instead. That's extremely ugly to do, but much better than what you're currently doing.

One thing you can do as a quick and dirty solution to this is #include <sys/types.h> and any other system header that's included before the namespace declaration. This will cause the double-inclusion guards in the system header files to kick in and avoid declaring stuff inside the namespace.

Should I #include in my library's namespace?

Applied 'common sense' suggests that you can't reliably include C++ standard headers inside your own namespace. The standard library code is meant to be in the std namespace, not the library::std namespace. If there are any non-templated functions, the system library will provide std::non_templated_function and not library::std::non_templated_function, so your code won't link. If everything is a template, you may get away with it, but it is (unnecessarily) risky at best so don't do it.

Further (as noted by T.C. in a comment), the C++11 standard (ISO/IEC 14882:2011) standard explicitly says in §17.6.2.2 Headers [using.headers]:

¶3 A translation unit shall include a header only outside of any external declaration or definition, and shall
include the header lexically before the first reference in that translation unit to any of the entities declared
in that header.

This refers to a header from the C++ standard library, of course; it makes no such proscription for your own headers.

In theory, your library's internal headers could be included inside your library namespace if you want (but they shouldn't be — see below):

namespace library {
#include "library/internal-header.h"
…other declarations or definitions…
}

However (as Matt McNabb noted in a comment), doing so would mean that the internal header could not include any new standard headers, and yet it is quite plausible that an internal header would need to use some (extra) standard headers.

You might care to think about including them inside your own internal sub-namespace (for example, library::internal). If your internal headers do not contain their own namespace library { … } block, ensure you always include them inside the scope of your namespace library { … } brackets in the headers that include them, but note that the internal headers are no longer completely standalone.

Alternatively, and much more reliably, your library's internal headers could should be made standalone, with their contents defined inside your library namespace (since namespaces are extensible).

#include "library/internal-header.h"
namespace library {
…other declarations or definitions…
}

where "library/internal-header.h" would contain:

namespace library {
namespace internal {
…internal declarations or definitions…
}
}

where the namespace internal { and matching } are optional — and you might want a using namespace library::internal; directive as well.

Either mechanism could be made to work. On the whole, though, standalone headers are much the better (I agree with πάντα ῥεῖ and his comment and Matt McNabb).



Related Topics



Leave a reply



Submit