Hi everyone, On Wed, Sep 23, 2015 at 02:27:55AM -0400, Alexander E. Patrakov wrote: > On 09/23/2015 02:12 AM, Tanu Kaskinen wrote: > >Hi all, > > > >We haven't been using anonymous structs and unions so far, because > >they've been non-standard in the past. C11 added support for them, > >however. GCC has supported them longer than that, I don't know about > >other compilers. Anonymous structs and unions are nice, and I think we > >should start allowing them. Any objections? > > I think it would be a good idea to send one small example patch that makes a > use of them, just to demonstrate where exactly in PulseAudio they would make > the code more elegant. > Sure, this pattern is used heavily in the memfd patches :-) ### 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 way, a lot of the mempools code can transparently access its backend memory by using `mempool->mem.ptr' and `mempool->mem.size`. This also saves us from polluting the mempool memblock.c code with a huge number of switch cases ;-) ### 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; .. 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, -- Darwish http://darwish.chasingpointers.com