3.2 Макросы, похожие на функции
Вы также можете определять макросы, использование которых выглядит как вызов функции. Они называются макросами, похожими на функции. Для определения макроса, подобного функции, вы используете ту же директиву ‘#define’, но ставите пару скобок сразу после имени макроса. Например,
#define lang_init() c_init()
lang_init()
→ c_init()
Макрос, похожий на функцию, расширяется только тогда, когда его имя появляется со скобками после него. Если вы напишете только имя, оно останется без изменений. Это может быть полезно, когда у вас есть функция и макрос с одинаковым именем, и вы хотите иногда использовать функцию.
extern void foo(void);
#define foo() /* optimized inline version */
…
foo();
funcptr = foo;
Здесь вызов foo() будет использовать макрос, но указатель функции получит адрес реальной функции. Если бы макрос был расширен, это привело бы к синтаксической ошибке.
Если вы поместите пробелы между именем макроса и скобками в определении макроса, это не определяет макрос, похожий на функцию, а определяет макрос, похожий на объект, чьё расширение случайно начинается с пары скобок.
#define lang_init () c_init()
lang_init()
→ () c_init()()
Первые две пары скобок в этом расширении взяты из макроса. Третья пара — это пара, которая изначально стояла после вызова макроса. Поскольку lang_init — это макрос, похожий на объект, он не потребляет эти скобки.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-12.1.0/cpp/Function-like-Macros.html