I ported a small C++ program to see how it would go

There are two bugs in this line of code. Explanation adapted from here:

Implementions of std.Io.Reader and std.Io.Writer rely on being able to use @fieldParentPtr to get a pointer to their containing struct (see here for my attempt at a different way of explaining @fieldParentPtr).

By doing std.fs.File.stdout().writer(&buf).interface you are throwing away the File.Writer struct containing the std.Io.Writer as a field, so when the functions in the File.Writer vtable call @fieldParentPtr it’ll be interpreting arbitrary memory as a File.Writer and lead to illegal behavior.

Additionally, you are taking a copy of the interface field, so even if you weren’t throwing away the File.Writer you’d still have problems (see here for more details on that)

One possible fix would be:

-    var stdout = std.fs.File.stdout().writer(&buf).interface;
+    var stdout_writer = std.fs.File.stdout().writer(&buf);
+    const stdout = &stdout_writer.interface;

Side note: you might be interested in changing main to return !void and replacing your many ... catch {} with try ...

5 Likes