在一个示例项目中,我定义了宏
#define FOO(x, y) x + y .
这效果非常好。例如,FOO(42, 1337)
被评估为1379
.
但是,我现在想使用另一个#define
:
#define SAMPLE 42, 1337
当我现在打电话时FOO(SAMPLE)
,这行不通。编译器告诉我FOO
接受两个参数,但仅使用一个参数调用。
我猜想这样做的原因是,虽然宏的参数是在函数本身之前评估的,但预处理器在评估后不会再次解析整个指令。这类似于不可能从宏输出额外的预处理器指令的事实。
有没有可能获得所需的功能?
更换FOO
带有 C 函数的宏是不可能的。原始宏位于我无法更改的第三方代码中,它输出一个以逗号分隔的值列表,可直接在数组初始值设定项中使用。因此,C 函数无法复制相同的行为。
如果使用简单的方法无法完成此任务:您将如何存储(x, y)
以可维护的形式配对?就我而言,有 8 个参数。因此,将各个部件单独存放#define
-s 也不容易维护。
您遇到的问题是预处理器未按照您想要的顺序匹配和扩展宏。现在,您通常可以通过插入一些额外的宏来强制它获得正确的顺序来让它执行您想要的操作,但为了做到这一点,您需要了解正常的顺序是什么。
当编译器看到带有参数的宏名称后跟(
它首先扫描该参数列表,将其分解为参数,而不识别或扩展参数中的任何宏。
解析和分离参数后,它会重新扫描每个参数的宏,并扩展在该参数中找到的任何参数,除非该参数与#
or ##
在宏观体
然后它用(现在可能扩展的)参数替换主体中参数的每个实例
最后,它重新扫描主体以查找主体中可能存在的任何其他宏以进行扩展。在这一次扫描中,原始宏将不会被识别和重新扩展,因此您不能进行递归宏扩展
因此,您可以通过仔细使用 EXPAND 宏来获得您想要的效果,该宏接受单个参数并对其进行扩展,从而允许您在过程中的正确位置强制进行额外的扩展:
#define EXPAND(X) X
#define FOO(x,y) x + y
#define SAMPLE 42, 1337
EXPAND(FOO EXPAND((SAMPLE)))
在这种情况下,您首先在参数列表中显式展开宏,然后手动展开生成的宏调用。
按问题海报更新
#define INVOKE(macro, ...) macro(__VA_ARGS__)
INVOKE(FOO, SAMPLE)
提供了一个扩展的解决方案,可以在不使代码混乱的情况下工作EXPAND
s.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)