【问题标题】:In C99, can I use a return value without first assigning it to a variable?在 C99 中,我可以在不先将返回值分配给变量的情况下使用它吗?
【发布时间】:2013-12-13 19:47:00
【问题描述】:

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

例如...

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

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

不仅有很多代码会这样做,我无法控制的已发布代码也会这样做,所以如果可能的话,我宁愿保留这个习语。

有没有办法定义与上述代码兼容的AvARRAY 的内联函数版本?

【问题讨论】:

  • 您说目标是优化,您是否认为内联函数可以使用一些比指针偏移更快的魔术指令?您是否手动展开宏扩展并考虑过哪种功能可能更有效?
  • @kfsone 我了解到现在编译器通常比我聪明,而且我认为更多的结构和类型检查将使它有更多的工作空间。我还了解到,当我试图猜测编译器会做什么时,我经常会出错。我想看看会发生什么。最后,这个源代码中宏的广泛使用使得理解发生了什么和调试有点像噩梦。
  • 在您给出的示例中,没有任何理由认为 inline 函数会比宏更好地优化或节省。您只对参数进行一次评估,并且从使用来看,这个东西是非常安全的,因为您在参数上使用了 -> 运算符。看起来你正在寻找一个幻影。 (为了更好地支持宏,我建议使用clang)我在你的代码中看到了一件令人讨厌的事情,那就是在另一个表达式中无偿使用--

标签: c macros inline c99


【解决方案1】:

是的,您可以使用返回值而不将其分配给变量。

但是,在一般情况下,不能用函数替换此宏。为此目的使用宏的全部意义在于宏可以“评估”为左值。不幸的是,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);

但这不适用于位域,而宏版本可以。

【讨论】:

  • 它被用作左值,但更多时候它以描述的方式用于设置数组中的特定槽。我已经定义了另一个函数来替换它作为左值的使用。
猜你喜欢
  • 1970-01-01
  • 2011-11-18
  • 2011-12-31
  • 2019-04-17
  • 1970-01-01
  • 1970-01-01
  • 2016-11-12
  • 1970-01-01
  • 2011-04-07
相关资源
最近更新 更多