How can I wrap BOOST in a separate namespace? - c++

I'm looking to have two versions of BOOST compiled into a project at the same time. Ideally they should be usable along these lines:
boost_1_36_0::boost::shared_ptr<SomeClass> someClass = new SomeClass();
boost_1_35_0::boost::regex expression("[0-9]", boost_1_35_0::boost::regex_constants::basic);

I read (well scanned) through the development list discussion. There's no easy solution. To sum up:
Wrapping header files in a namespace declaration
namespace boost_1_36_0 {
#include <boost_1_36_0/boost/regex.hpp>
}
namespace boost_1_35_0 {
#include <boost_1_35_0/boost/shared_ptr.hpp>
}
Requires modifying source files
Doesn't allow for both versions to be included in the same translation unit, due to the fact that macros do not respect namespaces.
Defining boost before including headers
#define boost boost_1_36_0
#include <boost_1_36_0/boost/regex.hpp>
#undef boost
#define boost boost_1_35_0
#include <boost_1_35_0/boost/shared_ptr.hpp>
#undef boost
Source files can simply be compiled with -Dboost=boost_1_36_0
Still doesn't address macro conflicts in a single translation unit.
Some internal header file inclusions may be messed up, since this sort of thing does happen.
#if defined(SOME_CONDITION)
# define HEADER <boost/some/header.hpp>
#else
# define HEADER <boost/some/other/header.hpp>
#endif
But it may be easy enough to work around those cases.
Modifying the entire boost library to replace namespace boost {..} with namespace boost_1_36_0 {...} and then providing a namespace alias. Replace all BOOST_XYZ macros and their uses with BOOST_1_36_0_XYZ macros.
This would likely work if you were willing to put into the effort.

Using bcp can install boost library to a specific location and can replace all 'namespace boost' in their code to a custom alias. Assuming our alias is 'boost_1_36_0' all 'namespace boost' code blocks will start with 'boost_1_36_0'. Something like
bcp --namespace=boost_1_36_0 --namespace-alias shared_ptr regex /path/to/install
, but check the documentation in the link yourself because I'm not sure if it is legal syntaxis.

#Josh:
While I agree with the shivering, I still believe this is the better course of action. Otherwise, linking troubles are a certainty. I've had the situation before where I had to hack the compiled libraries using objcopy to avoid definition conflicts. It was a nightmare for platform interoperability reasons because the name mangling works very differently even in different versions of the same compilers (in my case, GCC).

You'll have a world of trouble linking because the mangled names will be different. And yes, I see you knew that, but it seems like it will be trouble all around.

Related

Why we can't include std headers within a namespace in C++

The following code will cause compile errors in g++4.4:
// File test.cpp
namespace A
{
#include <iostream>
}
int main()
{
return 0;
}
I have this requirement because some third party library comes without namespace protected, and if I directly include these headers, my namespace is polluted.
As a result, I tried to create namespaces for those libraries, but if the library includes some "std headers" the above approach will fail.
Can anybody help?
Thank You!
I believe 17.4.2.1 [lib.using.headers] forbids including standard library headers in a namespace :
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 to any of the entities it declares or first defines in that
translation unit.
I don't think there is anything you can do besides filing a request to the library author.
This approach will most likely lead you to trouble. You could approach the problem by manually including each such standard header before entering the namespace, and the include guards would take care of not re-including the header inside the namespace.
That would take care of your current error, but it would on the other hand break too many other things --if the library is precompiled then the symbols used in your code and the symbols in the binary library would be different symbols (libname::foo() used in your code, ::foo() defined in the binary). Even if the library is header only, any fully qualified access to the library within the library itself would break (void foo() { ::bar(); } where foo and bar are inside the library).
A valid approach that you might want to try (even if cumbersome, and requiring real work) would be writting a wrapper that is within it's own namespace, and uses the library. Then include your wrapper instead of the actual library headers.
My advice, on the other hand, would be ignoring the problem altogether. Declare your own objects within your namespaces and that would take care of the possible name collisions. As long as you keep away from using namespace statements you will be fine.
Use fully qualified names when using calls to standard libraries like std::cout instead of writing using namespace std;. This way, both can coexist.

Why in C++ do I need to use namespace after already using import directive?

In C# one only uses an using directive for a namespace. In C++ like in this example below, one must do an include then use a namespace, why isn't it the same thing like in C# ?
#include <iostream>
int main()
{
using namespace std;
cout << "Hello world!" << endl;
return 0;
}
Because the compiler in C# works very differently than C++.
The quick version - C# uses references in a (vaguely) similar fashion as C++ uses the linker, and forward declarations. C++ requires forward declarations so it can compile each source file to a translation unit, then link all those units together. The C# compiler loads the code for your referenced assemblies, then compiles your whole assembly at once, and therefore doesn't need those sorts of forward declarations.
The long version -
C++
In C++, if you want to use code, you have to add it to the linker, and provide forward declarations. Header files contain forward declarations, and include files simply copy/paste that file into your source file.
This is because C++ has a mid-step called translation units, and produces object files. There are glued together by the linker.
In your example, #include <iostream> provides the forward declarations, and does so by including a header file (previously called "iostream.h", but now called "iostream"). This header file gets copy/pasted into your source code (along with all the headers that file includes, and so on). This all gets compiled down to a translation unit (object file), linked to the C++ runtime (as well as probably the C runtime, and maybe others), and turned into an executable.
C#
In C#, if you want to use code, you add a reference to the project or build file, or you simply add the C# file to the same project. No forward declarations are required, but you do have to reference the code, or have another source file in your current assembly that contains the code.
C# doesn't have the translation unit mid-step. It only produces assemblies.
When you reference System.dll, you already have the code available to you. You don't have to provide forward declarations, and therefore don't need to include any headers.
Both
You can use the using keyword to either pull an entire namespace into your current scope. In C++, you invoke using namespace std;. In C#, you invoke using System;
Then you can do things like:
std::cout << "test1\n";
cout << "test2\n";
Or
System.Console.WriteLine("test1");
Console.WriteLine("test1");
I forget if you can in C++, but in C# you can also alias namespaces:
using Ser = System.Runtime.Serialization;
...
class Blah : Ser.ISerializable {
Or alias types:
using ISer = System.Runtime.Serialization.ISerializable;
...
class Blee : ISer {
I normally wouldn't answer a question with so many useful answers, but nobody seems to have noticed "import" in your question. In C and C++, the "#include" directive is not the same as "import" in Java or "using" in C#. Literally, a #include directive simply adds lines you the compilation of the file containing the directive. Period.
There is no comparable feature to #include in most other compiler languages; but there is such a feature in nearly every useful assembler. C is a low-level language originally designed for portable implementation of operating system kernels, drivers and utilities. C++ is a higher-level language, but is built upon C. A deliberate design goal was to allow most C programs to compile with no source changes as legal C++ programs.
Keep that picture in mind as you study C++. It may help you understand how why it's put together the way it is.
The C++ standard library is much smaller than the frameworks for Java or C#, and all of it is defined within the std namespace. That means that the only "import" you need for the entire library is the "using namespace std;", which is what brings those names into view without explicit std:: prefixes; but only those names that have been #included into the current compilation.
If you don't use an include, then as far as the compiler is concerned, whatever is declared in that header doesn't exist. In order to use a function, the compiler must know that it exists. The using directive and the #include are totally tangental- you don't have to use a using at all and many more experienced programmers recommend against it.
the include directive just copy-pastes the source file into your progams, nothing more (in your code, for example, #include puts the source-file "iostream" that's in your C++ compiler install into your source code.
The using direcive, on the other hands, does exactly what the one in C# does.
The purpose of using namespace std; line is so you don't have to type out the full std::cout, std::endl every time. It will assume when you do use cout, endl, or any other function from the standard library without the std:: that you wanted to use the one from the standard library.
You can try this yourself, remove using namespace std; and try to compile. You should get errors. Then try to compile again using std::cout << "Hello world!" << std::endl; and it will work like before.
Check this out here:
http://www.cplusplus.com/doc/tutorial/namespaces/
It actually is similar in C#. Using is indeed only for namespaces, even in C# Try using something from an assembly you haven't referenced, it won't work no matter how many times you say using Foo.Bar. Adding the reference is similar to the include step in C++ (although not identical, C# makes "including" and "linking" a single step).

Boost's "cstdint" Usage

Boost's C99 stdint implementation is awfully handy. One thing bugs me, though. They dump all of their typedefs into the boost namespace. This leaves me with three choices when using this facility:
Use "using namespace boost"
Use "using boost::[u]<type><width>_t"
Explicitly refer to the target type with the boost:: prefix; e.g., boost::uint32_t foo = 0;
Option № 1 kind of defeats the point of namespaces. Even if used within local scope (e.g., within a function), things like function arguments still have to be prefixed like option № 3.
Option № 2 is better, but there are a bunch of these types, so it can get noisy.
Option № 3 adds an extreme level of noise; the boost:: prefix is often ≥ to the length of the type in question.
My question is: What would be the most elegant way to bring all of these types into the global namespace? Should I just write a wrapper around boost/cstdint.hpp that utilizes option № 2 and be done with it?
Also, wrapping the header like so didn't work on VC++ 10 (problems with standard library headers):
namespace Foo
{
#include <boost/cstdint.hpp>
namespace boost_alias = boost;
}
using namespace Foo::boost_alias;
EDIT: I guess another option is to use the preprocessor to make it work on VC 10? Taking the snippet above:
#ifndef FOO_HPP_INCLUDED
#define FOO_HPP_INCLUDED
#if _MSC_VER >= 1600 /*VC++ 10*/ || defined USE_NATIVE_STDINT_HEADER
#include <stdint.h>
#else
namespace cstdint_wrapper
{
#include <boost/cstdint.hpp>
namespace boost_alias = boost;
}
using namespace cstdint_wrapper::boost_alias;
#endif
#endif
Less work, I guess?
I just use C99's stdint.h (it's actually now in VS 2010). For the versions of Visual C/C++ that don't include it, I use a public domain version from MinGW that I modified to work with VC6 (from when I had to work in VC6):
http://snipplr.com/view/18199/stdinth/
There are a couple other options you might consider in this SO question: C99 stdint.h header and MS Visual Studio
If you'd like to continue using boost/cstdint.hpp, I'd say that the suggestion of implementing a wrapper header that brings the types into the global namespace would be the way to go.
Does boost/cstdint.hpp provide anything I should know about that isn't in stdint.h?
Your idea of writing a wrapper header that implements option 2 is definitely the better of those three options.
What I'd suggest, though, is a slight variant: Put those using declarations within another namespace, such as cstdint or something; then, you have the option if putting using cstdint; in your own code or explicitly specifying cstdint:: on the particular uses.
If you included directly the file you will be forced to prefix it with std::. So the question is, which option would you take in this case. What would you do with the other types introduced by Boost? Would you prefix them with boost:: or not?
The fist one is clearly a bad option.
You can implement option two using your my_cstdint.hpp file
#include <boost/cstdint.hpp>
using boost::uint32_t;
...
and include my_cstdint.hpp in your application. But in my opinion it is a bad idea to add new symbols on the root namespace, you can get more conflicts as the types can be already defined by for example the stdint.h C file.
Even if the third option use a lot of characters, namespaces are there for this purpose. boost::uint32_t will be defined to the correct type depending on your toolset, so just use it, as you would use std::uint32_t.
I personally always use option 3. If things are too long, then you can use typedefs to reduce the amount of code.

Declaring namespace as macro - C++

In standard library, I found that namespace std is declared as a macro.
#define _STD_BEGIN namespace std {
#define _STD_END }
Is this a best practice when using namespaces?
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..?
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.
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.
No idea. The file would probably be included by some other file that was included into the STL file.
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)
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.
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.

Can I redefine a C++ macro then define it back?

I am using both the JUCE Library and a number of Boost headers in my code. Juce defines "T" as a macro (groan), and Boost often uses "T" in it's template definitions. The result is that if you somehow include the JUCE headers before the Boost headers the preprocessor expands the JUCE macro in the Boost code, and then the compiler gets hopelessly lost.
Keeping my includes in the right order isn't hard most of the time, but it can get tricky when you have a JUCE class that includes some other classes and somewhere up the chain one file includes Boost, and if any of the files before it needed a JUCE include you're in trouble.
My initial hope at fixing this was to
#undef T
before any includes for Boost. But the problem is, if I don't re-define it, then other code gets confused that "T" is not declared.
I then thought that maybe I could do some circular #define trickery like so:
// some includes up here
#define ___T___ T
#undef T
// include boost headers here
#define T ___T___
#undef ___T___
Ugly, but I thought it may work.
Sadly no. I get errors in places using "T" as a macro that
'___T___' was not declared in this scope.
Is there a way to make these two libraries work reliably together?
As greyfade pointed out, your ___T___ trick doesn't work because the preprocessor is a pretty simple creature. An alternative approach is to use pragma directives:
// juice includes here
#pragma push_macro("T")
#undef T
// include boost headers here
#pragma pop_macro("T")
That should work in MSVC++ and GCC has added support for pop_macro and push_macro for compatibility with it. Technically it is implementation-dependent though, but I don't think there's a standard way of temporarily suppressing the definition.
Can you wrap the offending library in another include and trap the #define T inside?
eg:
JUICE_wrapper.h:
#include "juice.h"
#undef T
main.cpp:
#include "JUICE_wrapper.h"
#include "boost.h"
rest of code....
I then thought that maybe I could do some circular #define trickery like so:
The C Preprocessor doesn't work this way. Preprocessor symbols aren't defined in the same sense that a symbol is given meaning when, e.g., you define a function.
It might help to think of the preprocessor as a text-replace engine. When a symbol is defined, it's treated as a straight-up text-replace until the end of the file or until it's undefined. Its value is not stored anywhere, and so, can't be copied. Therefore, the only way to restore the definition of T after you've #undefed it is to completely reproduce its value in a new #define later in your code.
The best you can do is to simply not use Boost or petition the developers of JUCE to not use T as a macro. (Or, worst case, fix it yourself by changing the name of the macro.)