#Unaligned arbitrary width integer pointers

1 messages · Page 1 of 1 (latest)

jolly granite
#

Currently, this code segfaults on my x86-64 machine:

const std = @import("std");

pub fn main() !void {
    var page = try std.heap.page_allocator.alloc(u8, std.mem.page_size);
    defer std.heap.page_allocator.free(page);

    const ptr = @as(*align(1) u24, @ptrCast(page.ptr + std.mem.page_size - 3));
    std.debug.print("{x}", .{ptr.*});
}

Even though all the bytes relevant to the u24 are contained within the page, this still breaks, because @sizeOf(u24) == 4, and the assembly reads a dword, crossing the page boundary, since there is of course no such thing as a 1.5word.
This seems to be the cause of #stdlib-devel message.
Is this intended behavior?

unborn otter
#

exotic bit-width integers smaller than the largest platform bit width integer are defined as being backed by the next naturally sized integer type

#

that is to say, u24 is just implemented as a masked-off u32; the pointer being align(1) doesn't and can't technically change this property, as the semantics of accessing exotic bit width integers relies on that memory layout

jolly granite
unborn otter
#

this can be seen in arrays as well, wherein [n]u24 is equivalent in size to [n]u32

#

yeah, I'd intuit as much

jolly granite
#

right 👍

unborn otter
#

yeah, seems that PackedIntSliceEndian(T, endian).bytesRequired doesn't account for the natural size of the integer, it just calculates based off of bit size

jolly granite
#

so basically, accessing a *align(x) un is exactly the same as accessing *align(x) <backing integer>

unborn otter
#

yeah, effectively