Подтвердить что ты не робот

Пустые макросы функции

Если я определяю макрос функции без фактической функции, это как пустая строка с компилятором (т.е. она не генерирует никаких дополнительных инструкций во время компиляции)?

Пример:

#define SomeMacro(a)

SomeMacro("hello"); // This line doesn't add any instructions, does it?
4b9b3361

Ответ 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

Препроцессор выполняет литеральную замену всеми макросами.

Поэтому, если вы определяете "пустой" макрос, то каждое место, которое идентификатор появляется в вашем коде, будет заменено пустой инструкцией препроцессором до того, как компилятор когда-либо выполнит.

Так что да. Никакой код не будет создан для примера, указанного в вашем вопросе.