The OME Blog Because metadata is worth a thousand pictures

OME Files C++ and C++11

This blog is an update about the use of C++11 and C++14 (“modern C++”) within OME Files C++.

We have been evaluating the switch from C++98 to C++11 for over 18 months. Up until now, we have remained using C++98 in order to continue to support older systems with compilers which do not support C++11. However, circumstances have recently changed which will necessitate a switch at some point in the near future.

Platform support

Most current platforms support C++11 and C++14, with some exceptions (workarounds are noted)

Platform Compiler C++11 C++14
CentOS 6 GCC 4.6 Unsupported by default* Unsupported by default*
CentOS 7 GCC 4.8 Mostly supported Partially supported
FreeBSD 10 Clang/LLVM 3.4 Fully supported Fully supported
FreeBSD 11 Clang/LLVM 3.8 Fully supported Fully supported
MacOS X 10.10 Apple LLVM 7.3 Fully supported Fully supported
MacOS X 10.11 Apple LLVM 8.0 Fully supported Fully supported
MacOS X 10.12 Apple LLVM 8.0 Fully supported Fully supported
Ubuntu 14.04 GCC 4.8 Mostly supported Partially supported
Ubuntu 16.04 GCC 5.3 Fully supported Fully supported†
Visual Studio 2013 VC12‡ Partially supported Mostly unsupported
Visual Studio 2015 VC13‡ Supported Partially supported
Visual Studio 2017 VC15‡ Supported Supported

* The software collections devtoolset-4 (GCC 5.2) and devtoolset-3 (GCC 4.9) packages provide updated compilers which can build OME Files C++ using C++11

† Boost 1.58 provided by this release does not build OME Files with C++14, but does build with C++11; see trac ticket

‡ Microsoft Visual C++ lags significantly behind GCC and Clang/LLVM, but VS2013 contains a useful subset of features, which are improved upon significantly with VS2015 and later

The support classifications above are broad; please see the following references for full feature coverage:

Third-party dependencies

All of our third-party dependencies have supported building with a C++11 or C++14 compiler for some time. However, more recently some of our dependencies have begun to require it, or will require it in their next major release.

For many users, these libraries are provided by package repositories, including Linux distributions’ package managers, MacOS X homebrew and FreeBSD ports. As these package repositories begin to provide the updated C++11 versions of these libraries, OME Files C++ will no longer build with them. While some of these C++11 libraries are optional (Qt5), others such as ICU are required by Boost and Xerces-C++ for full Unicode support, which is needed by the OME-XML data model. As a result, C++11 support will become a necessity for continued use of these libraries as the versions requiring C++11 enter mainstream use.

The benefits of C++11

C++11 adds a number of useful features to the language, including:

  • auto type
  • decltype keyword
  • defaulted and deleted functions
  • delegating constructors
  • forward-declared enums
  • initialiser lists
  • lambdas
  • nullptr keyword
  • override and final qualifiers
  • range-based for loops
  • rvalue references
  • static_assert
  • strongly-typed enums
  • variadic templates

and library features, including:

  • std::array
  • std::shared_ptr
  • std::thread
  • std::tuple
  • std::unique_ptr

These features are all supported by the compilers on the above platforms. Some additional features (not included here) are not yet supported by the compilers on every platform, and so can’t yet be used.

These features benefit the project in several ways:

  • they reduce the code size dramatically by permitting much more concise code with reduced boilerplate (by around 50% in one test conversion of a single component)
  • they allow the use of standard library features in place of Boost equivalents, which aids interoperability (e.g. std::thread and std::shared_ptr in place of boost::thread and boost::shared_ptr)
  • they allow improved performance of standard library containers through the use of rvalue references, and also allow the use of new features such as std::unique_ptr to replace boost::shared_ptr in certain situations, again improving performance
  • they make the library easier to use, for example the use of initialiser lists can reduce the PixelBuffer nD array addressing from multiple lines to a single line of code
  • they make the library more understandable and more familiar for users already using these features with other libraries; in particular features such as std::shared_ptr have been available since VS2010 for Windows developers and their use is already widespread

Proposal

Given that:

  • all of our supported platforms can support a sizeable subset of C++11
  • our dependencies will increasingly require C++11
  • there are significant benefits to switching to C++11 as a result of the features and performance gains it brings

we plan to make a C++11 compiler a requirement in our upcoming 0.3.0 release of OME Files C++, and begin using a subset of the C++11 features available across our supported platforms. For most users, the transition should be entirely transparent and will require no immediate code changes as we will leave compatibility typedefs in place through a transitional period.

If this will present any problems, please get in touch through our mailing lists or forums so that we can discuss any concerns you may have. Likewise, if the change is something which you will find useful and beneficial, we would also like to hear from you.