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

Как создать новую строку в макросе cpp?

Как написать макрос cpp, который расширяется, чтобы включать символы новой строки?

4b9b3361

Ответ 1

Я работаю над большим проектом, который включает в себя множество макропроцессоров препроцессора для синтеза любого кода, который нельзя заменить шаблонами. Поверьте, мне знакомы всевозможные шаблонные трюки, но пока нет стандартизованного, типа безопасный язык метапрограммирования, который может напрямую создавать код, нам придется придерживаться старого старого препроцессора и его громоздких макросов, чтобы решить некоторые проблемы, которые потребовалось бы написать в десять раз больше кода без. Некоторые макросы охватывают многие строки, и их очень трудно читать в предварительно обработанном коде. Поэтому я подумал о решении этой проблемы, и я пришел к следующему:

Скажем, у нас есть макрос 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__ на выходе препроцессора с помощью новых строк, используя ваш любимый текстовый редактор, и, воала, вы получаете читаемое представление результата замененного макроса после предварительной обработки, которая точно напоминает то, что компилятор увидит, кроме искусственно введенных строк новой строки.

Ответ 2

Компиляторы C и С++ игнорируют пробелы без кавычек (кроме проблемы с шаблоном > ), поэтому получение макроса для испускания новых строк на самом деле не имеет смысла. Вы можете сделать макросмер нескольких строк, завершая каждую строку макроса обратным слэшем, но это не выводит символы новой строки.

Ответ 3

Это невозможно. Это было бы актуально только в том случае, если вы рассматривали файлы с листингами или выходные данные перед процессором.

Общей методикой написания макросов, чтобы их было легче читать, является использование символа \, чтобы продолжить макрос в следующей строке.

Я (верю, что я) видел компиляторы, которые включают новые строки в расширенных макросах в листинге вывода - для вашей выгоды. Это только полезно для нас, бедных людей, читающих расширенные макросы, чтобы попытаться понять, что мы действительно просили у компилятора. это не имеет никакого отношения к компилятору.

Языки C и С++ обрабатывают все пробелы вне строк таким же образом. Как разделитель.

Ответ 4

Компилятор C знает о пробеле, но он не различает пробелы, вкладки или новые строки.

Если вы имеете в виду, как у меня есть новая строка внутри строки в макросе, то:

#define SOME_STRING "Some string\n with a new line."

будет работать.

Ответ 5

Не совсем уверен, что вы спрашиваете здесь. Вам нужен макрос на нескольких строках?

#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

Ответ 6

Используйте \, например:

#define my_multiline_macro(a, b, c) \
if (a) { \
    b += c; \
}

Ответ 7

Используйте\в конце строки. Я видел много 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)