Guarantees on layout

Hello fellow ziguanas! I have a question about memory layout. Besides packed and extern, does zig provides any guarantees on user-defined types layout?

Specifically I have two structs with fields of the same type, and I’d like to be able to assume they’ll have the same layout:

const Field1 = ...;
const Field2 = ...;

const Type1 = struct {
    field1: Field1,
    field2: Field2,
};

const Type2 = struct {
    field1: Field1,
    field2: Field2,
};

Are Type1 and Type2 guaranteed to have the same layout? can I use @ptrCast or @bitCast safely, so that Type1.fieldx corresponds exactly to Type2.fieldx and vice-versa ?

Hi! Pretty sure bare enums, structs, and unions don’t guarantee any in-memory layout, as opposed to their extern and packed versions.

Here’s the langref excerpt for unions:

The in-memory representation of bare unions is not guaranteed. Bare unions cannot be used to reinterpret memory. For that, use @ptrCast, or use an extern union or a packed union which have guaranteed in-memory layout.

2 Likes

This is not guaranteed in the documentation, but assuming that the compiler is deterministic, the same struct with the same fields in the same order, should yield the same memory layout.
However, if you think you need to rely on behaviors like this it’s always best to take a step back and figure out a better solution. While it’s technically possible to @ptrCast here, it’s neither readable nor maintainable(imagine adding a new field to one of these).

Also by the way @bitCast is straight up forbidden for casting from or to elements without a guaranteed memory layout.

1 Like