tags:

views:

135

answers:

3

I'm using RHEL 5.3, which is shipped with gcc 4.1.2 and boost 1.33. There're some features I want, that are missing in the boost 1.33. Therefore the thought was to upgrade to fresh boost release 1.43.

  1. Is it possible to use concurrently some header-only library(s) from boost 1.43 and the rest from 1.33? For example I want to use unorded_map, which is missing in boost 1.33.

  2. Is it possible to use concurrently binary boost libraries from different releases?

+3  A: 

With a bit of luck (and a lot of care) you can probably get away with using entirely new headers. For almost anything else, it could get ugly in a hurry, because some parts of Boost refer to other parts, and if some v. 1.33 code accidentally loads a v. 1.43 header for its dependency, there's a pretty good chance you're going to get some problems as a result -- about the best you can hope for is a quick, clean death (crash) at that point, but you might easily get much worse (e.g., silent data corruption).

Jerry Coffin
+5  A: 

NO -- never do this!

It is impossible, you'll likely to get accidental crashes.

The only way to get it done correctly is using namespace renaming: i.e. create alternative boost version placed in different namespace.

Latest version of BCP provides this option. So you will use something like boost_1_43 instead of boost. But it will be quite transparent for you. But you should still be aware of that you can't use two versions of boost in same cpp file.

Also take a look on this discussion: http://stackoverflow.com/questions/836875/creating-library-with-backward-compatible-abi-that-uses-boost

The liked script renames namespace, defines and includes so you can actually include two versions of boost like

#include <boost/foo.hpp>
#include <myboost/bar.hpp>

boost::foo f;
myboost::bar b;

Boost BCP does not allow this.

But still you should be careful as some libraries export extern "C" symbols without boost prefix, boost::thread and boost::regex's C API (regexec, regcomp)

Edit

As example of such issue create following files:

a.cpp:

template<typename Foo>
Foo add(Foo a, Foo b)
{
        return a+b;
}


int foo(int x,int y)
{
        return add(x,y);
}

b.cpp:

template<typename Foo>
Foo add(Foo a, Foo b)
{
        return a-b;
}


int bar(int x,int y)
{
        return add(x,y);
}

test.cpp:

#include <iostream>

int foo(int,int);
int bar(int,int);

int main()
{
        std::cout<< foo(10,20) <<" " <<bar(10,20) << std::endl;
}

Compile them:

g++ a.cpp b.cpp test.cpp

You would expect:

30 -10

But you'll get

30 30

or

-10 -10

Depending on linking order.

So using two boost versions you may accidentally use symbols from other boost and crash same as in this program symbol int add<int>(int,int) is resolved to same symbol even if it is placed in different compilation units.

Artyom
+1 for the link - even though I disagree with the first half of your answer.
richj
@richj - it is possible under DLL platforms where all linkage is explicit, but for ELF bad things happen (from experience)
Artyom
A: 

Update

I think my original answer makes too many assumptions about the capabilities of the linker and the options used, and it may well be completely wrong. Ordinarily I would delete it, but there are some points in the discussion that aren't included in the other answers.

I find the implications for what it takes to build a well behaved closed-source library just amazing.

Original Answer

As long as you use one version per compilation step then you should be OK because the code is generated at compile time and the generated symbols should be confined to the scope of the compilation step.

I'm assuming that Boost is still a template library with no linkable libraries. If it isn't, then you're still OK as long as you don't link against more than one version of the library.

I might be wrong on this, but the implication would be that you can't use any third party library built against a different version of Boost from the version defined for your application. Nothing that I've read or heard even hints that this limitation applies.

If you are building your own application, then I would stick with one version of Boost for all of your own code. It doesn't have to be the same version that is supplied by RHEL.

Update

In comparison with Artyom's example, the scenario I am talking about is more like this:

g++ -c -I/usr/include/boost_1.31 a.cpp
g++ -c -I/usr/include/boost_1.39 b.cpp
ar rcs liba.a a.o
ar rcs libb.a b.o
g++ -I/usr/include/boost_1.41 test.cpp liba.a libb.a -o test

... and now I understand Artyom's point, because it depends on whether the linker prefers symbols in the same library file or not.

richj
-1 Not correct, especially when we talk about ELF platform
Artyom
By ELF do you mean this: http://en.wikipedia.org/wiki/Executable_and_Linkable_Format? If so, I don't know anything about it, but I don't see how it's relevant to C++ meta-programming. Please explain.
richj
@richj see example in my answer.
Artyom
Thank you for the example. I've updated my post to better explain the scenario that I was talking about. I should not have used "compilation unit" when I meant "set of files compiled together". I'll change it to "compilation step".
richj
@Artyom Does this mean that everything has to be built from source on the ELF platform to build an application that depends on libraries that depend on Boost? Or can you solve the problem of multiple Boost versions with incremental linking or shared libraries?
richj
BTW this is not ELF only, static link on Windows has same features. The issue that even shared libraries (ELF) will have exactly the same issue in run-time. In case of dll, you can have two different dlls using two different versions of boost if it is not exposed in DLL's API. So just don't do it... Ever.
Artyom
OK - but sometimes there is no choice. If you are using a third party library you might not even know that the third party code uses Boost. That is the case that I am interested in.
richj
You just rename the Boost using BCP or the script I published and use boost in `your_own_boost_namespace` instead of original boost namespace.
Artyom