如何编写扩展为包含换行符的cpp宏?
我正在从事一个涉及许多预处理器宏功能的大型项目,以合成无法被模板替换的任何代码。相信我,我熟悉各种模板技巧,但只要没有可以直接创建代码的标准化,类型安全的元编程语言,我们就必须使用良好的旧预处理器及其繁琐的宏来解决一些不这样做,将需要编写更多十倍的代码。
一些宏跨很多行,很难在预处理代码中读取。因此,我想到了解决该问题的方法,而我想到的是以下内容:
假设我们有一个C / C ++宏,它跨越多行,例如在名为MyMacro.hpp的文件中
1 2 3 4 5 6 7 8
| // 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,其中包含以下内容:
1 2 3 4 5
| // Content of MultilineMacroDebugging.hpp
#ifndef HAVE_MULTILINE_DEBUGGING
#define __NL__
#endif |
这定义了一个空的宏__NL__,它使__NL__定义在预处理期间消失。然后可以在某个地方使用该宏,例如
在名为MyImplementation.cpp的文件中。
1 2 3 4 5 6 7 8 9
| // 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__字符串,瞧,您最终得到了经过预处理的替换宏结果的可读表示,这与编译器的输出完全相似。参见,除了人为引入的换行符。
C&C ++编译器会忽略未加引号的空格(>>模板问题除外),因此让宏发出换行符实际上没有任何意义。您可以通过将宏的每一行都用反斜杠结尾来使宏跨越多行,但这不会输出换行符。
这不可能。仅在查看清单文件或预处理器输出时才有意义。
编写宏以使它们更易于阅读的一种常用技术是使用字符将宏继续到下一行。
我(相信我)已经看到编译器在清单输出中的扩展宏中包含新行-为您带来好处。这仅对我们贫穷的人有用,他们阅读了扩展的宏以试图了解我们真正要求编译器执行的操作。它对编译器没有影响。
C和C ++语言以相同的方式对待字符串之外的所有空格。就像分隔符一样。
C编译器知道空格,但是不能区分空格,制表符或换行。
如果您的意思是如何在宏的字符串中添加新行,则:
1 2
| #define SOME_STRING"Some string
with a new line." |
将工作。
在行的末尾使用。我看过很多C macOS,它们在其中使用do ... while(0)
1 2 3 4 5 6
| #define foo() do \
{
//code goes here \
\
\
}while(0); |
另外,请记住在许多情况下都使用括号。
例:
1 2 3
| #define foo(x) a+b
//should be
#define foo(x) (a+b) |
不太确定您在这里问什么。您是否需要多行宏?
1 2 3
| #define NEWLINE_MACRO(x) line1 \
line2 \
line3 |
此外,如果您想在宏中包含文字:
1
| #define NEWLINE_MACRO(x) ##x |
您在x中输入的内容将被替换为## x,因此:
1
| NEWLINE_MACRO( line1 ) // is replaced with line1 |
这有助于制作自定义全局函数,然后只需要更改部分函数名即可。
也:
1
| #define NEWLINE_MACRO(x) #x // stringify x |
会在x周围加上引号
使用\,如下所示:
1 2 3 4
| #define my_multiline_macro(a, b, c) \
if (a) { \
b += c; \
} |