Is it possible to detect whether at a given point of code you are in a namespace? In particular, I want to include a warning if a file is being including in the global namespace.
-
Can the file be included in only a particular namespace, or any namespace? – Luchian Grigore Sep 13 '12 at 15:53
-
@LuchianGrigore I'm including it in different namespaces to do some typedefs inside them and wanted a warning if the file was producing those typedefs in a global namespace. – pythonic metaphor Sep 13 '12 at 16:17
3 Answers
Good practice is including all headers in global namespace. Open all needed namespaces at the beginning of file and close them before end. Another way will inevitably lead to heap of problems.
** Comment extension **
To prevent unintended inclusion, you can do something like this:
In header:
#ifndef INTERNAL_INCLUDE
#error ...
#endif
When used:
#define INTERNAL_INCLUDE
#include "internal.h"
#undef INTERNAL_INCLUDE

- 249,747
- 28
- 448
- 644

- 962
- 7
- 15
-
2Disagree. There are exceptions from this rule. For example in http://www.boost.org/doc/libs/1_51_0/boost/smart_ptr/shared_ptr.hpp there is following include `// implicit conversion to "bool" #include
` – ForEveR Sep 13 '12 at 16:04 -
In my case, I'm using a file to declare some typedefs that I wanted confined to a namespace, and then including this file inside some different namespaces. But, regardless of whether this is a good idea, it would be interesting to know the answer to my question. I'll mark my question language lawyer. – pythonic metaphor Sep 13 '12 at 16:14
-
I see, boost developers used this in similar way. So, if you want to prevent header file from being unwittingly included, I wish you to add a preprocessor condition: `#ifndef _SOME_VAR_ #error bad include #endif` – Pavel Ognev Sep 13 '12 at 16:22
I can give you a hint that generates compilation error if header is not include in global namespace. If I know C++ constructiom which for sure generates compiler warning (other that #warning) then it could be used instead of compilation error.
Put in your header:
template <class A, class B>
struct AreSame { enum { VALUE = -1 }; };
template <class A>
struct AreSame<A,A> { enum { VALUE = 1 }; };
struct TestGlobalNamespace
{
int test_namespace[AreSame<TestGlobalNamespace, ::TestGlobalNamespace>::VALUE];
};
When your header is include in some namespace you'll get an error.
Like in this example:
namespace Some {
struct TestGlobalNamespace
{
int test_namespace[AreSame<TestGlobalNamespace, ::TestGlobalNamespace>::VALUE];
};
}
You'll get:
prog.cpp:17: error: size of array ‘test_namespace’ is negative
[UPDATE]
However the more probably would be this kind of errors:
prog.cpp:17: error: ‘::TestGlobalNamespace’ has not been declared
prog.cpp:17: error: template argument 2 is invalid
Anyway - no one will dare to include your header to namespace other than global.

- 23,099
- 7
- 66
- 112
-
After I wrote this I realized you wanted opposite, warning when file is in global namespace. Then just do opposite. Create AreDifferent template and you'll get opposite. Give me a note if you want this in such a way. – PiotrNycz Sep 13 '12 at 18:05
-
I realized that just added to my answer new set of errors is more likely. If you want your header to be included only in `Some` namespace - just use `Some::TestSomeNamespace` – PiotrNycz Sep 13 '12 at 19:29
-
This doesn't work for me... I need a static_assert<> that fires when NOT in global namespace. A compilation error won't do :/. – Carlo Wood Oct 24 '18 at 16:02
-
-
@PiotrNycz If you try that in a random namespace then TestGlobalNamespace must be defined in that namespace (or it will say that they are the same of course). I managed to come up with a macro in the end that triggers an assert when used outside of global namespace, but deleted it in the end because I chose a different route. – Carlo Wood Oct 26 '18 at 20:02
You can do this with the small inconvenience of requiring a second header, to be included in the global namespace before the first.
// stuff_guard.h - include from global namespace to guard stuff.h
#ifndef STUFF_GUARD_H
#define STUFF_GUARD_H
typedef char stuff_guard[1];
#endif
// stuff.h - must be included from non-global namespace, after stuff_guard.h
// No include guard - may be included multiple times, in different namespaces.
#ifndef STUFF_GUARD_H
#error stuff_guard.h must be included before stuff.h
#endif
typedef char stuff_guard[2];
static_assert(sizeof (stuff_guard) != sizeof (::stuff_guard),
"stuff.h must not be included from the global namespace");
// Put your stuff here
This will give reasonably friendly error messages if you break either of these two rules, and a somewhat less friendly error if you include stuff_guard.h
from a non-global namespace.
If you're stuck with an old compiler and static_assert
isn't available, then you could use BOOST_STATIC_ASSERT
, or roll your own.

- 1
- 1

- 249,747
- 28
- 448
- 644