Code should be migrated from tr1 to std (does not compile on OS X 10.9)

Bug #1236815 reported by Dominik
34
This bug affects 5 people
Affects Status Importance Assigned to Milestone
Gearman
Fix Released
Undecided
Brian Aker

Bug Description

Gearman does not compile on OS X 10.9.

According to Apple there are two ways to fix that (see below).
(There is a PR with a patch for this problem for the Homebrew package manager here:
https://github.com/mxcl/homebrew/pull/22612).

A little background:
The tr1 headers were an experiment by the C++ standards committee, nothing more. They are not part of any standard. Apple is involved with the standards committee in an effort to make future committee experiments more obvious, and less likely to be mistaken for stable parts of a standard.

Additionally Apple is in the middle of transitioning from a gcc-based implementation of the std::lib (based on gcc-4.2) to a new-from-the-ground-up implementation that fully supports the new C++11 standard. This new implementation is also open source and the open source project can be found here: http://libcxx.llvm.org

Since 10.7/Lion, two implementations of the std::lib, the old gcc libstdc++, and this new llvm libc++ have been shipped.
With -lets say "newer"- OSes, the new libc++ is becoming the default used by the compiler clang.
This switch in the default std::lib is what's causing the symptom described in this ticket.

The older libstdc++ is still available and still has the same tr1 headers it always has.
The newer libc++ lacks the tr1 experiment. However most of tr1 was standardized with C++11, and now lives in namespace std, and in headers not prefixed with tr1/.

The C++ committee purposefully used the experimental std::tr1 namespace for the experiment so that they could (if need be) modify the tr1 components as they were standardized. And indeed this has happened. For the most part you will not notice any difference as you migrate from tr1 implementations to the C++11 std implementations. However there do exist a few corner cases. I would not worry about these corner cases. If you hit one, it will almost certainly come in the form of a compile-time error.

You are faced with two options:

1. Migrate your code from tr1 to std. I will show how to do this below. It is very easy. And it can be done in a manner in which your code is portable to both the old libstdc++ and the new libc++. This is the path "people at some company recommend".

2. Override the default std::lib choice and specifically choose the older gcc-4.2 based libstdc++. This is the easier path. But if this path is chosen, you are ultimately simply delaying the (relatively easy) work of doing step 1.

To override the default on the command line, add -stdlib=libstdc++ to both the compile and link command lines. You can also specifically choose the newer libc++ with -stdlib=libc++.

To do (1), the first step is to auto-detect which std::lib you are using. If you have already included any std header, you can do:

#ifdef _LIBCPP_VERSION

// using the new libc++

#else

// using the old libstdc++

#endif

If you have not yet included a std header, and need to include one gratuitously to find out whether or not it will define _LIBCPP_VERSION, do:

#include <ciso646> // detect std::lib

<ciso646> is a wonderful little C++ header that is specified to do absolutely nothing. So it is very cheap to include, and it will define _LIBCPP_VERSION if you are using the newer libc++, and otherwise won't.

Once you know which std::lib you are using, it becomes very easy to do things such as:

#ifdef _LIBCPP_VERSION
// using the new libc++

#include <memory>
typedef std::shared_ptr<MyType> MyTypePtr;

#else
// using the old libstdc++

#include <tr1/memory>
typedef std::tr1::shared_ptr<MyType> MyTypePtr;

#endif

Once done, it's easy to switch between libstdc++ and libc++ for testing purposes.

Tags: clang std tr1
Brian Aker (brianaker)
Changed in gearmand:
assignee: nobody → Brian Aker (brianaker)
Brian Aker (brianaker)
Changed in gearmand:
status: New → In Progress
VemeC (vemecdos)
Changed in gearmand:
status: In Progress → Opinion
status: Opinion → In Progress
Revision history for this message
Dave (doc+launchpad) wrote :

Any chance of a status update or a documented workaround for this?

It's currently a blocker to installing and using Gearman on Mavericks

Thanks in advance.

Revision history for this message
Brian Aker (brianaker) wrote :

New version was just released (seconds ago).

I've been using it on my Mac for a while now with no issues.

Changed in gearmand:
status: In Progress → Fix Committed
status: Fix Committed → Fix Released
Revision history for this message
Dave (doc+launchpad) wrote :

Thanks,
this is also working for me.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.