I’m running into issues with @fieldParentPtr again and I would like to understand what is happening. Basically I’m trying to make a small wrapper for terminal methods, so I have a struct with some std.Io like so:
stdin: std.fs.File,
stdout: std.fs.File,
input_buffer: [4096]u8 = undefined,
fs_reader: std.fs.File.Reader = undefined,
reader: *std.Io.Reader = undefined,
output_buffer: [4096]u8 = undefined,
fs_writer: std.fs.File.Writer = undefined,
writer: *std.Io.Writer = undefined,
pub fn init() !@This() {
var self: @This = .{
// ...
.stdin = std.fs.File.stdin(),
.stdout = std.fs.File.stdout()
};
// ...
self.fs_reader = self.stdin.reader(&self.input_buffer);
self.reader = &self.fs_reader.interface;
self.fs_writer = self.stdout.writer(&self.output_buffer);
self.writer = &self.fs_writer.interface;
return self;
}
Now, when I try to use self.writer, either inside of declarations on the wrapper or elsewhere, sometimes it works but often I will get either a segfault or a “General protection exception (no address available)”, which immediately makes me think that somewhere along the line the pointer to the interface is getting dropped or copied somehow which is breaking the parent lookup. So, I go through each level in the call stack and add
std.debug.print("{*}\n", .{ wrapper.writer });
and the pointer looks good all the way up the stack, and then I get to that init method above, and I put
std.debug.print("{*}\n", .{ self.writer });
before returning, and suddenly all the problems dissapear. I remove all other debug statements, and everything still just works, but then if I comment out that one debug in the init function, things break again. What is going on here? I’m very confused.