3

I'd like to begin transitioning to use C++11 in a large, cross-platform codebase. The main problem is that the level of C++11 support varies between the compilers that are used.

Aside from littering macros throughout the code, does anyone have any examples/suggestions on how to ease this transition? Please provide techniques for specific features. For example:

// cpp11compat.h

// For compilers that do not have 'nullptr', we will define it as 'NULL'.
// Any misuses of 'nullptr' will be caught by C++11 compliant compilers.
// Obviously, this won't fix anything that depends on the type 'nullptr_t'
//
#ifdef STUPID_SUN_COMPILER
#define nullptr NULL
#endif

Thoughts?

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Michael Price
  • 8,088
  • 1
  • 17
  • 24
  • 1
    for now you have a few choices, look at all the compilers and figure out what features of c++11 they all share, and just use those features exclusively, or you can continue with your current macro scheme, all compilers have macros that will give their name and version number. That'll be one helluva header to write though sheesh. Good luck! – johnathan May 12 '12 at 18:39
  • @johnathon - Yeah, that would be great, except for a few compilers have next to nothing in terms of C++11 support. I'm looking at you SunStudio... – Michael Price May 12 '12 at 18:42
  • yea. Gotta love SunStudio. Makes ya kinda envious of gcc, clang, ICC, and VC – johnathan May 12 '12 at 18:43
  • personally i find the c++11 support is rather weak at the moment, even such a thing as vector v = {1,2,3} doesn't work in visual studio 11, now *that* would be helpful :) – AndersK May 12 '12 at 18:44
  • @AndersK yes, vc is lacking, but no where NEAR as bad as sun studio – johnathan May 12 '12 at 18:45
  • 2
    the real point to realize is c++ 11 is still new. it's still a baby, so compiler support is going to be lacking across the board, granted gcc is way ahead of its competitors, but even IT fails to support ALL of c++ 11. – johnathan May 12 '12 at 18:46
  • 3
    If you need to support really old compilers, this is probably just a waste of time. – Cat Plus Plus May 12 '12 at 18:56
  • @CatPlusPlus - Good point. Although, I think it depends on the feature. Obviously the effort/cost of simulating C++11 features will vary between features. Unfortunately, moving away from a known quantity (even if it is a crappy compiler) scares folks. Most of the time, those folks are the ones with the purse-strings. – Michael Price May 12 '12 at 19:01
  • 1
    `override` and `final` are also keywords which can be easily replaced with defines for compiles which dont support those. – smerlin May 12 '12 at 20:22
  • @smerlin - Could you issue an answer with those two? I'd like to make some comments, but would like them to be isolated from the rest of the discussion under the question. I'd also like to vote that up as an answer, not a comment. – Michael Price May 12 '12 at 22:14
  • I can understand why folks have voted to close this question. Might any of those individuals have suggestions on how to modify the original question in a way that would help to solve the problems that belie the question(s) posed? This **is** a very real problem and we as a community *deserve* answers better than: Common Demoninator or Just Wait. – Michael Price May 13 '12 at 03:55
  • @MichaelPrice: The question of "how do I know what C++11 features are supported" [has already been asked and answered](http://stackoverflow.com/questions/10225451/c11-feature-checking). The rest is a "should I do this" question, which we can't answer. – Nicol Bolas May 13 '12 at 04:21
  • @NicolBolas - I didn't think I asked either of those questions. Two different people have answered that way, but I haven't accepted them. My question is not "should", but "how". Perhaps if I ask the question in the context of individual features? e.g. Given a set of compilers, some without support for method deletion, what techniques can I use to provide non-copyable and non-movable that will work for that set of compilers? – Michael Price May 13 '12 at 14:24
  • Or maybe this should be a community wiki... I still don't quite understand the purpose for those or how to get one going. – Michael Price May 13 '12 at 14:24

2 Answers2

1

I would suggest that you start with finding the largest common denominator of C++11 features by current compilers. For a survey see: http://wiki.apache.org/stdcxx/C%2B%2B0xCompilerSupport The most widely supported features include auto, decltype and move semantics, so you could start with rewriting your code with those, and make a #define fix for the platforms that don't support a specific feature that most other platforms do support (e.g. nullptr).

For the file organization of all the config files, you might want to check the source code of Boost.Config It contains several directories, ordered by platform and purpose. E.g. config/platform/irix.hpp contains all the platform specific stuff for Irix.

EDIT: Another good way to do emulation of language features is to look at the Boost libraries for Language Feature Emulation tags. They contain libraries such as Move, Foreach and previously Lambda that have very similar (although not necessarily exactly the same) syntax as the standard C++11 features. This allows you to let Boost worry about platform compatibility.

TemplateRex
  • 69,038
  • 19
  • 164
  • 304
  • 2
    Thats quite easy. The intersection of the sets of C++11 features of each compiler is currently the empty set :-) – Gunther Piez May 12 '12 at 19:15
  • I generally like this approach, but unfortunately, that common denominator amounts to only *one* feature: `long long`. Not practical at all. This would be a surrender, not a solution. – Michael Price May 12 '12 at 19:15
  • @MichaelPrice So you would have to have #define all over the place: one version of some class/function that uses C++11 features, and some use the current code that don't have the C++11 stuff. You will be having a split codebase. The only question is how you organize this in code: through header files or through #defines inline. – TemplateRex May 12 '12 at 19:23
  • @rhalbersma - Not at all. I'm asking for solutions; they don't have to depend on macros if they don't have to. Also, for my `nullptr` example, the only `#define` would appear in that single header file and would work seamlessly as long as `nullptr` was used correctly. I'm looking for any simple techniques that can be used effectively and safely. – Michael Price May 12 '12 at 19:26
0

Little time has passed since the publication of the standard. While you could probably reach almost all of C++11 features through boost, this year probably is not the best timing for starting that type of migration unless you already are on this road, because it would result in migrating twice.

So I suggest that you give compiler vendors another year or two before you start migrating. Meanwhile, try to stop supporting any abandoned platforms where no updated compilers are likely to appear if you feel that C++11 is very important for you throughout the code base.

(In fact, it is completely fine and common to never completely migrate a large codebase to the next version of a language standard, but that is not relevant to your question the way it is currently phrased.)

Jirka Hanika
  • 13,301
  • 3
  • 46
  • 75