在下面的代码中,将retval
传递的任何内容评估为每次使用该令牌时给出的内容。
#define _CPFS_RETURN(commit, retval) do { \
util_cpfs_exit(commit); \
return retval; \
} while (false)
#define CPFS_RETURN_BOOL(retval) do { \
_CPFS_RETURN(retval, retval); \
} while (false)
例如,如果使用CPFS_RETURN_BOOL(inode && file_truncate(inode, len));
,则会生成:
do {
do {
util_cpfs_exit(inode && file_truncate(inode, len));
return inode && file_truncate(inode, len);
} while (0);
} while (0);
显然我不想多次执行语句inode && file_truncate(inode, len);
。
如何确保在粘贴helter-skelter之前评估给定的令牌?
我相信我有充分的理由在这里使用宏。在可能的情况下,将代码放入实际函数(例如 util_cpfs_exit )中,这些函数是从我正在使用的一组宏中调用的。宏根据返回类型而有所不同:在C ++中,我有明确的模板来处理这个问题。
答案 0 :(得分:4)
由于您的宏在返回类型上有所不同,您可以计算retval表达式并将其存储在第一级宏内的正确类型的变量中,然后使用此变量。即:
#define CPFS_RETURN_BOOL(retval) do { \
bool _tmp_ = retval;
_CPFS_RETURN(_tmp_, _tmp_); \
} while (false);
如果我理解得很好,那对你的用例就足够了,对于其他用例,你可以使用函数。
在你的例子中,你会得到:
do {
bool _tmp_ = inode && file_truncate(inode, len);
do {
util_cpfs_exit(_tmp_);
return _tmp_;
} while (0);
} while (0);
看起来很好。
PS:作为旁注,如果您始终在上述模型之后通过另一个宏间接使用_CPFS_RETURN,则无需通过do { } while (false);
保护它。此外,在while(false)
之后放置一个分号消除了使用它的大部分兴趣......这可能是为什么C宏是危险的并且隐藏容易陷阱的一个很好的例子。并非我不喜欢宏,恰恰相反。我来自(可能是罕见的)那些希望增强C宏以超越其当前限制以变得非常酷的人(并且不,C ++模板不是增强型宏,它们是完全不同的。)
答案 1 :(得分:2)
我建议您先评估病情。
即
bool val = inode && file_truncate(inode, len);
除此之外,建议可能是避免使用宏,在这种情况下它们似乎是不必要的,而是使用函数。
答案 2 :(得分:1)
编写函数而不是使用宏。在这种情况下,如果要在其中构建return
语句,最好只显式编写代码,而不是依赖宏来隐藏您正在做的事情。
答案 3 :(得分:-1)
将宏更改为“静态内联”功能。在gcc中,它和宏一样快。 http://gcc.gnu.org/onlinedocs/gcc/Inline.html