Как сделать макрос многострочного препроцессора? Я умею составлять одну строчку:
#define sqr(X) (X*X)
но мне нужно что-то вроде этого:
#define someMacro(X)
class X : public otherClass
{
int foo;
void doFoo();
};
Как я могу заставить это работать?
Это только пример, настоящий макрос может быть очень длинным.
c++
c
c-preprocessor
шумный кот
источник
источник
Ответы:
Вы используете
\
как escape-символ продолжения строки.#define swap(a, b) { \ (a) ^= (b); \ (b) ^= (a); \ (a) ^= (b); \ }
РЕДАКТИРОВАТЬ: как @abelenky указал в комментариях,
\
символ должен быть последним символом в строке . Если это не так (даже если это будет просто пробел), вы получите запутанные сообщения об ошибках в каждой строке после него.источник
` 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
`, чтобы это было сделано во всех строках, кроме последней.Вы можете сделать макрос охватывающим несколько строк, поместив обратную косую черту (
\
) в конце каждой строки:#define F(x) (x) \ * \ (x)
источник
ПОЖАЛУЙСТА, ОБРАТИТЕ ВНИМАНИЕ, как указали Керрек С.Б. и coaddict, что должно было быть указано в принятом ответе, ВСЕГДА помещайте фигурные скобки вокруг своих аргументов. Пример sqr - это простой пример, изучаемый на курсах CompSci.
Вот в чем проблема: если вы определите это так, как вы это сделали, что произойдет, когда вы скажете «sqr (1 + 5)»? Вы получите «1 + 5 * 1 + 5» или 11
Если вы правильно разместите вокруг него фигурные скобки,
#define sqr(x) ((x)*(x))
вы получите ((1 + 5) * (1 + 5)) или то, что мы хотели 36 ... красиво.
Эд С. будет иметь ту же проблему с "свопом"
источник
sqr(++i)
? (предположим, что у нас естьint i
) :)i
, увеличивается по мере того, как он подставляется в макрос (в этом случае он заменяется дважды), а затем он умножается. Итакsqr(++5) == ((7) * (7))
sqr(++i)
to((++i)*(++i))
вызовет неопределенное поведение, потому что значениеi
модифицируется более одного раза в этом операторе (нет точки последовательности между операциями).Вам нужно экранировать новую строку в конце строки, экранировав ее с помощью
\
:#define sqr(X) \ ((X)*(X))
источник