Стандарт С99 внес небольшие изменения и в препроцессор.
Возможно, самым важным изменением препроцессора является возможность обрабатывать макросы с переменным количеством аргументов. На переменное количество аргументов указывает многоточие (...), находящееся в определении макроса. Встроенный препроцессорный идентификатор __VA_ARGS__ определяет, куда будут подставляться аргументы. Например, после включения в программу определения
#define MyMax(...) max(__VA_ARGS__)
выражение
MyMax(a, b);
преобразуется в
max(a, b);
До обозначения переменного количества аргументов (...) макрос может иметь другие аргументы. Например, после определения
#define compare(compfunc, ...) compfunc(__VA_ARGS__)
оператор
compare(strcmp, "один", "два");
преобразуется в оператор
strcmp("один", "два");
Как видно из примера, встроенный идентификатор __VA_ARGS__ заменяется всеми остальными аргументами.
С выходом С99 в языке С появился еще один способ определять прагму в программе: оператор _Pragma. В общем виде этот оператор выглядит таким образом:
_Pragma("директива")
Здесь директива — это вызываемая прагма[1]. Появление оператора _Pragma дает прагмам возможность участвовать в макрозамене.
Прагма | Что означает |
---|---|
STDC FP_CONTRACT ON/OFF/DEFAULT | Во включенном состоянии (ON) выражения с плавающей точкой считаются неделимыми структурами, которые обрабатываются с помощью аппаратуры. Состояние по умолчанию (DEFAULT) определяется реализацией. |
STDC FENV_ACCESS ON/OFF/DEFAULT | Сообщает компилятору, что доступна аппаратура для выполнения операций с плавающей точкой. Состояние по умолчанию определяется реализацией. |
STDC CX_LIMITED_RANGE ON/OFF/DEFAULT | Во включенном состоянии (ON)сообщает компилятору, что некоторые формулы с составными значениями являются безопасными. Отключенное состояние (OFF) задается по умолчанию. |
Подробные сведения об этих прагмах должны быть приведены в документации по компилятору.
К макросам, поддерживаемым С89, в С99 добавлены следующие:
__STDC_HOSTED__ | 1, если имеется операционная система |
__STDC_VERSION__ | не меньше, чем 199901L; представляет версию языка С |
__STDC_IЕС_559__ | 1, если поддерживаются арифметические операции с плавающей запятой IEC 60559 |
__STDC_IEC_559_COMPLEX__ | 1, если поддерживаются арифметические операции с комплексными числами IEC 60559 |
__STDC_ISO_10646__ | Значение в виде гггглшЬ, которое указывает год и месяц выхода спецификации ISO/IEC 10646, поддерживаемой компилятором |
[1]Прагма называется также указанием транслятору, псевдокомментарием, директивой транслятора, указанием компилятору, директивой компилятора.