C preprocessor
lastmod 2025-02-13created 2016-04-1915 edits
A macro is a keyword that tells the compiler about characteristics of the code. It is therefore an element needed in the process of compiling to machine code; the macro itself does not generate machine code, but it is used to control specific code.
List of C/C++ preprocessor
- MSVC
- MWCC
- BCC
- EDG
- DMC
Built-in macros
-
__DATE__: Replaced with the compile date as a string. -
__TIME__: Replaced with the compile time as a string. -
__LINE__: Replaced with the line number being compiled as an integer. -
__FILE__: Replaced with the name of the file currently being compiled as a string. -
__TIMESTAMP__: Replaced with the last modification date and time of the source file as a string. -
__VA_ARGS__: Stands in for variadic arguments (...). -
__cplusplus: determines if your compiler is in C or C++ mode. Usually used in headers -
__PRETTY_FUNCTION__: Returns the class name and function name containing the source code in a pretty format.
About variadic macros
Rather than the above,
is better. Because when you write TRACE("hello"), the former expands as follows and becomes a syntax error:
Visual C++ Preprocessor Reference
Describes the preprocessor as it is implemented in Microsoft C and C++.
| Preprocessor Directives | #define Directive, #error Directive, #import Directive, #include Directive, #line Directive, #undef Directive, #using Directive, Null Directive |
| Preprocessor Directives (Condition check) | #if, #elif, #else, and #endif Directives, #ifdef and #ifndef Directives |
| Preprocessor Operators | Stringizing Operator (#), Charizing Operator (#@), Token-Pasting Operator (##) |
| Predefined Macros | Macros and C++, Variadic Macros, Predefined Macros |
| Pragmas |
Print message
The warning directive is probably the closest you'll get, but it's not entirely platform-independent:
AFAIK this works on most compilers except MSVC, on which you'll have to use a pragma directive:
Print error message
#ifndef NPY_DEPRECATED_INCLUDES
#error "Should never include npy_*_*_deprecated_api directly."
#endif
Print warning message
#if defined(_WIN32)
#define _WARN___STR2__(x) #x
#define _WARN___STR1__(x) _WARN___STR2__(x)
#define _WARN___LOC__ __FILE__ "("_WARN___STR1__(__LINE__)") : Warning Msg: "
#pragma message(_WARN___LOC__"Using deprecated NumPy API, disable it by " \
"#defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION")
#elif defined(__GNUC__)
#warning "Using deprecated NumPy API, disable it by " \
"#defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION"
#endif
Pre-defined Compiler Macros
- Stackoverflow: How do I check OS with a preprocessor directive?
- Pre-defined Compiler Macros
- [https://blog.kowalczyk.info/article/j/guide-to-predefined-macros-in-c-compilers-gcc-clang-msvc-etc..html Guide to predefined macros in C++ compilers (gcc, clang, msvc etc.)]
Windows
Taken from the Visual C docs, the most common ones are:
-
_WIN32: Both 32 bit and 64 bit -
_WIN64: 64 bit only
MSVC
- MSDN: Predefined Macros
- MSDN: Support for C++11/14/17 features (Modern C++)
- Stackoverflow: How to Detect if I'm Compiling Code With Visual Studio 2008?
Unix (Linux, *BSD, Mac OS X)
-
unix -
__unix -
__unix__
GCC
Mac OS X
-
__APPLE__ -
__MACH__
Linux
- The Linux GCC HOWTO
-
__linux__
FreeBSD
CLANG
Preprocessor checker
- c++ - How to detect reliably Mac OS X, iOS, Linux, Windows in C preprocessor? - Stack Overflow
- Predefined Macros (The C Preprocessor)
- Pre-defined Compiler Macros / Wiki / OperatingSystems
The Boost:Preprocessor code contains code for checking the preprocessor. (/boost/preprocessor/config/config.hpp)
# /* **************************************************************************
# * *
# * (C) Copyright Paul Mensonides 2002-2011. *
# * (C) Copyright Edward Diener 2011. *
# * Distributed under the Boost Software License, Version 1.0. (See *
# * accompanying file LICENSE_1_0.txt or copy at *
# * http://www.boost.org/LICENSE_1_0.txt) *
# * *
# ************************************************************************** */
#
# /* See http://www.boost.org for most recent version. */
#
# ifndef BOOST_PREPROCESSOR_CONFIG_CONFIG_HPP
# define BOOST_PREPROCESSOR_CONFIG_CONFIG_HPP
#
# /* BOOST_PP_CONFIG_FLAGS */
#
# define BOOST_PP_CONFIG_STRICT() 0x0001
# define BOOST_PP_CONFIG_IDEAL() 0x0002
#
# define BOOST_PP_CONFIG_MSVC() 0x0004
# define BOOST_PP_CONFIG_MWCC() 0x0008
# define BOOST_PP_CONFIG_BCC() 0x0010
# define BOOST_PP_CONFIG_EDG() 0x0020
# define BOOST_PP_CONFIG_DMC() 0x0040
#
# ifndef BOOST_PP_CONFIG_FLAGS
# if defined(__GCCXML__)
# define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_STRICT())
# elif defined(__WAVE__)
# define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_STRICT())
# elif defined(__MWERKS__) && __MWERKS__ >= 0x3200
# define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_STRICT())
# elif defined(__EDG__) || defined(__EDG_VERSION__)
# if defined(_MSC_VER) && (defined(__INTELLISENSE__) || __EDG_VERSION__ >= 308)
# define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_MSVC())
# else
# define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_EDG() | BOOST_PP_CONFIG_STRICT())
# endif
# elif defined(__MWERKS__)
# define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_MWCC())
# elif defined(__DMC__)
# define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_DMC())
# elif defined(__BORLANDC__) && __BORLANDC__ >= 0x581
# define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_STRICT())
# elif defined(__BORLANDC__) || defined(__IBMC__) || defined(__IBMCPP__) || defined(__SUNPRO_CC)
# define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_BCC())
# elif defined(_MSC_VER) && !defined(__clang__)
# define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_MSVC())
# else
# define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_STRICT())
# endif
# endif
#
# /* BOOST_PP_CONFIG_EXTENDED_LINE_INFO */
#
# ifndef BOOST_PP_CONFIG_EXTENDED_LINE_INFO
# define BOOST_PP_CONFIG_EXTENDED_LINE_INFO 0
# endif
#
# /* BOOST_PP_CONFIG_ERRORS */
#
# ifndef BOOST_PP_CONFIG_ERRORS
# ifdef NDEBUG
# define BOOST_PP_CONFIG_ERRORS 0
# else
# define BOOST_PP_CONFIG_ERRORS 1
# endif
# endif
#
# /* BOOST_PP_VARIADICS */
#
# define BOOST_PP_VARIADICS_MSVC 0
# if !defined BOOST_PP_VARIADICS
# /* variadic support explicitly disabled for all untested compilers */
# if defined __GCCXML__ || defined __CUDACC__ || defined __PATHSCALE__ || defined __DMC__ || defined __CODEGEARC__ || defined __BORLANDC__ || defined __MWERKS__ || ( defined __SUNPRO_CC && __SUNPRO_CC < 0x5130 ) || defined __HP_aCC && !defined __EDG__ || defined __MRC__ || defined __SC__ || defined __IBMCPP__ || defined __PGI
# define BOOST_PP_VARIADICS 0
# /* VC++ (C/C++) */
# elif defined _MSC_VER && _MSC_VER >= 1400 && (!defined __EDG__ || defined(__INTELLISENSE__)) && !defined __clang__
# define BOOST_PP_VARIADICS 1
# undef BOOST_PP_VARIADICS_MSVC
# define BOOST_PP_VARIADICS_MSVC 1
# /* Wave (C/C++), GCC (C++) */
# elif defined __WAVE__ && __WAVE_HAS_VARIADICS__ || defined __GNUC__ && defined __GXX_EXPERIMENTAL_CXX0X__ && __GXX_EXPERIMENTAL_CXX0X__
# define BOOST_PP_VARIADICS 1
# /* EDG-based (C/C++), GCC (C), and unknown (C/C++) */
# elif !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L
# define BOOST_PP_VARIADICS 1
# else
# define BOOST_PP_VARIADICS 0
# endif
# elif !BOOST_PP_VARIADICS + 1 < 2
# undef BOOST_PP_VARIADICS
# define BOOST_PP_VARIADICS 1
# if defined _MSC_VER && _MSC_VER >= 1400 && (defined(__INTELLISENSE__) || !(defined __EDG__ || defined __GCCXML__ || defined __CUDACC__ || defined __PATHSCALE__ || defined __clang__ || defined __DMC__ || defined __CODEGEARC__ || defined __BORLANDC__ || defined __MWERKS__ || defined __SUNPRO_CC || defined __HP_aCC || defined __MRC__ || defined __SC__ || defined __IBMCPP__ || defined __PGI))
# undef BOOST_PP_VARIADICS_MSVC
# define BOOST_PP_VARIADICS_MSVC 1
# endif
# else
# undef BOOST_PP_VARIADICS
# define BOOST_PP_VARIADICS 0
# endif
#
# endif
A simpler version:
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
//define something for Windows (32-bit and 64-bit, this part is common)
#ifdef _WIN64
//define something for Windows (64-bit only)
#else
//define something for Windows (32-bit only)
#endif
#elif __APPLE__
#include <TargetConditionals.h>
#if TARGET_IPHONE_SIMULATOR
// iOS, tvOS, or watchOS Simulator
#elif TARGET_OS_MACCATALYST
// Mac's Catalyst (ports iOS API into Mac, like UIKit).
#elif TARGET_OS_IPHONE
// iOS, tvOS, or watchOS device
#elif TARGET_OS_MAC
// Other kinds of Apple platforms
#else
# error "Unknown Apple platform"
#endif
#elif __ANDROID__
// Below __linux__ check should be enough to handle Android,
// but something may be unique to Android.
#elif __linux__
// linux
#elif __unix__ // all unices not caught above
// Unix
#elif defined(_POSIX_VERSION)
// POSIX
#else
# error "Unknown compiler"
#endif
See also
Favorite site
- Wikipedia (en) C preprocessor
- Types of preprocessor directives (#include, #define, #ifdef, … ) 1
- pragma preprocessor directives
Documentation
Tip & Trick
- KLDP: Using the preprocessor #define do{ statement1; statement2; statement3 }while(0)
- [Recommended] Stackoverflow - Can we have recursive macros? (Issues with recursive use of macros)
- Detect empty macro arguments
- pragma - once, pack, warning, comment, link 2
- Preprocessor directives - #include, #define, #undef, #if, #else, #endif, #ifdef, #elif, #ifndef, defined(), #error, #line 3