可变参数宏:粘贴标记的扩展 [英] Variadic macros: expansion of pasted tokens
问题描述
我想知道是否可以嵌套"可变参数宏调用.我只真正关心 GCC 和 Clang.我的宏定义如下所示:
I'm wondering if it's possible to "nest" variadic macro invocations. I'm only truly concerned with GCC and Clang. My macro definition looks like this:
/**
* @brief Invoke an instance method.
*/
#define $(obj, method, ...)
({
typeof(obj) _obj = obj;
_obj->interface->method(_obj, ## __VA_ARGS__);
})
我使用它来方便地在我的 OO 框架中调用实例方法"(https://github.com/jdolan/客观地):
I use this to conveniently call "instance methods" in my OO framework (https://github.com/jdolan/objectively):
$(array, addObject, obj);
工作老板.不幸的是,我还没有找到允许嵌套这些调用的方法,这在某些情况下会非常有用;例如:
Works boss. Unfortunately, I haven't yet figured out a way to allow nesting of these calls, which would be very useful in some situations; e.g.:
/**
* @see MutableSetInterface::addObjectsFromArray(MutableSet *, const Array *)
*/
static void addObjectsFromArray(MutableSet *self, const Array *array) {
if (array) {
for (size_t i = 0; i < array->count; i++) {
$(self, addObject, $(array, objectAtIndex, i));
}
}
}
上面的嵌套可变参数宏调用无法编译,因为内部调用从未扩展.是否有可能解决这个问题,或者我已经将预处理器滥用到了极限?:)
The nested variadic macro invocation above fails to compile because the inner invocation is never expanded. Is it possible to fix this, or have I already abused the preprocessor to its limits? :)
推荐答案
这是嵌套预处理器宏的常见问题.预处理器扩展规则相当晦涩;相关的 tl;dr 是宏是分层扩展的.解决方法是添加一个可以扩展参数的间接层:
This is a common problem with nested preprocessor macros. Preprocessor expansion rules are fairly arcane; the relevant tl;dr is that macros are expanded in layers. The workaround is to add a layer of indirection in which the parameter can be expanded:
#define MI(obj, method, ...)
({
typeof(obj) _obj = obj;
_obj->interface->method(_obj, ## __VA_ARGS__);
})
#define M(obj, method, ...) MI(obj, method, __VA_ARGS__)
// This will now expand properly.
M(self, addObject, M(array, objectAtIndex, M(foo, bar, i)))
旁注:注意 $
不是 C 的基本源字符集的一部分;使用它可能不便携.
Side note: be aware that $
is not part of C's basic source character set; using it will probably not be portable.
这篇关于可变参数宏:粘贴标记的扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!