views:

291

answers:

5

In standard library, I found that namespace std is declared as a macro.

#define _STD_BEGIN  namespace std {
#define _STD_END        }
  1. Is this a best practice when using namespaces?
  2. The macro is declared in Microsoft Visual Studio 9.0\VC\include\yvals.h. But I couldn't find the STL files including this. If it is not included, how it can be used?

Any thoughts..?

+3  A: 
  1. In general No. The macros were probably used at the time when namespaces were not implemented by some compilers, or for compatibity with specific platforms.
  2. No idea. The file would probably be included by some other file that was included into the STL file.
Amit Kumar
Thanks. I checked and couldn't find some other files including this file.
Appu
A: 

I imagine the only reason to do this is if you want to make it easy to change the namespace used by your application / library, or disable namespaces altogether for compatibility reasons.

Ryu
+4  A: 

Probably not a best practice as it can be difficult to read compared to a vanilla namespace declaration. That said, remember rules don't always apply universally, and I'm sure there is some scenario where a macro might clean things up considerably.

"But I couldn't find the STL files including this. If it is not included, how it can be used?".

All files that use this macro include yvals.h somehow. For example <vector> includes, <memory>, which includes <iterator>, which includes <xutility>, which includes <climits>, which includes <yvals.h>. The chain may be deep, but it does include it it some point.

And I want to clarify, this only applies to this particular implementation of the standard library; this is in no way standardized.

GMan
+1 for good explanation. Wish I could match!
Amit Kumar
A: 

One approach that I saw in a library that I recently used was:

BEGIN_NAMESPACE_XXX()

where XXX is the number of namespace levels for example:

BEGIN_NAMESPACE_3(ns1, ns1, ns3)

would take three arguments and expand to

namespace ns1 {
    namespace ns2 {
        namespace ns2 {

and a matching END_NAMESPACE_3 would expand to

        }
    }
}

(I have added the newlines and indentation for clarity's sake only)

6pack kid
A: 

I could see doing this for the C libraries that are included in C++ by reference (eg., the header that C calls string.h and that C++ calls cstring). In that case, the macro definition would depend on an #ifdef _c_plus_plus.

I wouldn't do it in general. I can't think of any compiler worth using that doesn't support namespaces, exceptions, templates or other "modern" C++ features (modern is in quotes because these features were added in the mid to late '90s). In fact, by my definition, compilers are only worth using if they offer good support for their respective language. This isn't a language issue; it's a simple case of "if I chose language X, I'd prefer to use it as it exists today, not as it existed a decade or two ago." I've never understood why some projects spend time trying to support pre-ANSI C compilers, for instance.

Max Lybbert