In the standard library, I see this pattern everywhere, for example in BufSet and BitStack:
pub fn deinit(self: *@This()) void {
self.bar.deinit(); // or other actual freeing of memory
self.* = undefined; // why?
}
What is the purpose of self.* = undefined here?
The only reason I can think of is to make it easier to spot usages of something that was already deinitialized, as 0xAA is written to undefined in debug mode. Is that truly the only reason?
Some time ago I read the same thing somewhere else in the stdlib (I think, mightve been the same thing) and wondered what it was for. I came to the same conclusion as you.
It informs valgrind and can be used for optimization. So slightly more than just writing over memory in debug/safe. It also communicates that this container is now invalidated and thus may not be used after .deinit(). Mistakes in reusing it result in a likely segfault which can be caught by the runtime in modes where it’s overwritten and explicitly marked UB otherwise.
Outside of debug, it should not emit any machine code, but it could improve the code around it. There’s been a bug where, sometimes, the compiler forgets to remove the write, but I think it’s been solved.