Skip to content

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__: 소스코드가 포함된 클래스 이름과 함수 이름을 이쁘게 반환.

가변인자 매크로에 대한 설명

#define TRACE(fmt, ...) printf(fmt, __VA_ARGS__)

보다,

#define TRACE(...) printf(__VA_ARGS__)

가 낫습니다. 왜냐하면 TRACE("hello")와 같이 썼을 때, 전자의 경우 아래와 같이 확장되며, 문법 에러가 됩니다:

printf("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

The warning directive is probably the closest you'll get, but it's not entirely platform-independent:

#warning "C Preprocessor got here!"

AFAIK this works on most compilers except MSVC, on which you'll have to use a pragma directive:

#pragma message ( "C Preprocessor got here!" )
#ifndef NPY_DEPRECATED_INCLUDES
#error "Should never include npy_*_*_deprecated_api directly."
#endif
#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

Windows

Taken from the Visual C docs, the most common ones are:

  • _WIN32: Both 32 bit and 64 bit
  • _WIN64: 64 bit only

MSVC

Unix (Linux, *BSD, Mac OS X)

  • unix
  • __unix
  • __unix__

GCC

Mac OS X

  • __APPLE__
  • __MACH__

Linux

FreeBSD

CLANG

Preprocessor checker

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

References


  1. The_type_of_c_preprocessor.pdf 

  2. Pragma-once_pack_warning_comment_link.pdf 

  3. Preprocessor-include_define_undef_if_else_endif_ifdef_elif_ifndef_defined_error_line.pdf