umcisou
umcisou

Reputation: 21

pointer casting (ptrCast) of child type embed in Zig

I wonder if it's safe in Zig to cast a pointer from a child struct to a parent struct embedded in the child.

Something like that:

const std = @import("std");

const Parent = struct {
    age: u8,

    fn init(age: u8) Parent {
        return .{ .age = age };
    }
};

const Child = struct {
    parent: Parent, // Parent field must be the first one
    some_other_field: bool = true,

    fn init(age: u8) Child {
        const p = Parent.init(age);
        return .{ .parent = p };
    }
};

test "inheritance" {
    const child = Child.init(20);

    // casting to Parent and retrieve value
    const parent_ptr = @ptrCast(*Parent, &child);
    try std.testing.expect(parent_ptr.age == 20);
}

It's working well like that.

But if I swap field order for Child, putting parent in second position, it does not work anymore, returning instead the value of some_other_field. So the order of the fields seems to be fundamental here.

The Zig Documentation says Zig gives no guarantees about the order of fields and the size of the struct but the fields are guaranteed to be ABI-aligned. I'm talking here of normal structs, not extern or packed.

So I wonder if it's safe to do as in the example above, as the order of fields has no guaranty in normal structs?

Upvotes: 2

Views: 1640

Answers (1)

InKryption
InKryption

Reputation: 175

No, that is, in fact, not safe. As an implementation detail, at the time of writing, it has the same layout details as an extern struct, but the compiler can take liberties and reorganize the struct fields in memory however it sees fit. A more appropriate alternative would be @fieldParentPtr:

const std = @import("std");

const Foo = struct {
    value: u32 = 0,
};
const Bar = struct {
    foo: Foo = .{},
    hash: u32 = 1,
};

test {
    var bar: Bar = .{};
    const p_foo: *Foo = &bar.foo;
    const p_bar: *Bar = @fieldParentPtr(Bar, "foo", p_foo);
    try std.testing.expectEqual(&bar, p_bar);
}

Upvotes: 2

Related Questions