C++ 如何制作G++;预处理器在宏中输出换行符?

C++ 如何制作G++;预处理器在宏中输出换行符?,c++,g++,newline,c-preprocessor,C++,G++,Newline,C Preprocessor,在gcc/g++4.*中有没有办法编写一个扩展成几行的宏 以下代码: #define A X \ Y 扩展到 X Y 我需要一个宏扩展到 X Y 这就是你想要的吗: #define A "X \nY" 为什么间距很重要 X11(旧版本?)版本中使用的imake程序使用C预处理器生成生成生成文件,但imake程序使用了一种特殊技术,即在行尾用@符号表示行尾,然后对预处理器的输出进行后处理,以换行符替换@符号 从这个设计中,我得出结论,没有可靠的方法从C(或C++)中的扩展宏中获取换行符。事

在gcc/g++4.*中有没有办法编写一个扩展成几行的宏

以下代码:

#define A X \ Y
扩展到

X Y
我需要一个宏扩展到

X
Y
这就是你想要的吗:

#define A "X \nY"

为什么间距很重要

X11(旧版本?)版本中使用的imake程序使用C预处理器生成生成生成文件,但imake程序使用了一种特殊技术,即在行尾用@符号表示行尾,然后对预处理器的输出进行后处理,以换行符替换@符号

从这个设计中,我得出结论,没有可靠的方法从C(或C++)中的扩展宏中获取换行符。事实上,对于C,没有必要,因为:

  • 与C预处理器运行后的空白相比,C不关心换行符,并且
  • 不能从宏等生成预处理器指令

我很确定,为不关心换行符的C语言设计的CPP无法处理此类工作。您仍然可以使用一些特殊的标记字符串标记想要的换行符,并通过
sed
awk
传递结果,以获得所需内容。

来自:

在目前的实施中 整个扩展在一条线上完成

明白了

#define anlb /*
*/ A /*
*/ B

anlb anlb


另一方面,不能在宏中放置换行符会创建不可读的代码,这使得调试预处理器输出更加困难。C和C++可能不关心新行,但是C预处理器确实如此。

我真的想做一个宏ConditionalDefine(x,y),它输出以下内容

    #ifdef x
    #define y
    #endif
以下定义了“执行关闭的操作”:

    #define hash #
    #define nl
    #define _def_p8(A,B) A ifdef _P8_K60_BOARD_ A define B  A endif
    #define X_def_p8(A,B) _def_p8(A,B)
    #define def_p8(A) X_def_p8(nl hash,A)
扩展以下内容:

    def_p8(PTPD_DBGA 0)
结果:

    # ifdef _P8_K60_BOARD_ # define PTPD_DBGA 0    # endif

但是如果不能在散列之前放入新行,它将无法按预期工作。这也让你很恼火,你必须跳转才能接近它。

你可以在宏中加入一个魔术角色序列,例如

#define X(y,z) y nl z
运行
gcc-E infle | sed g/s/nl/\n/>无论什么

(也许不完全正确,但你明白了,对吧?通过管道或在输出上运行。)


有时我这样做是为了使用C宏来生成源代码,不,我不想学习如何在或其他工具中这样做。

让宏生成一个特殊的标记,比如说
\uuuu CR\uuu
,然后将CPP的结果导入一个脚本,该脚本将宏转换为真正的换行符,例如,
sed's/\uu CR\uu/\n/g'


我刚刚发现这对于生成手动填充的代码模式非常有用。当代码可读时,它会变得更容易。

不,我不需要字符串常量。我需要一个函数来扩展成两个操作符,两个操作符之间用换行符分隔。例如#定义一个x++;这里有些特别的东西y++;我希望它扩展到:x++;y++;而不是x++;y++;
x++有什么问题;y++?编译器不关心空格。@Michael,那么你想实现什么有趣的问题呢?我不知道用C/C++实现你所描述的功能的方法(尽管GCC可能有一个我不熟悉的扩展)。你能更详细地解释一下你想做什么(用“什么”而不是“如何”)吗?也许还有另一种方法可以得到你最终想要的结果。我的动机是这会使调试更容易。@JonathanLeffler我不认为把这个问题标记为重复问题有什么用,当它是唯一一个有可行答案的时候。这尤其不幸,因为未登录的用户会自动重定向到另一个用户,所以他们得到的问题没有好的答案。只要你使用
CPP
生成C/C++/其他不可知新行的语言结果,这一切都很好。最近,我不得不使用C预处理器生成shell文件。我向你保证新词很重要。@SF:在这种情况下,你在工作中使用了错误的工具。CPP是,嗯,C预处理器。因此,它遵循C标准中的一些严格规则,并且可能是为预处理C而优化的。为自己准备一个真正的宏预处理器,或者使用脚本语言编写一些东西。请不要坚持将附加功能附加到我预期使用的软件上。类似地,我喜欢买一个侧面没有锤头的新月形扳手。“为什么间距很重要?”有时人必须对输出进行故障排除:)CPP是gfortran使用的预处理器。Fortran对换行符和行长很敏感。C也不关心制表符,但您可以定义一个宏,其扩展包括一个或多个制表符。缺少换行符是C宏功能中一个非常特殊的漏洞。@Steve Jessop:如果需要通用的宏预处理器,请使用“m4”。C预处理器是为了满足C编译器的需要而设计的;尽管它被广泛使用,但它不是一个通用的宏预处理器。制表符的保留是由标准保证的,还是仅仅允许实现的?预处理器对标记序列进行操作,而注释、制表符和换行符被视为空白,而不是预处理标记。我在标准中没有看到任何建议在替换列表中保留空格的内容,只有预处理标记。@jw013:我不确定它是否是一般标准,但我绝对确定它必须在字符串文本中保留制表符和其他空格。我严重怀疑是否有人会仔细检查替换内容是否包含字符串,并仅删除/替换这些字符串之外的选项卡。思考:
#定义制表符或空格(x)((x)?:“)
-为什么预处理器会试图确定允许剥离制表符或空格的位置?“我严重怀疑是否有人会头痛不已,无法识别替换是否包含字符串,并仅删除/替换这些字符串之外的制表符。”--那是非常愚蠢的,尼克
    # ifdef _P8_K60_BOARD_ # define PTPD_DBGA 0    # endif
#define X(y,z) y nl z