Padding struct to fixed size with usable bytes

Unfortunately using a function and @ptrCast() doesn’t work after all since the compiler is allowed to do whatever it wants to the padding bytes of a struct (as confirmed by the man himself).
However your second suggestion has inspired me to come up with something which is still pretty cursed but at least avoids playing Russian roulette with the compiler (it’s playing Breakout with it instead):

const Location = blk: {
    // For good measure
    @setEvalBranchQuota(std.atomic.cache_line);
    var estimated_padding_size = std.atomic.cache_line;
    var Attempt = LocationType(estimated_padding_size);
    const initial_size = @sizeOf(Attempt);
    assert(initial_size > std.atomic.cache_line);
    while (@sizeOf(Attempt) == initial_size) {
        estimated_padding_size -= 1;
        Attempt = LocationType(estimated_padding_size);
    }
    assert(@alignOf(Attempt) == std.atomic.cache_line);
    break :blk Attempt;
};

fn LocationType(comptime padding_size: usize) type {
    return struct {
        _: void align(std.atomic.cache_line) = {},
        state: atomic.Value(u32),
        descriptor: Descriptor,
        padding_bytes: [padding_size]u8 = undefined,
    };
}
1 Like