# Help with ptr casting inconsistency

**URL:** <https://ziggit.dev/t/help-with-ptr-casting-inconsistency/4979>\
**Category:** Help\
**Tags:** language\
**Created:** [July 4, 2024, 4:16pm UTC](https://ziggit.dev/t/help-with-ptr-casting-inconsistency/4979 "2024-07-04T16:16:34Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![rdeanmcdonald](https://ziggit.dev/user_avatar/ziggit.dev/rdeanmcdonald/32/2867_2.png) [@rdeanmcdonald](https://ziggit.dev/u/rdeanmcdonald)\
**Post date:** [July 4, 2024, 4:16pm UTC](https://ziggit.dev/t/help-with-ptr-casting-inconsistency/4979/1 "2024-07-04T16:16:34Z")

</div>

Hello! I’m quite stumped on something and was hoping that someone here can help diagnose what’s going on. I’m doing some ptr arithmatic stuff, and something isn’t working as I was expecting it to, here’s an example test to reproduce what I’m seeing:

```zig
const OFFSET = 13;
fn getU64Ptr(data: *[1024]u8) *u64 {
    var bytes align(@alignOf(u64)) = data[OFFSET .. OFFSET + @sizeOf(u64)];
    const u64_ptr: *u64 = @ptrCast(&bytes);

    return u64_ptr;
}
fn initU64Value(data: *[1024]u8) void {
    const ptr = getU64Ptr(data);
    std.debug.print("PTR 2 {d}\n", .{ptr});
    ptr.* = 0;
    std.debug.print("PTR 2 VAL {d}\n", .{ptr.*});
}

test "example" {
    var data: [1024]u8 = undefined;
    // set up some initial bytes
    for (0..1024) |i| {
        var intBytes: [@sizeOf(usize)]u8 = undefined;
        mem.writePackedIntNative(usize, intBytes[0..], 0, i);
        data[i] = intBytes[0];
    }
    const ptr = getU64Ptr(&data);
    std.debug.print("PTR 1 {*}\n", .{ptr});
    std.debug.print("PTR 1 VAL {d}\n", .{ptr.*});
    initU64Value(&data);
    std.debug.print("PTR 1 VAL {d}\n", .{ptr.*});
}

```

I really expected the last log to be 0, but it’s not. It seems that getU64Ptr doesn’t return the same pointer every time, which I really was not expecting. Can anyone explain why?

---

<div class="post-metadata">

**Author:** ![dimdin](https://ziggit.dev/user_avatar/ziggit.dev/dimdin/32/1457_2.png) [@dimdin](https://ziggit.dev/u/dimdin)\
**Post date:** [July 4, 2024, 4:34pm UTC](https://ziggit.dev/t/help-with-ptr-casting-inconsistency/4979/2 "2024-07-04T16:34:24Z")

</div>

`bytes` is a slice, `&bytes` returns the address of the slice, you need `bytes.ptr`.  
`bytes` must be a `const` since it is not modified.  
With the `@ptrCast` you also need `@alignCast`, and this is not going to work for OFFSET=13.

```zig
fn getU64Ptr(data: *[1024]u8) *u64 {
    const bytes align(@alignOf(u64)) = data[OFFSET .. OFFSET + @sizeOf(u64)];
    const u64_ptr: *u64 = @ptrCast(@alignCast(bytes.ptr));
    return u64_ptr;
}

```

---

<div class="post-metadata">

**Author:** ![rdeanmcdonald](https://ziggit.dev/user_avatar/ziggit.dev/rdeanmcdonald/32/2867_2.png) [@rdeanmcdonald](https://ziggit.dev/u/rdeanmcdonald)\
**Post date:** [July 4, 2024, 5:11pm UTC](https://ziggit.dev/t/help-with-ptr-casting-inconsistency/4979/3 "2024-07-04T17:11:35Z")

</div>

Ah I see, makes sense thank you! I’m following along with some c code, the gist is that there’s a buffer with data adhering to a custom format like

```zig
| byte 0 | byte 1 | bytes n - n+8 |
| node_type | ... | u64 id. |

```

I’m trying to get a pointer to the u64 value so it can be read/updated. The c code I’m following gets a void ptr to that location, and it seems it automatically can be cast into a u64 ptr. Are you familiar with a way to do this in zig?

---

<div class="post-metadata">

**Author:** ![AndrewCodeDev](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/278dde/32.png) [@AndrewCodeDev](https://ziggit.dev/u/AndrewCodeDev)\
**Post date:** [July 4, 2024, 5:31pm UTC](https://ziggit.dev/t/help-with-ptr-casting-inconsistency/4979/4 "2024-07-04T17:31:10Z")

</div>

Do you have any alignment guarantees on that buffer? If you don’t, you’re not going to enjoy trying to cast that buffer.

Instead, I would go the opposite way:

1. Make a value of type T
2. Get a slice of bytes to memory of said value
3. `@memcpy` the bytes from the buffer into the value
4. use your value

Very safe bet, imo - no casting shenanigans to buffers that could be aligned to anything or everything.

Edited: Using @mnemnion 's flag value.

```zig
const std = @import("std");

pub fn main() !void {

    // buffer to your source bytes
    var buffer: [10]u8 = .{ 0 } ** 10;

    // consider default value that can be used for debugging
    var value: usize = 0xa5a5a5a5a5a5a5a5;

    // cast to a slice of target bytes
    const bytes = std.mem.asBytes(&value);

    // copy your source to target
    @memcpy(bytes, buffer[2..]);

    // check that you get your result
    std.debug.print("Should be zero: {}\n", .{ value });

}

```

---

<div class="post-metadata">

**Author:** ![mnemnion](https://ziggit.dev/user_avatar/ziggit.dev/mnemnion/32/2478_2.png) [@mnemnion](https://ziggit.dev/u/mnemnion)\
**Post date:** [July 4, 2024, 5:54pm UTC](https://ziggit.dev/t/help-with-ptr-casting-inconsistency/4979/5 "2024-07-04T17:54:05Z")

</div>

> [@AndrewCodeDev](#):
>
> ```zig
> var value: usize = 9999; // obvious flag
> 
> ```

Might be my paranoia speaking, but when doing weird casting stuff I like to ‘color’ all the bytes, usually like this:

```zig
// even more obvious flag
var value: usize = 0xa5a5a5a5a5a5a5a5;

```

Same principle though, just slightly higher odds of catching in a debugger if I clip some edge or other. I even know that decimal printing that value starts with 1193 as long as the high four is still there.

---

<div class="post-metadata">

**Author:** ![rdeanmcdonald](https://ziggit.dev/user_avatar/ziggit.dev/rdeanmcdonald/32/2867_2.png) [@rdeanmcdonald](https://ziggit.dev/u/rdeanmcdonald)\
**Post date:** [July 4, 2024, 5:54pm UTC](https://ziggit.dev/t/help-with-ptr-casting-inconsistency/4979/6 "2024-07-04T17:54:57Z")

</div>

Ohh that should work for my needs! Awesome, thanks a bunch folks.

Just for my own edification, is doing a mem.asBytes and @memcpy similar in performance as writing to a pointer?

I’m new to this lower level programming, but seems like doing `someT.* = newT` must be doing something similar to @memcpy(newTAsBytes, someTAsBytes) under the hood no?

---

<div class="post-metadata">

**Author:** ![AndrewCodeDev](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/278dde/32.png) [@AndrewCodeDev](https://ziggit.dev/u/AndrewCodeDev)\
**Post date:** [July 4, 2024, 6:03pm UTC](https://ziggit.dev/t/help-with-ptr-casting-inconsistency/4979/7 "2024-07-04T18:03:37Z")

</div>

Give a fish or teach to fish… your choice, my friend 🙂

How to use Zig with Compiler Explorer: [https://ziggit.dev/t/how-to-use-compiler-explorer-with-zig/](https://ziggit.dev/t/how-to-use-compiler-explorer-with-zig/)

Compiler Explorer: [godbolt.org](http://godbolt.org)

---

<div class="post-metadata">

**Author:** ![AndrewCodeDev](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/278dde/32.png) [@AndrewCodeDev](https://ziggit.dev/u/AndrewCodeDev)\
**Post date:** [July 4, 2024, 6:07pm UTC](https://ziggit.dev/t/help-with-ptr-casting-inconsistency/4979/8 "2024-07-04T18:07:22Z")

</div>

Yeah - same, it’s 11:00am here… writing good code is an “after noon/coffee” thing haha… cheers…

---

<div class="post-metadata">

**Author:** ![rdeanmcdonald](https://ziggit.dev/user_avatar/ziggit.dev/rdeanmcdonald/32/2867_2.png) [@rdeanmcdonald](https://ziggit.dev/u/rdeanmcdonald)\
**Post date:** [July 4, 2024, 6:07pm UTC](https://ziggit.dev/t/help-with-ptr-casting-inconsistency/4979/9 "2024-07-04T18:07:41Z")

</div>

Thanks for sharing! I’ll explore 🙂
