Per-Compiler Notes

Notes about setting up cxxomfort, and the support available, on different compilers and setups.

The notes take into consideration following the setup available in Installation for the testbed compilers.

GNU GCC -- MSVC -- CLang -- Digital Mars -- Open Watcom -- general notes

GNU GCC

Supported versions:

  • -std=c++03: 4.4-6.0
  • -std=c++0x: 4.6-6.0
  • -std=c++11: 4.8-6.0
  • -std=c++14: 5.x
  • -std=c++17: undetermined
  • -std=c++20: undetermined

201x versions and TR1 Implementation

For users of cxxomfort versions released 201x only:

For C++<11, GCC sets up TR1 components as header files in the tr1/ include path and the features under the std::tr1 namespace. Cxxomfort sets up the macro CXXO_namespace_tr1 to the later value.

Unfortunately the TR1 headers are coded in such a way that it is not possible to add them to the #include search path. See [8ee003badda1c6033919702ac729de7c00ceb6b1] for the local report, GCC bugzilla for an example bug reported at bugzilla and report about stl_list.h for more general information. The tl;dr of the problem is that adding TR1 to the #include path causes ambiguity errors in declarations that can not be solved without patching the non-TR1 headers themselves, such as stl_list.h.

Since GCC considers Tr1 "not worth fixing", which given its age makes sense, it is instead recommended to use a TR1 forwarder such as tr1_fwd, which is the supported and tested-for configuration in GCC C++03 mode; or any other TR1 forwarder set up by the user.

Versions of cxxomfort pre 2020-01-01 do not include a forwarder; that is a task left to the user to handle.

Versions of cxxomfort post 2020-01-01 are not affected by this requirement - they detect the path and namespace used by TR1 headers; thus users should not set up a TR1 forwarder.

Associated tickets:

Short enum Types

GCC supports the -fshort-enums flag which allows enumeration types to use as a base types shorter than signed/unsigned int. Note that when this flag is enabled, the default implementation of typesafe enumeration types using library::typesafe_enum might change.

As a result, some specific types exposed to the public interface may or may not change:

  • std::errc
  • std::endian
User code can check the result of sizeof(cxxomfort::fix::short_enum) to determine if short enums are enabled or not.

GCC >= 7.x

Cxxomfort as of early 2020, is not tested with and not intended to be used with more modern versions of GCC, the latest version tested being 6.0. Ideally, at least for C++03 up to C++14 mode Cxxomfort should be expected to work in all GCC versions past 6.0.

The ticket [457376c379] will follow efforts to test GCC >= 7.x compatibility.


Microsoft Visual C++ Compiler

Supported versions:

  • C++03 : 2008 SP1, 2010, 2012 (partial), 2013 (partial)
  • C++11: none? (as of 2020-01-01)
  • C++14 / later: none? (as of 2020-01-01, the base compiler does not support it)

TR1 Implementation

MSVC 2008 without SP1, and earlier versions of MSVC, ship without a TR1, and thus are unsupported.

For compilers missing TR1, cxxomfort does implement the following few features only:

  • array (in cxxomfort/array.hpp).
  • reference_wrapper and helpers (in cxxomfort/functional.hpp).
  • Fundamental type traits (in cxxomfort/type_traits.hpp).

MSVC 2008 SP1 ships with a TR1 implementation that is functional for Cxxomfort's requirements. The implementation uses the same header files as the normal C++ headers, as such MSVC does not require a TR1 forwarder or any other special treatment; also the features live in the std::tr1 namespace. Cxxofort defines the macro CXXO_namespace_tr1 to this later value so that features such as hash can be pointed to.

MSVC 2012 and later do not have a std::tr1 namespace.

MSVC 2010 std::common_type

MSVC 2010 and 2010 SP1 ship with a broken implementation of std::common_type that is not variadic and can only take two types. Because this means that the name common_type is used, Cxxomfort can not extend this feature to more template arguments.

Code wanting to transparently use common_type can instead use cxxomfort::fix::common_type which will forward to the correct implementation (std or cxxomfort) depending on compiler version.

MSVC < 2013 and std::errc

MSVC 2010 and 2012 ship with a broken implementation of system_error's std::errc and its associated values, that can not be used as objects (because they are, strangely enough, a namespace in that implementation). Because this means that the name errc is used, Cxxomfort can not fix this feature.

Code wanting to transparently and portably use std::errc can instead use cxxomfort::fix::errc which will forward to the correct implementation (std or cxxomfort) depending on compiler version, as well as the helper function to_errc() to build errc values without having to name the type.

MSVC >= 2013

Cxxomfort is largely untested with compiler versions 1800 and above (MSVC 2013). These versions also include a number of variants such as the "November Update". The cxxomfort basics do function with MSVC 2013 but the supplementals are untested.

The ticket [70b70d8017] will track compatibility tests with MSVC 2012 and 2013.

As of early 2020, there is no intention to support MSVC 2015 and beyond.

No typeof

MSVC < 2010 lacks any semblance to a __typeof__ mechanism. As such, code using CXXO_TYPEOF or CXXO_DECLTYPE will fail to compile. See the general note on __typeof__.


Clang

Supported versions:

  • default / -std=c++03: 2.8; 3.0-3.6; 4.x; 5.x
  • -std=c++0x: 3.0-3.6
  • -std=c++11: 3.2-3.6; 4.x; 5.x
  • -std=c++14: undetermined
  • -std=c++17: undetermined

Most of the notes valid for GCC are also valid here.

clang-libc++

Cxxomfort has not been tested with Clang using libc++, and has no support for it as of the latest 2019 releases.

Rvalue-References

Clang supports C++11 rvalue-references as an extension in C++03. Cxxomfort may or may not pick rvalue-reference constructors in C++03 when using Clang, but no guarantees are provided.


Digital Mars

Lacking C++ Support

The compiler supports a limited subset of C++, lacking features such as inline struct initialization, template constructors and template conversion operators (see "Template Support" below). Because of this, as of latest 2020 releases of Cxxomfort the library is not guaranteed to compile beyond the Base featureset.

decltype

Digital Mars provides minimal support for the decltype feature, although it lacks some of the corrections from later revisions such as decltype 1.1. Cxxomfort defines the macros CXXO_TYPEOF and CXXO_DECLTYPE to use this feature.


Watcom 1.9 / OpenWatcom (beta)

Lacking C++ Support

The compiler supports a limited subset of C++, lacking features such as inline struct initialization, template constructors, correct ADL and template template parameters. See #general below and also https://github.com/open-watcom/open-watcom-v2/wiki/C---Language at the OpenWatcom wiki for more details. This also means classes such as istream and ostream families are implemented in a manner different than the Standard and there are entire base class families missing. Because of this, as of latest 2020 releases of Cxxomfort the library is not guaranteed to compile beyond the Base featureset.

As of May-October 2020, an effort is going to be made to provide at least a subset of features of Cxxomfort and other backports for Watcom 1.9 and OpenWatcom 2.0, with [b8ea55b791] being used as the tracking ticket.

Features confirmed to work as of September 2020 include:

  • std::array (if enabled internal TR1)
  • output operators for std::basic_string
  • std::byte (but not the to_integral helper)
  • string_view in a limited form
  • type_index in a limited form
  • any/all/none_of
  • rvoid
  • array_ref
  • fixed_vector
  • type_name()

Features planned to land "sometime in the future" as of September 2020 include:

  • std::valarray in a limited form.
  • std::forward_list in a limited form.
  • Different-range signatures for equal and mismatch.
  • std::optional (as part of Extras) (without the emplace construction support)
  • std::any (as part of Extras)
  • std::endian
  • memory management tools (destroy, uninitialized_copy, etc)
  • static math

Features believed to not be implementable as far as it's known as of September 2020 include:

  • "correct" move emulation
  • type category type_traits (is_enum etc)
  • std::unique_ptr
  • std::mem_fn (due to overloading and ADL template support issues)
  • std::bind (see above)
  • std::random_device
  • result_of, which needs compiler provisioning (correct typeof)
  • std::tuple, at least not with the get<N> interface
  • anything that uses std::tuple
  • std::variant
  • std::invoke

basic_istream, basic_ostream

Watcom 1.9 only supports the istream and ostream classes as sole classes, not templated on char type, and they inherit from ios rather than basic_ios; hence code that depends on prototypes for basic_istream or basic_ostream will fail to compile.

As of latest 2020 release Cxxomfort does not make any attempt to provide a basic_i/o_stream.

No TR1 Support

Watcom 1.9 / 2.0 beta has almost no support for C++ TR1 or its headers. As such <array>, <cstdint>, <tuple> all required by Cxxomfort are missing.

It is possible to enable partial TR1 support via the CXXOMFORT_USE_INTERNAL_TR1 macro. This enables backports for the following features as of September 2020:

  • array and its utilities
  • reference_wrapper and its utilities
  • basic category type_traits

nullptr

Watcom defines NULL as integral zero, and also lacks template conversion operators; as such, nullptr can not be implemented as per C++11 official backport. For this compiler, Cxxomfort defines nullptr to be integral zero, and std::nullptr_t as an empty type with an implicit conversion to null void pointer.

Template Support

See #general below.


General Notes

Compiler Lacks Basic C++ Support

Some old compilers might lack enough support for C++ features, in particular inline and templates that implementing a number of Cxxomfort features might be unfeasible. Cxxomfort requires, in order to provide proper support for the base features, compliance with template member operators (used by nullptr), zero-argument macros (needed for code generation tools), explicit template argument call (needed to implement explicit_cast), two-phase lookup and typenames (all required to implement eg.: begin/end iterator accessors, or move emulation).

Support for the various C++ backports requires even more extensive use of templates, in particular when it comes to stuff in <functional> or <tuple>.

In theory a compiler that lacks this level of support should declare __cplusplus to be a value below 199712UL and thus lack of features can be caught early in order to either provide a few minimal implementations or terminate early with #error; as of latest 2020 release, Cxxomfort takes neither approach.

Compiler Intrinsics

In order to work correctly, cxxomfort expects to find, for pre-C++11 compilers, support for a number of compiler intrinsics related to type and memory information. If those intrinsics are not found, the library is not guaranteed to work and might induce hard compilation fails.

  • __alignof(T) is needed by cxxomfort's base feature set.
  • The type category intrinsics __is_enum, __is_union and __is_class are expected and needed to be found when using per-compiler TR1 support.
  • The type/memory information intrinsics __is_pod and __is_abstract are expected when using per-compiler TR1 support.
  • __typeof(expr) is expected by cxxomfort's base feature set in order to set up CXXO_TYPEOF in compilers that have it.

#pragma messages

When using the macro CXXOMFORT_NOTICES to enable compilation logs, Cxxomfort makes use of #pragmas in order to emit the messages. It is implementation-defined by each compiler whether those notices are interpreted to be compilation messages or compilation warnings (which show in the build logs). As such, when setting CXXOMFORT_NOTICES on a project that uses such options as "treat warnings as errors", compilation should be expected to fail.

__typeof__

Compilers such as GCC >= 4.0 and CLang >= 3.1 implement the __typeof__ extension in all Standard modes, which returns the type corresponding to an expression: it is basically an earlier alternative to decltype.

Cxxomfort declares the CXXO_TYPEOF(expression) macro to return __typeof__ of the expression in C++03 mode, or decltype of the expression in later Standards.

Compilers without typeof will evaluate CXXO_TYPEOF to a non-resolvable type or expression and thus compilation will fail. User code wanting to check before use should check the value of CXXO_COMPILER_SUPPORT_typeof.

type_name

Using the library::type_name and typeid_demangle features require typeid support and thus RTTI to be enabled, and the <typeinfo> header to be included explicitly (Though an assist using compile-time type index is under study).


Proceed with the Configuration