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