简体   繁体   English

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

[英]In C99, can I use a return value without first assigning it to a variable?

I am replacing macros in a large C99 code base with inline functions to see if the compiler can do a better job optimizing. 我正在使用内联函数替换大型C99代码库中的宏,以查看编译器是否可以更好地进行优化。 There are a lot of macros which expand to a data structure. 有很多宏扩展到数据结构。 The code uses them not as functions, but as a replacement for the data structure itself. 代码不是将它们用作函数,而是用作数据结构本身的替代品。

For example... 例如...

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

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

Not only is there a lot of code which does this, published code outside of my control does this, so I would rather leave this idiom in place if possible. 不仅有很多代码可以做到这一点,我控制之外的已发布代码就是这样做的,所以如果可能的话,我宁愿把这个成语留在原地。

Is there a way to define an inline function version of AvARRAY which is compatible with the sort of code above? 有没有办法定义AvARRAY的内联函数版本,它与上面的代码类型兼容?

Yes, you can use the return value without assigning it to a variable. 是的,您可以使用返回值而不将其赋值给变量。

However, in general case it is not possible to replace this macro with a function. 但是,在一般情况下,无法用函数替换此宏。 The whole point of using macros in for this purpose is that macros can "evaluate" to lvalues. 为此目的使用宏的全部意义在于宏可以“评估”到左值。 Functions in C cannot produce lvalues, unfortunately. 遗憾的是,C中的函数不能产生左值。 In other words, no, in general case you can't directly replace such macros with a functions. 换句话说,不,一般情况下你不能用函数直接替换这些宏。

But in specific case it could be different. 但在具体情况下,它可能会有所不同。 Do they really use those macros as lvalues? 他们真的将这些宏用作左值吗? In your specific example it is not used as an lvalue, so in your case you can just do 在您的具体示例中,它不用作左值,因此在您的情况下,您可以这样做

inline whatever_type_it_has *AvARRAY(struct_type *av)
{
  return av->sv_u.svu_array;
}

and use it later exactly as it is used in your example 并在稍后使用它,就像在您的示例中使用它一样

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

But if somewhere else in the code you have something like 但是,如果代码中的其他地方你有类似的东西

AvARRAY(av) = malloc(some_size);

or 要么

whatever_type_it_has **pptr = &AvARRAY(av);

then you'll be out of luck. 那你就不走运了。 The function version will not work, while the original macro will. 功能版本不起作用,而原始宏将。

The only way to [almost] fully "emulate" the functionality of macro with a function in this case is to lift it to a higher level of indirection, ie assume that the function always returns a pointer to the target data field 在这种情况下,用函数[几乎]完全“模拟”宏的功能的唯一方法是将其提升到更高的间接级别,即假设函数总是返回指向目标数据字段的指针

inline whatever_type_it_has **AvARRAY_P(struct_type *av)
{
  return &av->sv_u.svu_array;
}

In that case you will have to remember to dereference that pointer every time 在这种情况下,您必须记住每次都取消引用该指针

(*(AvARRAY_P(av))[--key] = &PL_sv_undef;

but this will work 但这会奏效

*AvARRAY_P(av) = malloc(some_size);
whatever_type_it_has **pptr = &*AvARRAY_P(av);

But this will not work with bit-fields, while the macro version will. 但这不适用于位字段,而宏版本则适用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM