C++ 有没有办法逃逸C预处理器指令?

C++ 有没有办法逃逸C预处理器指令?,c++,c,escaping,c-preprocessor,C++,C,Escaping,C Preprocessor,我试图做的是让C预处理器输出#ifdef,#else和#endif指令。也就是说,我想以某种方式“转义”一个指令,以便预处理器的输出包括在输出上运行的预处理器的指令 是否可以“转义”CPP指令,使其由预处理器输出,从而使转义指令的输出在CPP输出本身进行预处理时成为预处理器指令?编辑:以下答案仅适用于CPP的早期版本。它介于4.2.1和4.3.2之间gcc-E和g++-E更早实现盈亏平衡。有关详细信息,请参见注释 以下是一个似乎有效的技巧: #define HASH() # ... HAS

我试图做的是让C预处理器输出
#ifdef
#else
#endif
指令。也就是说,我想以某种方式“转义”一个指令,以便预处理器的输出包括在输出上运行的预处理器的指令


是否可以“转义”CPP指令,使其由预处理器输出,从而使转义指令的输出在CPP输出本身进行预处理时成为预处理器指令?

编辑:以下答案仅适用于
CPP
的早期版本。它介于4.2.1和4.3.2之间
gcc-E
g++-E
更早实现盈亏平衡。有关详细信息,请参见注释


以下是一个似乎有效的技巧:

#define HASH() #

...

HASH()ifdef __cplusplus
class foo { };
HASH()endif
您必须直接使用
cpp
,因为编译器会尝试立即使用预处理器输出,并且不知道如何处理未处理的指令。

GNU cpp 4.4.3上的一个小变体对我来说是可行的:

#define HASH(x) x

...

HASH(#)ifdef __cplusplus
class foo { };
HASH(#)endif

另一个似乎有效的技巧是:

#define EMPTY
EMPTY#ifdef
使用GCC的预处理器(版本4.5.2),我得到:

#ifdef
出于某种原因,这种技术与C预处理器有着相同的主要空间问题,但这可能不是符合现代标准的C预处理器的问题。

@sidyll如果OP在预处理器中运行两次,它就会发生。@sidyll:True。我正在考虑使用预处理器生成项目模板。@sidyll:“…如果CPP输出本身是预处理的”我怀疑有更好的工具可以满足您的想法,比如使用通用宏处理器或用方便的语言编写预处理脚本。相关(几乎是重复):GCC的预处理器出现错误:“error:“#”后面没有宏参数“@DanielTrebbien:您是如何调用它的?我只是将上面的代码粘贴到一个文本文件中,然后运行
cpp file.c
。它给出了一个由
#ifdef#endif
。。。。啊,我明白了。您使用了
g++-E
建议。这似乎失败了,原因我目前无法理解。也许
cpp
更宽容。我使用
cpp
也会失败
cpp——版本
打印
cpp(Debian 4.3.2-1.1)4.3.2
,以防有人好奇。编辑:在另一个带有
cpp(Ubuntu 4.4.3-4ubuntu5)4.4.3
的框中得到相同的结果。我的是4.2.1(
i686-apple-darwin11-llvm-g++-4.2(GCC)4.2.1
),但我的g++也是如此。对预处理器机制的创造性使用。唯一(微小)的问题是它将
#
缩进了一个空格。我相信一些较旧的预处理器不喜欢这样,因此约定是缩进命令(ifdef/endif/include…),而不是缩进
。在任何情况下,答案都是正确的,而且非常有创意。@Marcelocontos:是的,我不知道这个空间是从哪里来的。(这并不是显而易见的:即使使用了
#define HASH(x)x
,空间也会出现)我猜空间与宏替换避免某些可能被解释为标记粘贴的事情的方式有关。因此,它不希望在没有前面空格的情况下发出
,因为
可能最终附加到前面的标记。马塞洛:我们还需要担心那些C89之前的标准编译器吗?我从来没有遵循过这个惯例,我也从来没有想过,但我在2002年左右第一次编写了C,我从来没有在真正破旧的系统上工作过,除非算上Symbian/C++。写第一版《K&R》的想法有点吓人,我甚至没有一本。。。 #ifdef