我正在研究关于预处理器的确切行为的C++标准(我需要实现某种C++预处理程序)。根据我的理解,我所编的(以帮助我理解)的例子应该是有效的:
#define dds(x) f(x,
#define f(a,b) a+b
dds(eoe)
su)我希望像宏调用dds(eoe)这样的第一个函数被f(eoe,替换(注意替换字符串中的逗号),当输入被重新屏蔽时,这个逗号被认为是f(eoe,su)。
但是VC++2010的测试给了我这个结果(我告诉VC++输出预处理文件):
eoe+et_leoe+et_l
su)这是违反直觉的,显然是不正确的。是VC++2010的错误还是我对C++标准的误解?特别是,在替换字符串的末尾加上逗号是否与我一样不正确?我对C++标准语法的理解是,任何preprocessing-token都是允许的。
编辑:
我没有GCC或其他版本的VC++。有人能帮我和这些编译器核实一下吗。
发布于 2014-03-23 12:16:48
据我所知,在标准的[cpp.subst/rescan]部分中,没有任何东西会使您的行为成为非法行为,clang和gcc将其扩展为eoe+su是正确的,而MSC (VisualC++)行为必须报告为bug。
我没能让它发挥作用,但我设法为您找到了一个丑陋的MSC解决方案,使用了各种变量--您可能会发现它有帮助,或者您可能没有,但无论如何,它是:
#define f(a,b) (a+b
#define dds(...) f(__VA_ARGS__)它扩大为:
(eoe+
su)当然,这对gcc和克朗来说是行不通的。
发布于 2014-03-23 11:44:06
嗯,我看到的问题是,预处理器执行以下操作
ddx(x)变成f(x,
然而,f(x,也被定义为f(a,b) ),所以f(x,扩展为x+垃圾)。
因此,ddx(x)最终转换为x+垃圾(因为您定义了f(smthing ) )。
您的dds( eoe )实际上扩展到a+b,其中a是eoe,b是et_l。无论出于什么原因,它都会做到两次。)
此场景是编译器特定的,这取决于预处理器如何选择处理定义的扩展。
https://stackoverflow.com/questions/22590006
复制相似问题