如何在 cpp 宏中生成换行符?

2022-01-11 00:00:00 macros c++ c-preprocessor

如何编写扩展为包含换行符的 cpp 宏?

How do I write a cpp macro which expands to include newlines?

推荐答案

我正在做一个大型项目,该项目涉及大量预处理器宏函数来合成任何无法被模板替换的代码.相信我,我熟悉各种模板技巧,但只要没有可以直接创建代码的标准化、类型安全的元编程语言,我们将不得不坚持使用好的旧预处理器及其繁琐的宏来解决一些问题如果没有,则需要编写十倍以上的代码.一些宏跨越多行,在预处理代码中很难阅读.因此,我想到了解决该问题的方法,我想出的是以下内容:

I am working on a large project that involves a lot of preprocessor macro functions to synthesize any code that cannot be replaced by templates. Believe me, I am familiar with all sorts of template tricks, but as long as there is no standardized, type safe metaprogramming language that can directly create code, we will have to stick with good old preprocessor and its cumbersome macros to solve some problems that would require to write ten times more code without. Some of the macros span many lines and they are very hard to read in preprocessed code. Therefore, I thought of a solution to that problem and what I came up with is the following:

假设我们有一个跨多行的 C/C++ 宏,例如在一个名为 MyMacro.hpp

Let's say we have a C/C++ macro that spans multiple lines, e.g. in a file named 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,其中包含以下内容:

In every file where I defined such a macro, I include another file MultilineMacroDebugging.hpp that contains the following:

// Content of MultilineMacroDebugging.hpp

#ifndef HAVE_MULTILINE_DEBUGGING
#define __NL__
#endif

这定义了一个空宏__NL__,这使得__NL__定义在预处理过程中消失.然后可以在某处使用宏,例如在名为 MyImplementation.cpp 的文件中.

This defines an empty macro __NL__, which makes the __NL__ definitions disappear during preprocessing. The macro can then be used somewhere, e.g. in a file named 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__ 宏导致未定义,这会导致它保留在已编译的代码中,但是可以对其进行预处理.

If I need to debug the PRINT_VARIABLE macro, I just uncomment the line that defines the macro HAVE_MULTILINE_DEBUGGING in MyImplementation.cpp. The resulting code does of course not compile, as the __NL__ macro results undefined, which causes it to remain in the compiled code, but it can, however, be preprocessed.

现在的关键步骤是使用您最喜欢的文本编辑器将预处理器输出中的 __NL__ 字符串替换为换行符,瞧,您最终得到了替换后宏结果的可读表示除了人为引入的换行符之外,预处理与编译器所看到的完全相似.

The crucial step is now to replace the __NL__ string in the preprocessor output by newlines using your favorite text editor and, voila, you end up with a readable representation of the result of the replaced macro after preprocessing which resembles exactly what the compiler would see, except for the artificially introduced newlines.

相关文章