Why does this cause a byte alignment error?

const std = @import("std");

pub fn main() void {
    
  //  why below can't compile
     const ptr: *align(1) i32 = @ptrFromInt(0x1); 
     const aligned: *align(4) i32 = @alignCast(ptr); 
       _ = aligned;
  
//why below code compile        
     const z: i32 align (1) = 44;
     const x: *align(4) i32 = @ptrCast(@alignCast(@constCast(&z)));
   _= x;
}

I think the compile error says it best:

main.zig:5:48: error: pointer address 0x1 is not aligned to 4 bytes
     const aligned: *align(4) i32 = @alignCast(ptr); 

The address 0x1 is not aligned to 4 bytes. Try it with another address like 0x4 and you’ll see that it compiles. To be clear, I’m not implying that there’s something special given that it has a 4 in it, it just so happens that address works for 4-byte alignment (or at least Zig sees that it does).

Also - I’m changing the title to better reflect the content and adding formatting to your post.

3 Likes

Because ptr is const. Subsequently the compiler sees that aligned is comptime known, so it tries to evaluate the value and runs into the error. The following compiles:

const std = @import("std");

pub fn main() void {
    var ptr: *align(1) i32 = @ptrFromInt(0x1);
    const aligned: *align(4) i32 = @alignCast(ptr);
    _ = aligned;
    ptr = ptr; // <- workaround for retarded feature
}
1 Like

Zig’s alignment fetishism is so obnoxious at times. For my target platforms (x64) it is only needed in specific situations, and I don’t care about other platforms and never will with the code I’m writing right now. I shouldn’t have to worry about some random other architecture. Most code is written with distinct platforms in mind. Alignment isn’t the performance improvement people think it is. The CPU cache even has things like split buffers to allow single cycle atomic ops across cache lines. It hasn’t helped performance for most things in over a decade. Even vector instructions don’t suffer from it anymore.