Предопределённые макросы

Что такое предопределённые макросы и как их посмотреть

Любая программа работает в некотором системном окружении. Общепринято, что информация о системном окружении и режимах трансляции передается от компилятора программе через предустановленные макроопределения. Ниже приведены имена и значения основных предопределенных макроопределений компилятора и описаны случаи, при которых они выставляются

Предопределённые макросы можно посмотреть следующим образом:

$ lcc -dM -E -xc /dev/null

Данный запуск покажет все установленные на конец препроцессирования макросы. Поскольку мы подаём пустой файл в режиме Си, то это означает, что мы увидим все предустановленные макросы в режиме Си. Если нужен режим Си++, то вместо опции -xc нужно подать опцию -xc++. Если подать опцию -mptr128, то в печати дополнительно появятся макросы, которые включается в защищённом режиме, если подать опцию -O2, то в печати дополнительно появятся макросы, которые включаются в режиме с оптимизациями и т.п.

Предопределённый макрос эквивалентен тому, что в в самом начале каждого компилируемого файла из командной строки появляется соответствующая директива #define. Или, что тоже самое, в компиляцию подаются соответствующие опции -D. По правилам языков Си/Си++ при наличии конструкции типа #define XXX (т.е. задаётся имя макроса, но не задаётся его значение) макрос устанавливается в значение 1. То же самое касается и предопределённых макросов. Т.е. если в описании просто задано имя макроса, то в соотвествии с правилами значение макроса будет выставлено в 1. За исключением случаев, когда это явным образом оговорено

Макросы, помеченные как “DEPRECATED”, возможно, в будущем будут удалены, а потому их НЕ рекомендуется использовать

Макросы, определяющие целевую архитектуру

Макросы архитектуры семейства E2K:

  • __e2k__

  • __iset__=2 взводится в режимах -march=elbrus-v2, -mtune=elbrus-2c+

  • __iset__=3 взводится в режимах -march=elbrus-v3, -mtune=elbrus-4c

  • __iset__=4 взводится в режимах -march=elbrus-v4, -mtune=elbrus-8c, -mtune=elbrus-1c+

  • __iset__=5 взводится в режимах -march=elbrus-v5, -mtune=elbrus-8c2

  • __iset__=6 взводится в режимах -march=elbrus-v6, -mtune=elbrus-12c, -mtune=elbrus-16c, -mtune=elbrus-2c3

  • __iset__=7 взводится в режимах -march=elbrus-v7

  • __elbrus_2cplus__ взводится в режиме -mtune=elbrus-2c+

  • __elbrus_4c__ взводится в режиме -mtune=elbrus-4c

  • __elbrus_8c__ взводится в режиме -mtune=elbrus-8c

  • __elbrus_1cplus__ взводится в режиме -mtune=elbrus-1c+

  • __elbrus_8c2__ взводится в режиме -mtune=elbrus-8c2

  • __elbrus_12c__ взводится в режиме -mtune=elbrus-12c``

  • __elbrus_16c__ взводится в режиме -mtune=elbrus-16c

  • __elbrus_2c3__ взводится в режиме -mtune=elbrus-2c3

Макросы архитектуры семейства E90:

  • __sparc, __sparc__, sparc последний взводится только при отсутствии режима -ansi

  • __sparcv9 взводится в режиме -m64 (DEPRECATED)

  • __sparc_v8__ взводится в режиме -mcpu=v8

  • __sparc_v9__ взводится в режимах -mcpu=v9, -mcpu=ultrasparc, -mcpu=ultrasparc3, -mcpu=r1000, -mcpu=r2000, -mcpu=r2000+

  • __r1000__ взводится в режиме -mcpu=r1000

  • __r2000__ взводится в режиме -mcpu=r2000

  • __r2000plus__ взводится в режиме -mcpu=r2000+

  • __arch64__ взводится в режиме -m64

Макросы, определяющие режимы адресации:

  • __ptr32__ для E2K в режиме -mptr32, для E90 в режиме -m32

  • __ptr64__ для E2K в режиме -mptr64, для E90 в режиме -m64

  • __ptr128__ для E2K в режиме -mptr128

  • __PROTECTED__ эквивалентен __ptr128__ (DEPRECATED)

  • __64__ для E2K в единственно возможном режиме -mptr64 на операционной системе qnx (КПДА)

  • _LP64, __LP64__ для E2K в режиме -mptr64, для E90 в режиме -m64

Макросы, определяющие целевую операционную систему

  • __gnu_linux__, __linux, __linux__, linux взводится для компиляторов под linux. Последний взводится только при отсутствии режима -ansi

  • __QNXNTO__, __QNX__ взводится для компиляторов под qnx (КПДА)

Макросы, определяющие характеристики базовых и стандартных типов

Данные макросы введены для совместимости с компилятором gcc и используются в том числе и в стандартных заголовочных файлах limits.h и float.h

Макросы, задающие байтовые размеры типов:

  • __CHAR_BIT__=8

  • __SIZEOF_SHORT__=2

  • __SIZEOF_INT__=4

  • __SIZEOF_LONG__=<val> для E2K в режиме -mptr32, E90 в режиме -m32 <val> равно 4, в остальных случаях - 8

  • __SIZEOF_LONG_LONG__=8

  • __SIZEOF_INT128__=16 кроме E90 режима -m32

  • __SIZEOF_FLOAT__=4

  • __SIZEOF_DOUBLE__=8

  • __SIZEOF_LONG_DOUBLE__=16

  • __SIZEOF_FLOAT128__=16

  • __SIZEOF_POINTER__=<val> для E2K в режиме -mptr128 <val> равно 16, для E2K в режиме -mptr32, E90 в режиме -m32 <val> равно 4, в остальных случаях - 8

  • __SIZEOF_SIZE_T__=<val> для E2K в режиме -mptr32, E90 в режиме -m32 <val> равно 4, в остальных случаях - 8

  • __SIZEOF_PTRDIFF_T__=<val> для E2K в режиме -mptr32, E90 в режиме -m32 <val> равно 4, в остальных случаях - 8

  • __SIZEOF_WCHAR_T__=4

  • __SIZEOF_WINT_T__=4

Макросы, задающие битовые размеры типов:

  • __SCHAR_WIDTH__ - битовый размер типа char

  • __SHRT_WIDTH__ - битовый размер типа short

  • __INT_WIDTH__ - битовый размер типа int

  • __LONG_WIDTH__ - битовый размер типа long

  • __LONG_LONG_WIDTH__ - битовый размер типа long long

  • __PTRDIFF_WIDTH__ - битовый размер типа ptrdiff_t

  • __SIG_ATOMIC_WIDTH__ - битовый размер типа sig_atomic_t

  • __SIZE_WIDTH__ - битовый размер типа size_t

  • __WCHAR_WIDTH__ - битовый размер типа wchar_t

  • __WINT_WIDTH__ - битовый размер типа wint_t

  • __INT_LEAST8_WIDTH__ - битовый размер типа int_least8_t

  • __INT_LEAST16_WIDTH__ - битовый размер типа int_least16_t

  • __INT_LEAST32_WIDTH__ - битовый размер типа int_least32_t

  • __INT_LEAST64_WIDTH__ - битовый размер типа int_least64_t

  • __INT_FAST8_WIDTH__ - битовый размер типа int_fast8_t

  • __INT_FAST16_WIDTH__ - битовый размер типа int_fast16_t

  • __INT_FAST32_WIDTH__ - битовый размер типа int_fast32_t

  • __INT_FAST64_WIDTH__ - битовый размер типа int_fast64_t

  • __INTPTR_WIDTH__ - битовый размер типа intptr_t

  • __INTMAX_WIDTH__ - битовый размер типа intmax_t

Макросы, задающие максимальные величины целочисленных типов:

  • __SIGNED_CHARS__ - при отсутствии режима -funsigned-chars

  • __SCHAR_MAX__=127

  • __SHRT_MAX__=32767

  • __INT_MAX__=2147483647

  • __LONG_MAX__=<val> для E2K в режиме -mptr32, E90 в режиме -m32 <val> равно 2147483647L, в остальных случаях - 9223372036854775807L

  • __LONG_LONG_MAX__=9223372036854775807LL

  • __INTMAX_MAX__=9223372036854775807LL

  • __WCHAR_MAX__=2147483647

  • __WCHAR_MIN__=(-__WCHAR_MAX__ - 1)

  • __WINT_MAX__=4294967295U

  • __WINT_MIN__=0U

  • __PTRDIFF_MAX__=<val> для E2K в режимах -mptr64 и -mptr128, E90 в режиме -m64 <val> равно 9223372036854775807L, для E2K в режиме -mptr32 <val> равно 2147483647L, для E90 в режиме -m32 <val> равно 2147483647

  • __SIZE_MAX__=<val> для E2K в режимах -mptr64 и -mptr128, E90 в режиме -m64 <val> равно 18446744073709551615UL, для E2K в режиме -mptr32 <val> равно 4294967295UL, для E90 в режиме -m32 <val> равно 4294967295U

Макросы, задающие стандартные типы из stddef.h:

  • __SIZE_TYPE__=<val> описывает тип size_t. Для E2K в режиме -mptr32, E90 в режиме -m32 <val> равно unsigned int, в остальных случаях - unsigned long

  • __PTRDIFF_TYPE__=<val> описывает тип ptrdiff_t. Для E2K в режиме -mptr32, E90 в режиме -m32 <val> равно int, в остальных случаях - long

  • __WCHAR_TYPE__=int описывает тип wchar_t

Макросы, задающие характеристики типа float:

  • __FLT_RADIX__=2

  • __FLT_EVAL_METHOD__=0

  • __FLT_MANT_DIG__=24

  • __FLT_DIG__=6

  • __FLT_MIN_EXP__=(-125)

  • __FLT_MIN_10_EXP__=(-37)

  • __FLT_MAX_EXP__=128

  • __FLT_MAX_10_EXP__=38

  • __FLT_MIN__=1.175494351E-38F

  • __FLT_MAX__=3.402823466E+38F

  • __FLT_EPSILON__=1.192092896E-07F

  • __FLT_DENORM_MIN__=1.40129846e-45F

  • __FLT_HAS_INFINITY__=1

  • __FLT_HAS_QUIET_NAN__=1

  • __FLT_HAS_DENORM__=1

Макросы, задающие характеристики типа double:

  • __DBL_MANT_DIG__=53

  • __DBL_DIG__=15

  • __DBL_MIN_EXP__=(-1021)

  • __DBL_MIN_10_EXP__=(-307)

  • __DBL_MAX_EXP__=1024

  • __DBL_MAX_10_EXP__=308

  • __DBL_MIN__=2.2250738585072014E-308

  • __DBL_MAX__=1.7976931348623157E+308

  • __DBL_EPSILON__=2.2204460492503131E-16

  • __DBL_DENORM_MIN__=4.9406564584124654e-324

  • __DBL_HAS_INFINITY__=1

  • __DBL_HAS_QUIET_NAN__=1

  • __DBL_HAS_DENORM__=1

Макросы, задающие характеристики типа long double на E2K (взводятся только на E2K):

  • __LDBL_MANT_DIG__=64

  • __LDBL_DIG__=18

  • __LDBL_DECIMAL_DIG__=21

  • __LDBL_MIN_EXP__=(-16381)

  • __LDBL_MIN_10_EXP__=(-4931)

  • __LDBL_MAX_EXP__=16384

  • __LDBL_MAX_10_EXP__=4932

  • __LDBL_MIN__=3.3621031431120935062627E-4932L

  • __LDBL_MAX__=1.1897314953572317650213E+4932L

  • __LDBL_EPSILON__=1.0842021724855044340075E-19L

  • __LDBL_DENORM_MIN__=3.64519953188247460253e-4951L

  • __LDBL_HAS_INFINITY__=1

  • __LDBL_HAS_QUIET_NAN__=1

  • __LDBL_HAS_DENORM__=1

  • __DECIMAL_DIG__=21

Макросы, задающие характеристики типа long double на E90 (взводятся только на E90):

  • __LDBL_MANT_DIG__=113

  • __LDBL_DIG__=33

  • __LDBL_DECIMAL_DIG__=36

  • __LDBL_MIN_EXP__=(-16381)

  • __LDBL_MIN_10_EXP__=(-4931)

  • __LDBL_MAX_EXP__=16384

  • __LDBL_MAX_10_EXP__=4932

  • __LDBL_MIN__=3.362103143112093506262677817321752603E-4932L

  • __LDBL_MAX__=1.189731495357231765085759326628007016E+4932L

  • __LDBL_EPSILON__=1.925929944387235853055977942584927319E-34L

  • __LDBL_DENORM_MIN__=6.47517511943802511092443895822764655e-4966L

  • __LDBL_HAS_INFINITY__=1

  • __LDBL_HAS_QUIET_NAN__=1

  • __LDBL_HAS_DENORM__=1

  • __DECIMAL_DIG__=36

Исторические рудименты:

  • __LONG_DOUBLE_128__ взводится для E90 в режиме -m32

Макросы для имитации поведения gcc под x86

Данные макросы поддерживаются только на E2K

  • __MMX__ - в режиме -mmmx

  • __SSE__ - в режиме -msse

  • __SSE2__ - в режиме -msse2

  • __SSSE3__ - в режиме -msse3

  • __SSE4_1__ - в режиме -msse4.1

  • __SSE4_2__ - в режиме -msse4.1

  • __AVX__ - в режиме -mavx

  • __3dNOW__ - в режиме -m3dnow

  • __3dNOW_A__ - в режиме -m3dnowa

  • __SSE4A__ - в режиме -msse4a

  • __FMA4__ - в режиме -mfma4

  • __XOP__ - в режиме -mxop

  • __AES__ - в режиме -maes

  • __PCLMUL__ - в режиме -mpclmul

  • __RDRND__ - в режиме -mrdrnd

  • __BMI__ - в режиме -mbmi

  • __TBM__ - в режиме -mtbm

  • __ABM__ - в режиме -mabm

  • __F16C__ - в режиме -mf16c

  • __POPCNT__ - в режиме -mpopcnt

  • __RDSEED__ - в режиме -mrdseed

  • __LZCNT__ - в режиме -mlzcnt

  • __MWAITX__ - в режиме -mmwaitx

  • __CLZERO__ - в режиме -mclzero

  • __CLFLUSHOPT__ - в режиме -mclflushopt

  • __CLWB__ - в режиме -mclwb

  • __BMI2__ - в режиме -mbmi2

  • __FMA__ - в режиме -mfma

  • __AVX2__ - в режиме -mavx2

  • __SHA__ - в режиме -msha

Прочие макросы, которые взводятся всегда

Оговоримся, что подразумевается под “всегда”. Есть макросы, которые взводятся только для E2K, но не взводятся для E90. В этом смысле по отношению к E2K это означает “всегда”. Есть макросы, которые взводятся всегда, но в зависимости от целевой архитектуры значение макроса может меняться. Но по отношению к тому, что макрос присутствует или отсутсвует это так же означает “всегда”

  • __MCST__

  • __LCC__=127 соответствует первым двум числам версии компилятора

  • __LCC_MINOR__=<val> значение равно последнему числу в номере версии компилятора. Например, для версии компилятора lcc-1.27.06, <val> равно 6

  • __unix, __unix__, unix последний взводится только при отсутствии режима -ansi

  • __ELF__

  • __LONG_DOUBLE__=<val> для E2K <val> равно 80, для E90 - 128

  • _LITTLE_ENDIAN взводится только для E2K (DEPRECATED)

  • __ORDER_LITTLE_ENDIAN__=1234

  • __ORDER_BIG_ENDIAN__=4321

  • __ORDER_PDP_ENDIAN__=3412

  • __BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__ взводится только для E2K

  • __FLOAT_WORD_ORDER__=__ORDER_LITTLE_ENDIAN__ взводится только для E2K

  • __BYTE_ORDER__=__ORDER_BIG_ENDIAN__ взводится только для E90

  • __FLOAT_WORD_ORDER__=__ORDER_BIG_ENDIAN__ взводится только для E90

  • __PRAGMA_REDEFINE_EXTNAME

  • __STDC__

  • __DATE__=<val> выставляется в строковой литерал с датой компиляции, например “Feb 13 2012”

  • __TIME__=<val> выставляется в строковой литерал с временем компиляции, например “13:48:01”

  • __FILE__=<val> выставляется в строковой литерал с именем файла, соответствующего точке использования макроса, например “t.c”

  • __LINE__=<val> выставляется в номер строки, соответствующего точке использования макроса, например 10

  • __USER_LABEL_PREFIX__ значение макроса равно пустышке (а не 1, как это бы следовало из общих правил)

  • __REGISTER_PREFIX__ значение макроса равно пустышке (а не 1, как это бы следовало из общих правил)

  • __GFORTRAN__ взводится при запуске lfortran’а

Прочие макросы, которые взводятся в зависимости от поданных опций

  • __STRICT_ANSI__ в режимах -ansi, -std=c89, -std=iso9899:1990, -std=iso9899:199409, -std=c99, -std=c9x, -std=iso9899:1999, -std=c11, -std=c1x, -std=iso9899:2011, -std=c17, -std=c18, -std=iso9899:2017, -std=iso9899:2018, -std=c++98, -std=c++11, -std=c++0x, -std=c++14, -std=c++1y, -std=c++17, -std=c++1z, -std=c++2a

  • __OPTIMIZE__ в режимах с оптимизациями

  • __FAST_MATH__ в режиме -ffast-math

  • __EXCEPTIONS в режиме -fexceptions

  • _REENTRANT в режиме -pthreads

  • __VIS=<val> только для E90 в режиме -mvis: в режиме -mcpu=ultrasparc <val> равно 0x100, в режиме -mcpu=ultrasparc3 - 0x200, в режимах -mcpu=r1000 и -mcpu=r2000 - 0x300, в режиме -mcpu=r2000+ - 0x400

  • _OPENMP=201107 - в режиме -fopenmp

  • __NO_INLINE__ в случае если НЕ используются оптимизации и НЕ используется профилирование

  • _GNU_SOURCE в режиме C++

  • __GXX_WEAK__ в режиме C++

  • __DEPRECATED в режиме C++ -Wdeprecated

  • __STDC_VERSION__=<val> в режиме языка C99 и выше. В режиме C99 <val> равно 199901L, в режиме C11 <val> равно 201112L, в режиме C18 <val> равно 201710L

  • __STDC_HOSTED__ в режиме языка C99 и выше

  • __cplusplus=<val> в режиме языка C++. В режиме C++98/C++03 <val> равно 199711L, в режиме C++11 <val> равно 201103L, в режиме C++14 <val> равно 201402L, в режиме C++17 <val> равно 201703L, в режиме C++20 <val> равно 202002L

  • _WCHAR_T в режиме языка C++. Макрос означает наличие поддержки ключевого слова wchar_t

  • _BOOL в режиме языка C++. Макрос означает наличие поддержки ключевого слова bool

  • __ARRAY_OPERATORS в режиме языка C++. Макрос означает наличие поддержки операторов new[] и delete[]

  • __RTTI в режиме языка C++ в режиме -frtti. Макрос означает наличие поддержки RTTI (Run-Time Type Information)

  • __PLACEMENT_DELETE в режиме языка C++. Макрос означает наличие поддержки оператора “placement delete”

  • __EDG_RUNTIME_USES_NAMESPACES в режиме языка C++

  • __EDG_IA64_ABI в режиме языка C++. Макрос означает использование IA64_ABI при работе с Си++

  • __EDG_IA64_ABI_USE_INT_STATIC_INIT_GUARD в режиме языка C++

  • __EDG_TYPE_TRAITS_ENABLED в режиме языка C++ в режиме -fno-gnu

  • __GNUC__=<val> в режиме -gcc-version 930 (по умолчанию) <val> равно 9, в режиме -gcc-version 730 <val> равно 7, в режиме -gcc-version 550 <val> равно 5, в режиме -gcc-version 480 <val> равно 4, в режиме -gcc-version 440 <val> равно 4

  • __GNUC_MINOR__=<val> в режиме -gcc-version 930 (по умолчанию) <val> равно 3, в режиме -gcc-version 730 <val> равно 3, в режиме -gcc-version 550 <val> равно 5, в режиме -gcc-version 480 <val> равно 8, в режиме -gcc-version 440 <val> равно 4

  • __GNUC_PATCHLEVEL__=<val> в режиме -gcc-version 930 (по умолчанию) <val> равно 0, в режиме -gcc-version 730 <val> равно 0, в режиме -gcc-version 550 <val> равно 0, в режиме -gcc-version 480 <val> равно 0, в режиме -gcc-version 440 <val> равно 0

  • __GNUG__=<val> макрос взводится в режиме C++, <val> совпадает со значением макроса __GNUC__

  • __VERSION__=<val> в режиме -gcc-version 930 (по умолчанию) <val> равно “9.3”, в режиме -gcc-version 730 <val> равно “7.3”, в режиме -gcc-version 550 <val> равно “5.5”, в режиме -gcc-version 480 <val> равно “4.8”, в режиме -gcc-version 440 <val> равно “4.4”

  • __FINITE_MATH_ONLY__ в режиме -ffinite-math-only

  • __GXX_EXPERIMENTAL_CXX0X__ в режимах C++11, C++14, C++17, C++20

  • __CHAR_UNSIGNED__ в режиме -funsigned-char

  • __SIGNED_CHARS__ в режиме -fsigned-char (по умолчанию)

  • __SANITIZE_ADDRESS__ в режиме -fsanitize=address

  • __pic__=<val> взводится в режимах -fpic, -fPIC, -fpie, -fPIE. В режимах -fpic и -fpie <val> равно 1, в остальных случаях <val> равно 2

  • __PIC__=<val> эквивалентно макросу __pic__

  • __pie__=<val> взводится в режимах -fpie, -fPIE. В режиме -fpie <val> равно 1, в остальных случаях <val> равно 2

  • __PIE__=<val> эквивалентно макросу __pie__