我正在从事一个大型项目,该项目涉及大量预处理器宏函数来合成任何无法被模板替换的代码。相信我,我熟悉各种模板技巧,但只要没有可以直接创建代码的标准化、类型安全的元编程语言,我们就必须坚持使用好的旧预处理器及其繁琐的宏来解决一些问题如果没有,则需要编写十倍以上的代码。
一些宏跨越多行,在预处理代码中很难阅读。因此,我想到了一个解决这个问题的方法,我想出的是:
假设我们有一个跨多行的 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 宏,我只需取消注释MyImplementation.cpp 中定义宏HAVE_MULTILINE_DEBUGGING 的行。生成的代码当然不会编译,因为 __NL__ 宏导致未定义,这会导致它保留在已编译的代码中,但是可以对其进行预处理。
现在的关键步骤是使用您最喜欢的文本编辑器将预处理器输出中的 __NL__ 字符串替换为换行符,瞧,您最终会在预处理后得到替换宏的结果的可读表示,这与编译器会看到,除了人为引入的换行符。