[cppx] Compiler-specific functionality abstracted

The cppx library so far relies on four areas of compiler-specific functionality:

  • debugger API implementation
    (e.g. trace to debugger),
  • fixed size types
    (although <stdint.h> could be used, that would introduce a dependency on e.g. Boost),
  • sillywarnings
    (turning off MSVC sillywarnings so as to be able to compile at highest warning level, and yes it works 🙂 ), and
  • in-namespace friendship declarations for class templates,
    (MSVC 7.1 requires non-standard syntax, fixed in MSVC 9.0).

Instead of peppering the code with preprocessor conditionals I’ve collected all the compiler specific functionality in header files that abstract away the compiler specific implementation, so that …

  • there are no preprocessor conditionals in ordinary source files (all centralized above!), and …
  • it’s very clearly apparent what is compiler specific, and how and where it’s implemented for each compiler and OS.

Each such abstracting header file relies on a general “select compiler” mechanism to include the proper compiler-specific file, using a macro CPPX_COMPILER_SPECIFIC_INCLUDE, like …

In abstracting header file [progrock/cppx/compiler_specific/friendship.h]:

#include <progrock/cppx/compiler_specific/include.h>
#include CPPX_COMPILER_SPECIFIC_INCLUDE( friendship.h )

… where the file included for a general standard-conforming compiler defines …

In file [progrock/cppx/compiler_specific/_generic/friendship.h]:

#define CPPX_TEMPLATE_FRIEND( template_args ) \
    template< template_args > friend

… while the file included for MSVC (Microsoft Visual C++) defines …

In file [progrock/cppx/compiler_specific/msvc/friendship.h]:

#if     _MSC_VER <= 0x0701
#   define  CPPX_TEMPLATE_FRIEND( template_args )   \
#   include <progrock/cppx/compiler_specific/_generic/friendship.h>

I’m not sure about which version of MSVC fixed this, but at least the friendship syntax is non-standard in MSVC 7.1 and is OK, conforming, in MSVC 9.0.

The general mechanism for bringing in the compiler-specific header, which is of course the C++ equivalent of old WWW “browser sniffing” and therefore sort of brittle and ungood, but probably the Lesser Evil for this kind of thing?:

In file [progrock/cppx/compiler_specific/include.h]:

#include    <progrock/cppx/macro_util.h>        // CPPX_CONCAT3

#if     defined( _MSC_VER )
#   define  CPPX_CSI_SUBDIR     msvc
#elif   defined( __GNUC__ )
#   define CPPX_CSI_SUBDIR      gnuc
#   define CPPX_CSI_SUBDIR      _generic

#define CPPX_CSI_DIR( maindir )                 \
    CPPX_CONCAT3( maindir, /, CPPX_CSI_SUBDIR )
#define CPPX_CSI_PATH( maindir, path )          \
    CPPX_CONCAT3( CPPX_CSI_DIR( maindir ), /, path )
#define CPPX_CSI_BRACKET_PATH( maindir, path )  \
    CPPX_CONCAT3( <, CPPX_CSI_PATH( maindir, path ), > )

// To avoid macro replacement a component of 'path' should not be all uppercase
// and should not be any of 'assert', 'errno', 'offsetof', 'setjmp', 'va_arg',
// 'va_end' or 'va_start', which are macros  --  see C++98 §

    CPPX_CSI_BRACKET_PATH( progrock/cppx/compiler_specific, path )

Hopefully I won’t get up against some functionality where this scheme doesn’t work well. So far it’s held up.


4 comments on “[cppx] Compiler-specific functionality abstracted

  1. Pingback: cppx: /W4, no warnings! (Disabling MSVC sillywarnings) | Alf on programming (mostly C++)

  2. Pingback: Hubris, significant spaces, g++ | Alf on programming (mostly C++)

  3. Pingback: 2010 in review | Alf on programming (mostly C++)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s