On Tue, Feb 21, 2023 at 01:24:17PM +0000, Richard W.M. Jones wrote:
> >> +++ b/generator/states-connect-socket-activation.c
> >> @@ -51,7 +51,7 @@ prepare_socket_activation_environment (string_vector
*env)
> >> char *p;
> >> size_t i;
> >>
> >> - assert (env->len == 0);
> >> + *env = (string_vector)empty_vector;
> >
> > Do you actually need to cast this?
>
> This is not a cast, but a C99 compound literal. And yes, it is
> necessary, as empty_vector is just:
>
> #define empty_vector { .ptr = NULL, .len = 0, .cap = 0 }
>
> So this is *not* initialization, but assignment. We have a string_vector
> object (a structure) on the LHS, so we ned a structure on the RHS as
> well. The compound literal provides that (unnamed, automatic storage
> duration) structure. It looks like a cast (quite intentionally, I'd
> hazard), but it's not a cast.
OK it's not a cast, but struct assignment is well defined so is the
change necessary?
Struct assignment requires a source struct. Either a named one (which
we do not have here without declaring one), or via a compound literal
(which resembles a cast).
It sounds like it would be nice to have a type-specific macro, as in
'empty_string_vector', 'empty_int_vector', and so on, per each use of
DEFINE_VECTOR_TYPE() - but while our one macro can easily declare
other type-specific functions, you can't really use the preprocessor
to define further type-specific macros. So having to tell the user to
supply their own type name when reusing the type-agnostic initializer
portion of a compound literal is not too bad in the long run, although
it might be worth documenting the practice in vector.h.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization:
qemu.org |
libvirt.org