我正在使用内联函数替换大型C99代码库中的宏,以查看编译器是否可以更好地进行优化。有很多宏扩展到数据结构。代码不是将它们用作函数,而是作为数据结构本身的替代。
例如......
#define AvARRAY(av) ((av)->sv_u.svu_array)
AvARRAY(av)[--key] = &PL_sv_undef;
不仅有很多代码可以做到这一点,我控制之外的已发布代码就是这样做的,所以如果可能的话,我宁愿把这个成语留在原地。
有没有办法定义AvARRAY
的内联函数版本,它与上面的代码类型兼容?
答案 0 :(得分:3)
是的,您可以使用返回值而不将其分配给变量。
但是,在一般情况下,无法用函数替换此宏。为此目的使用宏的全部意义在于宏可以“评估”到左值。遗憾的是,C中的函数不能产生左值。换句话说,不,一般情况下你不能用函数直接替换这些宏。
但在具体情况下可能会有所不同。他们真的将这些宏用作左值吗?在您的具体示例中,它不用作左值,因此在您的情况下,您可以执行
inline whatever_type_it_has *AvARRAY(struct_type *av)
{
return av->sv_u.svu_array;
}
并在以后使用它,就像在您的示例中使用的那样
AvARRAY(av)[--key] = &PL_sv_undef;
但是如果代码中的其他地方你有类似
的东西AvARRAY(av) = malloc(some_size);
或
whatever_type_it_has **pptr = &AvARRAY(av);
那么你将失去运气。功能版本不起作用,而原始宏将。
在这种情况下,用[函数] [几乎]完全“模拟”宏的功能的唯一方法是将其提升到更高级别的间接,即假设函数总是返回指针到目标数据字段
inline whatever_type_it_has **AvARRAY_P(struct_type *av)
{
return &av->sv_u.svu_array;
}
在这种情况下,你必须记住每次都取消引用该指针
(*(AvARRAY_P(av))[--key] = &PL_sv_undef;
但这将有效
*AvARRAY_P(av) = malloc(some_size);
whatever_type_it_has **pptr = &*AvARRAY_P(av);
但这不适用于位字段,而宏版本则会。