在C99中,我可以使用返回值而无需先将其赋值给变量吗?

时间:2013-12-13 19:47:01

标签: c macros inline c99

我正在使用内联函数替换大型C99代码库中的宏,以查看编译器是否可以更好地进行优化。有很多宏扩展到数据结构。代码不是将它们用作函数,而是作为数据结构本身的替代。

例如......

#define AvARRAY(av)     ((av)->sv_u.svu_array)

AvARRAY(av)[--key] = &PL_sv_undef;

不仅有很多代码可以做到这一点,我控制之外的已发布代码就是这样做的,所以如果可能的话,我宁愿把这个成语留在原地。

有没有办法定义AvARRAY的内联函数版本,它与上面的代码类型兼容?

1 个答案:

答案 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);

但这不适用于位字段,而宏版本则会。