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. 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, i.e. 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.