Skip to content

Instantly share code, notes, and snippets.

@via
Created July 13, 2019 13:38
Show Gist options
  • Save via/1bd5854801b7cfe986c37d16d20fee68 to your computer and use it in GitHub Desktop.
Save via/1bd5854801b7cfe986c37d16d20fee68 to your computer and use it in GitHub Desktop.
pub const Console = struct {
buf: [1024]u8,
outstream: std.io.SliceOutStream,
pub fn init() Console {
var ret = Console{
.buf = undefined,
.outstream = undefined,
};
ret.outstream = std.io.SliceOutStream.init(ret.buf[0..]);
return ret;
}
pub fn process(self: *Console) void {
self.outstream.reset();
self.outstream.stream.print("rpm: {}\n", c_tfi.config.decoder.rpm) catch unreachable;
self.outstream.stream.print("fueling_us: {}\n", c_tfi.calculated_values.fueling_us) catch unreachable;
const output = self.outstream.getWritten();
std.debug.warn("{}", output);
}
};
@mikdusan
Copy link

mikdusan commented Jul 13, 2019

  • line 6: ret is an instance of Console put on stack with undefined values
  • (side note: since it's all defined you could also do var ret: Console = undefined)
  • line 10: copy a new value to outstream which stores a copy of slice ret.buf[0..]
  • at this time everything is valid
  • line 11: return the structure. it is copied to callsite because you first put it on stack
  • but ret.outstream still has a pointer (slice) to line 6's stack var -- which is no longer valid

there is a new result-location mechanism as part of copy-elision in zig. and it allows returning structs to callsite that elide redundant copies. and it works like this. imagine if we could init the struct in one shot:

return Console{
    .buf = undefined,
    .outstream = std.io.SliceOutStream.init( ??? ), // but how do we self-reference .buf? there is no syntax for that (yet?)
};

this would be ok if we were able to self-reference because zig is using callsite storage for Console in this return statement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment