Вопрос по c++, c – Многострочные макросы препроцессора

57

Как сделать многострочный макрос препроцессора? Я знаю, как сделать одну строку:

<code>#define sqr(X) (X*X)
</code>

но мне нужно что-то вроде этого:

<code>#define someMacro(X)
    class X : public otherClass
    {
         int foo;
         void doFoo();
    };
</code>

Как я могу заставить это работать?

Это только пример, настоящий макрос может быть очень длинным.

разные методы здесь:parashift.com/c++-faq/macros-with-multi-stmts.html Ayrat
Вы можете легко получить ответ, выполнив поиск SO. напримерstackoverflow.com/questions/4007865/… Forever Learner

Ваш Ответ

4   ответа
11

ПОЖАЛУЙСТА, ОБРАТИТЕ ВНИМАНИ как указали Kerrek SB и coaddict, которые должны были быть указаны в принятом ответе,ВСЕГД ставьте скобки вокруг своих аргументов. Пример sqr - простой пример, который преподается на курсах CompSci.

Вот в чем проблема: если вы определите это так, как вы это сделали, что произойдет, когда вы скажете «sqr (1 + 5)»? Вы получаете "1 + 5 * 1 + 5" или 11
Если вы правильно расставите брекеты,#define sqr(x) ((x)*(x))
ты получаешь ((1 + 5) * (1 + 5)) или то, что мы хотели 36 ... красиво.

Эд С. будет иметь ту же проблему с «своп»

Я сделал это как упражнение и, видимо,iначение @ увеличивается, поскольку оно подставляется в макрос (в этом случае оно подставляется дважды), а затем умножается. Такsqr(++5) == ((7) * (7)) jiveturkey
как насчетsqr(++i)? (предположим, у нас естьint i):) Géza Török
@ GézaTörök Расширениеsqr(++i) в((++i)*(++i)) будет вызывать неопределенное поведение, потому что значениеi изменяется в этом выражении более одного раза (между операциями нет точки последовательности). moooeeeep
@ moooeeeep конечно, это то, на что я пытался указать Géza Török
94

Ты используешь\ как escape-символ продолжения строки.

#define swap(a, b) {               \
                       (a) ^= (b); \
                       (b) ^= (a); \
                       (a) ^= (b); \
                   }

EDIT: Как @abelenky указал в комментариях,\ персонаж должен быть последним символом в строке. Если это не так (даже если это просто пробел после), вы будете получать непонятные сообщения об ошибках в каждой строке после него.

Слово предостережения: убедитесь, что \ являетсяпрошло символ в строке. В Си пробелы обычно не имеют значения, но в этом случае невидимые пробелы в конце строки могут вас убить. abelenky
@ abelenky: Хорошо, спасибо. Ed S.
Один из них должен добавить, что полученный текст находится в одной строке. Поскольку C обрабатывает все пробелы между токенами одинаково, обычно это не имеет большого значения, но все же. Peter A. Schneider
Еще одна вещь, которую я бы предложил сделать, это разместить` after all useful lines of the macro, and add a comment afterward saying something like // Пустая строка требуется после макроса. It's sometimes easier to ensure that all lines of a macro end with `чем все, кроме последней строки. supercat
14

поставив обратную косую черту \) в конце каждой строки:

#define F(x) (x)   \
              *    \
             (x)
+ 1: за то, что не пропустили скобки вокругx -!) alk
2

экранируя ее с помощью\:

#define sqr(X) \
        ((X)*(X))

Похожие вопросы