Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using concurrently 2 versions of boost

Tags:

c++

boost

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?

like image 308
dimba Avatar asked May 25 '10 19:05

dimba


3 Answers

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: 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.

like image 166
Artyom Avatar answered Nov 04 '22 13:11

Artyom


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.

like image 1
richj Avatar answered Nov 04 '22 13:11

richj


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).

like image 3
Jerry Coffin Avatar answered Nov 04 '22 14:11

Jerry Coffin