Предопределённые макросы¶
- Что такое предопределённые макросы и как их посмотреть
- Макросы, определяющие целевую архитектуру
- Макросы, определяющие целевую операционную систему
- Макросы, определяющие характеристики базовых и стандартных типов
- Макросы для имитации поведения gcc под x86
- Прочие макросы, которые взводятся всегда
- Прочие макросы, которые взводятся в зависимости от поданных опций
Что такое предопределённые макросы и как их посмотреть¶
Любая программа работает в некотором системном окружении. Общепринято, что информация о системном окружении и режимах трансляции передается от компилятора программе через предустановленные макроопределения. Ниже приведены имена и значения основных предопределенных макроопределений компилятора и описаны случаи, при которых они выставляются
Предопределённые макросы можно посмотреть следующим образом:
$ 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 - __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 - __revision__=0 зарезервировано на будущее, в будущих версиях компилятора возможны изменения значения для конкретных моделей процессора
Макросы архитектуры семейства 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__=125 соответствует первым двум числам версии компилятора
- __LCC_MINOR__=<val> значение равно последнему числу в номере версии компилятора. Например, для версии компилятора 1.25.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=c++98,-std=c++11,-std=c++0x,-std=c++14,-std=c++1y,-std=c++17,-std=c++1z - __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 <val> равно 199901L, в режиме языка C11 <val> равно 201112L
- __STDC_HOSTED__ в режиме языка C99 и C11
- __cplusplus=<val> в режиме C++98/C++03 <val> равно 199711L, в режиме C++11 <val> равно 201103L, в режиме C++14 <val> равно 201402L, в режиме C++17 <val> равно 201703L
- _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 730(по умолчанию) <val> равно 7, в режиме-gcc-version 550<val> равно 5, в режиме-gcc-version 480<val> равно 4, в режиме-gcc-version 440<val> равно 4 - __GNUC_MINOR__=<val> в режиме
-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 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 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
- __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__
