C preprocessor
매크로는 컴퍼일러에게 코드의 특성을 알려주는 키워드 이다. 따라서 기계어로 컴파일 과정에서 필요한 요소이고, 매크로 자체가 기계어 코드로 생성 되지는 않지만 특정 코드를 제어하는데 사용 한다.
List of C/C++ preprocessor
- MSVC
- MWCC
- BCC
- EDG
- DMC
컴파일러 내장 매크로(Built-in macros)
-
__DATE__
: 컴파일 날짜를 문자열로 치환한다. -
__TIME__
: 컴파일하는 시간을 문자열로 치환한다. -
__LINE__
: 컴파일하고 있는 줄 번호를 정수형으로 치환한다. -
__FILE__
: 현재 컴파일 하고 있는 파일의 이름을 문자열로 치환한다. -
__TIMESTAMP__
: 소스 파일의 최종 변경 날짜와 시간을 문자열로 치환한다. -
__VA_ARGS__
: 가변인자(...)를 대신한다. -
__cplusplus
: determines if your compiler is in C or C++ mode. Usually used in headers -
__PRETTY_FUNCTION__
: 소스코드가 포함된 클래스 이름과 함수 이름을 이쁘게 반환.
가변인자 매크로에 대한 설명
보다,
가 낫습니다. 왜냐하면 TRACE("hello")
와 같이 썼을 때, 전자의 경우 아래와 같이 확장되며, 문법 에러가 됩니다:
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: C++11/14/17 기능에 대한 지원(최신 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
Boost:Preprocessor코드에 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
좀 더 간단한 버전:
#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
Documentation
Tip & Trick
- KLDP: 전처리기 #define do{ 문장1; 문장2; 문장3 }while(0) 사용
- [추천] Stackoverflow - Can we have recursive macros? (Macro의 재귀적 사용에 대한 이슈)
- Detect empty macro arguments
- pragma - once, pack, warning, comment, link 2
- 전처리기 지시어 - #include, #define, #undef, #if, #else, #endif, #ifdef, #elif, #ifndef, defined(), #error, #line 3