Как мне написать макрос cpp, который расширяется и включает символы новой строки?
Как создать новую строку в макросе cpp?
Ответы (7)
Я работаю над большим проектом, который включает в себя множество макросов препроцессора для синтеза любого кода, который нельзя заменить шаблонами. Поверьте, я знаком со всевозможными трюками с шаблонами, но до тех пор, пока нет стандартизированного, безопасного типа языка метапрограммирования, который может напрямую создавать код, нам придется придерживаться старого доброго препроцессора и его громоздких макросов для решения некоторых проблем, которые потребовалось бы написать в десять раз больше кода без. Некоторые макросы занимают много строк, и их очень трудно прочитать в предварительно обработанном коде. Поэтому я подумал о решении этой проблемы и пришел к следующему:
Допустим, у нас есть макрос C / C ++, который занимает несколько строк, например в файле с именем MyMacro.hpp
// Content of MyMacro.hpp
#include "MultilineMacroDebugging.hpp"
#define PRINT_VARIABLE(S) \
__NL__ std::cout << #S << ": " << S << std::endl; \
__NL__ /* more lines if necessary */ \
__NL__ /* even more lines */
В каждый файл, в котором я определил такой макрос, я включаю другой файл MultilineMacroDebugging.hpp, который содержит следующее:
// Content of MultilineMacroDebugging.hpp
#ifndef HAVE_MULTILINE_DEBUGGING
#define __NL__
#endif
Это определяет пустой макрос __NL__
, из-за которого определения __NL__
исчезают во время предварительной обработки. Затем макрос можно где-нибудь использовать, например в файле с именем MyImplementation.cpp.
// Content of MyImplementation.cpp
// Uncomment the following line to enable macro debugging
//#define HAVE_MULTILINE_DEBUGGING
#include "MyMacro.hpp"
int a = 10;
PRINT_VARIABLE(a)
Если мне нужно отладить макрос PRINT_VARIABLE
, я просто раскомментирую строку, определяющую макрос HAVE_MULTILINE_DEBUGGING
в MyImplementation.cpp. Результирующий код, конечно, не компилируется, поскольку результат макроса __NL__
undefined, что заставляет его оставаться в скомпилированном коде, но его можно, однако, предварительно обработать.
Решающим шагом теперь является замена строки __NL__
в выводе препроцессора на новые строки с помощью вашего любимого текстового редактора, и, вуаля, вы получите удобочитаемое представление результата замененного макроса после предварительной обработки, которое в точности напоминает то, что увидел бы компилятор. за исключением искусственно введенных новых строк.
Это невозможно. Это было бы актуально только в том случае, если вы просматривали список файлов или вывод препроцессора.
Распространенным методом написания макросов, чтобы их было легче читать, является использование символа \ для продолжения макроса на следующей строке.
Я (полагаю, я) видел компиляторы, которые включают новые строки в расширенные макросы в выводе листинга - для вашей выгоды. Это полезно только для нас, бедных людей, читающих расширенные макросы, чтобы попытаться понять, что мы на самом деле просили сделать компилятор. для компилятора это не имеет значения.
Языки C и C ++ обрабатывают все пробелы вне строк одинаково. Просто как разделитель.
Компиляторы C и C ++ игнорируют пробелы без кавычек (за исключением проблемы с шаблоном>>), поэтому создание макроса для вывода новой строки на самом деле не имеет смысла. Вы можете сделать макрос охватывающим несколько строк, закрыв каждую строку макроса обратной косой чертой, но это не выводит символы новой строки.
Компилятор C знает о пробелах, но не различает пробелы, табуляции или новые строки.
Если вы имеете в виду, как сделать новую строку внутри строки в макросе, то:
#define SOME_STRING "Some string\n with a new line."
буду работать.
Не совсем понимаю, о чем вы здесь спрашиваете. Вы хотите, чтобы макрос состоял из нескольких строк?
#define NEWLINE_MACRO(x) line1 \
line2 \
line3
Кроме того, если вы хотите включить в макрос литерал:
#define NEWLINE_MACRO(x) ##x
то, что вы вставляете в x, будет заменено ## x, поэтому:
NEWLINE_MACRO( line1 ) // is replaced with line1
Это может быть полезно для создания настраиваемых глобальных функций, тогда просто нужно изменить часть имени функции.
Также:
#define NEWLINE_MACRO(x) #x // stringify x
Заключим x в кавычки
Используйте \ в конце строки. Я видел много C macos, где они использовали do ... while (0)
#define foo() do \
{
//code goes here \
\
\
}while(0);
Также не забывайте во многих случаях использовать круглые скобки.
Пример:
#define foo(x) a+b
//should be
#define foo(x) (a+b)
Используйте \
, например:
#define my_multiline_macro(a, b, c) \
if (a) { \
b += c; \
}
.S
). Итак, это три варианта использования fwiw - person jberryman   schedule 26.12.2016cpp
вclang-format
. Теперь получаю читаемый результат. - person Jean-Bernard Jansen   schedule 28.04.2017