#Allocate one variant of `union`

1 messages · Page 1 of 1 (latest)

keen spruce
#

I have a const C = union {a: A, b: B}; where A is roughly twice as large as B. When I now allocate a C where only C.b is active, I'd like to allocate only the space required for a B rather than max(sizeof A, sizeof B). How can I do this? Can I just allocate a B and cast to make it work? Will this be guaranteed to work?

crisp elk
#

Yes you can allocate a B but it will be a different length in memory and defeats any benefit you would get from a union, so it depends on your use case
Casting it however will probably not work or be any more efficient

cyan jewel
#

In this case, I would consider avoiding a builtin union, as---IIRC---they have no defined layout.

#

Ideally, it would be nice if there was a way to do this with the builtin union perhaps, but there isn't currently.
An alternative impl is that you use the "encoding" pattern.
Andrew explains it here (https://vimeo.com/649009599) at the 23:25 mark.

Andrew Kelley, creator of Zig, picks up where Mike Acton left off to teach us practical ways to apply data-oriented design References: - CppCon 2014: Mike Acton…

▶ Play video
crisp elk
#

What would it even mean to do this? At best you can say the part of the union you don't need is uninitialised memory, which is what memory allocating gives you anyway

drifting shore
#

I think the best way to achieve this would be to allocate A and B instead of allocating C:
So const C = union {a: *A, b: *B}

cyan jewel
keen spruce
#

thanks for the input

hot osprey
#

I'd be cautious if you were to do this

#

Make sure the allocation is also aligned to the smaller of the two, as opposed to being aligned to the larger of the two, lest you risk loading garbage memory from an over-aligned memory location or register

#

(and if you do do it, use extern union)

keen spruce
hot osprey
#

yeah, no issue there