Скажем, что по какой-то причине вам нужно написать макрос: MACRO(X,Y)
. (Предположим, что есть хорошая причина, по которой вы не можете использовать встроенную функцию.) Вы хотите, чтобы этот макрос эмулировал вызов функции без возвращаемого значения.
Пример 1: Это должно работать как ожидалось.
if (x > y)
MACRO(x, y);
do_something();
Пример 2: Это не должно приводить к ошибке компилятора.
if (x > y)
MACRO(x, y);
else
MACRO(y - x, x - y);
Пример 3: Это не должно компилироваться.
do_something();
MACRO(x, y)
do_something();
Наивный способ записи макроса выглядит следующим образом:
#define MACRO(X,Y) \
cout << "1st arg is:" << (X) << endl; \
cout << "2nd arg is:" << (Y) << endl; \
cout << "Sum is:" << ((X)+(Y)) << endl;
Это очень плохое решение, в котором не все три примера, и мне не нужно объяснять, почему.
Игнорировать то, что на самом деле делает макрос, что не точка.
Теперь, как я чаще всего вижу написанные макросы, нужно заключить их в фигурные скобки, например:
#define MACRO(X,Y) \
{ \
cout << "1st arg is:" << (X) << endl; \
cout << "2nd arg is:" << (Y) << endl; \
cout << "Sum is:" << ((X)+(Y)) << endl; \
}
Это разрешает пример 1, потому что макрос находится в одном блоке оператора. Но пример 2 сломан, потому что мы положили точку с запятой после вызова макроса. Это заставляет компилятор думать, что точка с запятой - это оператор сам по себе, что означает, что оператор else не соответствует какому-либо оператору if! И, наконец, пример 3 компилируется в порядке, хотя точки с запятой нет, потому что блоку кода не требуется точка с запятой.
Есть ли способ написать макрос, чтобы он прошел все три примера?
Примечание. Я отправляю свой собственный ответ в качестве части принятого способа поделиться советом, но если у кого-то есть лучшее решение, не стесняйтесь публиковать сообщения он здесь, он может получить больше голосов, чем мой метод.:)