Tagged Union Instances in Memory

Message ID
DKIM signature
Download raw message
I have been reading the Hare documentation and the example in the
section "Casting & type assertions" confused me. As I understand it, a
union variable is just a memory cell the size of the biggest union type.
So, if we have a union of `int` and `uint`, it should be one common cell
for both of them. However, in the given example, a memory cell right
after the union variable is referenced.

Here is my attempt to make sense of what is going on in the example:

use fmt;

export fn main() void = {
	// x is a union
	let x: (int | uint) = 42i;
	// sizes of int and uint are equal,
	// so they should be sharing a memory cell
	assert(size(int) == size(uint));

	// currently x is set to int, value in the memory is 42
	assert(x is int);
	assert(x == 42);

	// y is a pointer to x
	let y: nullable *(int | uint) = &x;
	assert((y is *int));

	// the memory cell with x and the memory cell after it
	fmt::printfln("| {:x} | {:x} |", y, y: uintptr + size(int): uintptr)!;

	// z is a valid (non nullable) pointer to the next cell after x
	let z = (y: uintptr + size(int): uintptr): *int;
	// yet z is still 42

So, the question is: why can we reference the next cell after `x` as
valid and why does it have the value of `x` in it?
Message ID
<ufPCh9qdObnCZITqZrbNqwwE2czozuZAZaV9McmwiLnzdVwOG8IitsOHGOv5C0VknBMgEt2-yXs-LMPeB5g1Nl80hyS888a4-2YjcbNVHTs=@protonmail.com> (view parent)
DKIM signature
Download raw message
The tagged union also includes... a tag. Check out the spec for the full
details on tagged union storage:


section 6.5.17
Reply to thread Export thread (mbox)