[pulseaudio-discuss] Allowing anonymous structs and unions
Alexander E. Patrakov
patrakov at gmail.com
Wed Sep 23 04:49:34 PDT 2015
On 09/23/2015 04:34 AM, Ahmed S. Darwish wrote:
> ### Anonymous unions
>
> Used to provide the mempool with polymorphic memory region access
> regardless of the type of memory used:
>
> union {
> pa_mem mem;
> union {
> pa_shm shm;
> pa_memfd memfd;
> pa_privatemem privatemem;
> } per_type;
> };
This kind of usage looks good.
> ### Anonymous structs
>
> They are also used in the memfd patches, but they're really used
> to minimize code repetitions and make relationships explicit.
>
> Basically, we want to build an inheritance relationship: pa_shm,
> pa_memfd, and pa_privatemem has the common parent pa_mem. We also
> want to make this relationship explicit since it's at the core of
> the anonymous polymorphic union mentioned above.
>
> To do so without introducing extra (compile-time) dereferences,
> the following patten is used:
>
> /* Parent anonymous structure representing a plain memory
> * area and its size. Different structures inherit from this,
> * representing different memory area types (e.g. Posix SHM,
> * Linux memfds, or private mallocs).
> *
> * To inherit from this object, just include PA_MEM_STRUCT as
> * the very first element of your structure definition. */
> #define PA_MEM_STRUCT struct { \
> void *ptr; \
> size_t size; \
> } PA_GCC_PACKED
>
> typedef struct pa_mem {
> PA_MEM_STRUCT;
> } pa_mem;
>
> This way, children pa_shm, pa_memfd, and pa_privatemem can be
> defined as follows:
>
> typedef struct pa_shm {
> PA_MEM_STRUCT;
> unsigned id;
> bool do_unlink;
> } pa_shm;
>
> typedef struct pa_memfd {
> PA_MEM_STRUCT;
> int fd;
> } pa_memfd;
>
> typedef struct pa_privatemem {
> PA_MEM_STRUCT;
> } pa_privatemem;
I don't like that (on a purely subjective basis).
>
> ..
>
> So to summarize, such annotation explicitly shows the inheritance
> relationship, minimize code repeition in the struct defintions, and
> also saves us an extra compile-time dereference in shm.c, memfd.c,
> and privatemem.c code. It also really works in tandem with the
> earlier polymorphic union:
>
> union {
> pa_mem mem;
> union {
> pa_shm shm;
> pa_memfd memfd;
> pa_privatemem privatemem;
> } per_type;
> };
>
> Hopefully these patterns will be OK from your side :-)
>
> Regards,
>
--
Alexander E. Patrakov
More information about the pulseaudio-discuss
mailing list