C and C++ compilers automatically define certain macros that can be used to check for compiler or operating system features. This is useful when writing portable software.
These pages lists various pre-defined compiler macros that can be used to identify standards, compilers, operating systems, hardware architectures, and even basic run-time libraries at compile-time.
For example, if we want to use a generic or opaque pointer type, we use void pointers. However, ancient K&R compilers (from the time before the first ANSI C standard) do not support void pointers. Instead we can define our own type:
Another example, Microsoft Visual C++ version 4.2 added a pragma to reduce compilation times by only including a file once (if _MSC_VER is not defined then it will evaluate to 0 (zero) — however, some compilers may complain about an undefined macro)
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif
The macros contained in these pages have been obtained through vendor documentation, the defines script, contributors, and third-party source code. No guarantee about the correctness of the macros is given.
An often-used alternative is Autoconf, which is a more powerful tool to examine various types of features, including compilation options. However, Autoconf is fairly Unix-centric, and requires a Unix layer on other platforms (e.g. Cygwin on Windows). Other alternatives are Buildtool, CMake, SCons, PMK, Jam, Ant, and Bakefile.
Contributors
Bjorn Reese, Daniel Stenberg, Greg Roelofs, Steven G. Johnson, Wlodzimierz ABX Skiba, Marc Finet, Philip Newton, Mitchell Charity, Christian Klutz, Seo Sanghyeon, Chris Adami, Geoff Clare, Dan Fandrich, Mike Gorchak, Yuri D'Elia, Gynvael Coldwind, Alain Tauch, Vadim Zeitlin, Steve White, Thomas David Rivers, Tom Honermann, Martin Mitas, Dinesh Chhadwa, Erik Faye-Lund, Leo Davis, Paul Hsieh, Roland Schwarz, Darko Kolakovic, Andy Buonviri, Ming Kin Lai, Kent Johnson, Helmut Bauer, Oliver Schneider, Ron Pimblett, Jose Luis Rodriguez Garcia, Jeroen Ruigrok van der Werven, Uffe Jakobsen, Bryan Ashby, Bruno Haible, Artur Bac, Terry Schwarz, Leo Davis, Markus Duft, William Dang, Paul Green, Ruben Van Boxem, Pau Garcia i Quiles, Mikulas Patocka, Leo Davis, Mark Ferry, Holger Machens, Simon Watts, Paul Hargrove, Hans-Christoph Steiner, Gerald Combs, Denys Bulant, Massimo Morara, Jeremy Bennett, Guillem Jover, Riku Voipio, Jacques Pelletier, Mark Jarvin, Georg Sauthoff, Scot Jenkins, Grzegorz Brzęczyszczykiewicz, John Dallman, Gianmichele Toglia, Robbie Groenewoudt, Andreas Mohr, Алексей Пюрецкий, Sverre Hvammen Johansen, Stefan Tauner, Daniel Garcia, Ozkan Sezer, Dean Saridakis, Frank Long, Kevin Adler.
Notice that not all compliant compilers provides the correct pre-defined macros. For example, Microsoft Visual C++ does not define __STDC__, or Sun Workshop 4.2 supports C94 without setting __STDC_VERSION__ to the proper value. Extra checks for such compilers must be added.
Notice that some compilers, such as the HP aC++, use the value 199707L to indicate the C++98 standard. This value was used in an earlier proposal of the C++98 standard.
Example: Pre-C89
In continuation of the above example, pre-C89 compilers do not recognize certain keywords. Let the preprocessor remove those keywords for those compilers.
# if (_XOPEN_VERSION >= 4) && defined(_XOPEN_UNIX)
# define PREDEF_STANDARD_XOPEN_1995
# endif
# if (_XOPEN_VERSION >= 500)
# define PREDEF_STANDARD_XOPEN_1998
# endif
# if (_XOPEN_VERSION >= 600)
# define PREDEF_STANDARD_XOPEN_2003
# endif
# if (_XOPEN_VERSION >= 700)
# define PREDEF_STANDARD_XOPEN_2008
# endif
# endif
#endif
Notice that not all compliant compilers provides the correct pre-defined macros. For example, IBM xlC supports Unix without setting any of the __unix__ macros. Extra checks for such compilers must be added.
Notice
that clang also defines the GNU C version macros, but you should use the clang feature checking macros to detect the availability of various
features.
The
values of the __clang_major__, __clang_minor__,
and __clang_patchlevel__ macros
are not consistent across distributions of the Clang compiler. For example, the
Clang 3.1 distribution available at http://clang.llvm.org defines __clang_major__ and __clang_minor__ as 3 and 1 respectively.
The version of Clang distributed with Apple XCode 4.4 is branded as "Apple
Clang 4.0" and derives from the open source Clang 3.1 distribution, but
defines these macros with the values 4 and 0 respectively.
Apple's Clang distribution can be identified by the presence of the __apple_build_version__macro.
Notice
that the z/OS C/C++ compiler also defines __IBMC__ and __IBMCPP__ macros,
but with a different syntax. See the entry on the z/OS C/C++ compiler below for
further information.
This
is the XL C/C++ compiler for mainframes (e.g. z/OS). The entry on XL C/C++ has
been split into two for clarity.
Type
Macro
Format
Description
Identification
__IBMC__
Identification
__IBMCPP__
Version
__IBMC__ __IBMCPP__
NVRRM
N = Product (0 =
C/370, 1 = MVS, 2 = OS/390, 4 = z/OS)
V = Version
RR = Revision
P = Patch
Defined for z/OS XL C/C++
Version
__COMPILER_VER__
0xNVRRPPPP
N = Product (see
above)
V = Version
RR = Revision
PPPP = Patch
Defined for z/OS XL C/C++
Notice
that XL C/C++ also defines __IBMC__ and __IBMCPP__ macros,
but with a different syntax. You can use __xlC__ (only
defined for XL C/C++) or __COMPILER_VER__ (only
defined for z/OS C/C++) to distinguish between the two. Alternatively, the
macro identifying z/OS (__MVS__)
can be used to distinguish between them.
请发表评论