是否可以给自己的问题投票?
感谢Martin York的建议,我发现在Visual Studio中,解决方案看起来非常简单(需要进一步测试)。只需将所有预处理指令重命名为其他内容(不是有效的c++语法也可以),然后使用带有/P参数的cl.exe即可。
cl target.cpp /P
它生成一个
target.i
,并包含源代码去除注释的部分。只需将先前的指令重命名即可。可能需要删除cl.exe生成的
#line
指令。
这是因为根据MSDN,翻译的阶段如下:
字符映射
将源文件中的字符映射到内部源表示形式。在此阶段,三字符序列将被转换为单个字符的内部表示形式。
行拼接
以反斜杠()结尾且紧接着换行符的所有行都与源文件中的下一行连接起来,从物理行形成逻辑行。除非为空,否则源文件必须以不带反斜杠的换行符结尾。
标记化
将源文件分解为预处理标记和空格字符。源文件中的注释将替换为一个空格字符。换行符保留。
预处理
执行预处理指令并将宏展开到源文件中。#include语句在任何包含的文本上调用前面三个翻译步骤的翻译。
字符集映射
将所有源字符集成员和转义序列转换为其在执行字符集中的等效项。对于Microsoft C和C++,源和执行字符集都是ASCII。
字符串连接
所有相邻的字符串和宽字符串文字都将被连接。例如,"String " "concatenation"变为"String concatenation"。
翻译
所有标记都被语法和语义地分析;这些标记转换为目标代码。
链接
解析所有外部引用以创建可执行程序或动态链接库
在
标记化之前删除注释。因此,在预处理阶段期间,请确保没有任何内容可供处理(删除所有指令),其输出应该只是由前三个阶段处理的内容。
至于用户定义的.h文件,请使用/FI选项手动包含它们。生成的.i文件将是.cpp和.h的组合。没有注释。每个片段都以正确的文件名前缀#line开始。因此,可以通过编辑器轻松拆分它们。如果我们不想手动拆分它们,可能需要使用某些编辑器的宏/脚本功能来自动执行此操作。
现在,我们无需关心任何预处理指令。更好的是,行继续字符(反斜杠)已处理。
-#include "stdafx.h"
-#include <windows.h>
-#define NOERR
-#ifdef NOERR
whatever error line is ok
-#else
some error line if NOERR not defined
-#endif
void pr() ;
int _tmain(int argc, _TCHAR* argv[])
{
pr();
return 0;
}
void pr() {
printf(" /* ");
printf(" ");
printf\
("some weird lines \
with line continuation");
}
在执行
cl.exe vc8.cpp /P
之后,它会变成这样,然后在恢复指令(并删除#line)后可以再次输入到cl.exe中。
#line 1 "vc8.cpp"
-#include "stdafx.h"
-#include <windows.h>
-#define NOERR
-#ifdef NOERR
whatever error line is ok
-#else
some error line if NOERR not defined
-#endif
void pr() ;
int _tmain(int argc, _TCHAR* argv[])
{
pr();
return 0;
}
void pr() {
printf(" /* ");
printf(" ");
printf\
("some weird lines \
with line continuation");
}