Пустые макросы функции
Если я определяю макрос функции без фактической функции, это как пустая строка с компилятором (т.е. она не генерирует никаких дополнительных инструкций во время компиляции)?
Пример:
#define SomeMacro(a)
SomeMacro("hello"); // This line doesn't add any instructions, does it?
Ответы
Ответ 1
Вы абсолютно правы, пустой макрос не генерирует никакого кода.
Я видел два места, где это полезно. Во-первых, для устранения предупреждений, когда параметр функции не используется:
#define UNUSED(x)
int foo(int UNUSED(value))
{
return 42;
}
Во-вторых, когда вы используете условные выражения, чтобы определить, должен ли быть код или нет.
#ifdef LOGGING_ENABLED
#define LOG(x) log_message(x)
#else
#define LOG(x)
#endif
Ответ 2
Ваш код не совсем корректен, я предлагаю вам положить пустые фигурные скобки в ваш макрос
#define somemacro(a) {}
причина проста, код будет намного более безопасным!
возьмите этот пример:
if(Value)
somemacro(a)
else
somemacro(b)
Если макрос пуст, ваш код не будет компилироваться! (Ожидаемое первичное выражение перед "else" ). В любом случае некоторые правила стиля заставляют вас писать
if(Value)
{
somemacro(a)
}
else
{
somemacro(a)
}
поэтому это не будет проблемой.
Другой вариант - использовать ";" вместо "{}", но этот параметр в том же случае даст вам предупреждения о компиляции, в то время как пустые фигурные скобки не выдадут предупреждений и ошибок! (точка с запятой все еще лучше, даже если выдавать предупреждения);)
возьмем следующий случай
if(value)
somemacro(a);
else
somemacro(b);
будет расширяться до
if(value)
{};
else
{};
который не может скомпилироваться!
Вот почему макросы злы
(поскольку макросы являются простой заменой текста, правилом немых должно быть всегда пытаться вручную заменить код и посмотреть, что происходит, есть также инструменты, которые заменят макросы, показывая расширенный код.)
Догадаться, если есть полностью безопасный макрос? Да, это называется "NOP"
#define somemacro(a) ((void)0)
который будет работать в любом случае (даже исходные файлы компиляторов используют это как NOP, например
просто посмотрите на "assert.h"
Ответ 3
Это правильно. Ваш код расширяется до
;
после предварительной обработки.
Обратите внимание, что вы можете попросить своего компилятора показать вам код после предварительной обработки (в gcc, это параметр -E
, ваш компилятор может отличаться).
Ответ 4
Препроцессор выполняет литеральную замену всеми макросами.
Поэтому, если вы определяете "пустой" макрос, то каждое место, которое идентификатор появляется в вашем коде, будет заменено пустой инструкцией препроцессором до того, как компилятор когда-либо выполнит.
Так что да. Никакой код не будет создан для примера, указанного в вашем вопросе.