#Acces the active field of a union

1 messages · Page 1 of 1 (latest)

grim inlet
#

Say I'd like to print the currently active field. And the union is not a tagged union. Can I do some kind of union.active_field?

cinder phoenix
#
switch (my_union) {
    inline else => |value, tag| {
        // ...
    },
}```
tropic epoch
#

the union needs to be tagged in order to switch on it

cinder phoenix
#

yeah ofc

tropic epoch
#

i.e const tagged_union = union(some_enum) { a: u8, b: u16 };

cinder phoenix
#

I mean generally you'd use union(enum) but yeah you can specify an explicit tag type

#

(Note type names should be UpperCamelCase, so const TaggedUnion = union(SomeEnum))

fervent cobalt
#

%%std.meta.activeTag for a runtime value

cinder phoenix
#

I don't think that's what they're asking

fervent cobalt
#

it looks like it on the op

#

but yeah the switch is usually what you want

cinder phoenix
#

activeTag gives you an enum, it doesn't access the field

fervent cobalt
#

yes

#

and I actually have one legitimate use of activeTag

#

but nothing besides that :^)

#

the rest are switches

cinder phoenix
#

inline else <3

grim inlet
#

Trying the suggested

grim inlet
#

hm no luck so far. If I would want to to print the currently active field of an untagged union. Would I need to use std.meta.activeTag? How does the compiler or program know what field is active. It can throw an error when an inactive field is accessed, so I guess it keeps track somehow.

#

inline else seems pretty cool. Does it catch all? Could you elaborate a bit?

half bough
# grim inlet hm no luck so far. If I would want to to print the currently active field of an ...

You cannot get the active field of an untagged union.
The whole point of using a tagged union is that you can check which field is active.

For the runtime check the compiler probably uses some hidden tag. (note that unions have no guaranteed memory layout)
But you can and should not access this hidden tag because the safety checks (and therefor the hidden tag) only exist in debug/ReleaseSafe mode.

final skiff
#

If you're using an untagged union, the idea is that you have some other metadata to indicate which field is "active"

grim inlet
#

I suppose so yes

final skiff
#

erego, in order to print it, you'd basically have to branch on that metadata, and make a branch for each field in which you print the value

#

is there any reason you want to use an untagged union?

static rose
grim inlet
#

Well, just for getting my feet wet in the language I was writing a print function that readably prints anything you throw at it. And now the only thing that doesn't look very nice is if you ask it to print a union. 😉

#

Not very important. But it would be very satisfactory

#

So far it's a great learning experience 😉

#

Also I think in C I could print any of the fields to get the value, because all sat at the same memory address. Maybe I can still iterate somehow in zig and catch the error and in that case falltrough to the next field if the current field is not active. If I sound like a beginner, I am 🙂

fervent cobalt
#

when working with extern data structures, your zig will look close to C

final skiff
#

It's just that a bare union in safe modes has a secret tag to make sure you don't reinterpret data (access the wrong field)

#

We can also do the unchecked version using an extern union or packed union

#

If you want to know the way the stdlib prints a bare union, iirc it just prints the address