I complained earlier about this. But how to rewrite this in some orderly fashion?
var s = MoveStorage.init();
// after this call s.ptr is *not* pointing to s.moves.
pub const MoveStorage = struct
{
moves: [224]Move,
ptr: [*]Move,
pub fn init() MoveStorage
{
var result: MoveStorage = undefined;
result.ptr = &result.moves;
return result;
}
(Using an index will be slower)
Here’s one approach for self-referential inits:
const std = @import("std");
pub const MoveStorage = struct {
moves: [224]u8,
ptr: [*]u8,
pub fn init(storage: *MoveStorage) void {
storage.ptr = &storage.moves;
}
};
pub fn main() !void {
var storage: MoveStorage = undefined;
MoveStorage.init(&storage);
}
1 Like
I suppose you could even do this, right? Then you can’t forget to initialize a new field in the future.
storage.* = .{
.moves = undefined,
.ptr = &storage.moves,
};
1 Like
Yeah, I think that’s better in general
Btw, what do you mean by this? Surely you are not talking about ptr.*
being faster than baseptr[i]
right?.. right?
Loading from memory just outweights athrimetics on the pointers, I would expect the two to be the same. Even better with indices since you can just use u8 index and overall fit more things in the cache line, more chance for cache hits.
There are so many instances of people realizing that storing indices are vastly better than storing pointers that I think it is not a coincidence or personal taste anymore. For example, @floooh’s article Handles are the better pointers, or @andrewrk’s Programming without pointers talk. Or say, C++ folks realizing storing container reference inside iterators might not be the best idea: GitHub - tcbrindle/flux: A C++20 library for sequence-orientated programming. And funnily, all for different reasons, but the same overarching theme of storing indices, not pointers
3 Likes