#Pointier to a tagged union

1 messages · Page 1 of 1 (latest)

carmine panther
#

Hi,

I have a tagged union to represent an Expression on an AST.

pub const Expression = union(enum) {
    const Self = @This();

    infixExpression: InfixExpression,
    identifier: Identifier,
    integerLiteral: IntegerLiteral,
    booleanLiteral: BooleanLiteral,
    prefixExpression: PrefixExpression,
// more code
}```

`PrefixExpression` has a pointer to `Expression`

pub const PrefixExpression = struct {
const Self = @This();
token: Token,
operator: []const u8,
right: ?*const Expression,
// more code


If I create a `PrefixExpression` I can safely recover the `right` Expression that is being referenced, but once my prefixExpression is passed to a different function I cannot recover it anymore and the active member is always `infixExpression`. 

AFAIK in order to preserve the correct value I need a `packed` union but there are no packed tagged unions. Am I missing something? am I doing something wrong?

Thanks .
static cedar
#

can you post the code where you create and pass it?

carmine panther
#

Sure, I'll post later the GitHub links

carmine panther
#

This is the function that creates the PrefixExpression, inside this function, the tagged union is ok https://github.com/MarioAriasC/monito/blob/parser/src/parser.zig#L184

This test fails https://github.com/MarioAriasC/monito/blob/689070e60fe901cda5a4297f03aaadcff164ef92/src/parser.zig#L360

GitHub

Contribute to MarioAriasC/monito development by creating an account on GitHub.

GitHub

Contribute to MarioAriasC/monito development by creating an account on GitHub.

static cedar
#

It seems you're taking a pointer to a stack variable, &r

carmine panther
#

I see

static cedar
#

verify with

const value = blk: {
            if (right) |r| {
                const new_r = self.allocator.create(Expression) catch break :blk null;
                new_r.* = r;
                break :blk new_r;
            } else {
                break :blk null;
            }
        };

This will leak mem if not using an arena allocator

carmine panther
#

it worked

#

Thanks, Now I need to wrap my head around it

static cedar
#

right gets created on the stack and then you take a pointer to it, but once that fn is done the stack is reused, ie overwritten, now you have a pointer to random data

carmine panther
#

which is why it works if testing in the same function i.e. same frame

static cedar
#

yes