3 ms·
You are entirely correct, and I should perhaps have been more precise. However, because Lisp_Objfwd is basically a pointer, zero-initialized is pretty much as g
by db48x 8y ago
You are entirely correct, and I should perhaps have been more precise. However, because Lisp_Objfwd is basically a pointer, zero-initialized is pretty much as good as uninitialized. It's not a useful value.
- danaliv 8y agoIt fails a NULL check, where an uninitialized value (probably) won’t. That seems like a pretty important distinction, no?
- db48x 8y agoIn C, yes, that's a useful distinction. One of the goals of Rust is that you'll never have to check that manually. You'll never encounter a pointer that points to an invalid, uninitialized, or unallocated object. Since we're writing some unsafe code here, we can operate outside that restriction as long as we promise to put things right before the end of the unsafe block. This can be simplified somewhat once everything is written in Rust.
- beagle3 8y agoThe C spec says zero in a pointer context is null (and the other way around) Can you elaborate on “as good as uninitialized”?
- db48x 8y agoYou can't ever usefully dereference a null pointer, so the only thing you can safely do with it is check to see if it is null. I commented on a sibling comment in more detail, but basically in Rust no reference is allowed to be null except temporarily inside an unsafe context.
- kazinator 8y agoThere isn't anything you can do safely with an actually uninitialized value, though. In the internals of TXR Lisp, I used a null pointer to represent the symbol nil, with all the useful semantics that follows. If an object containing Lisp values is initialized to zero, those values are nil.
- db48x 8y agoYes, Emacs and Remacs do the same thing. All Lisp values are tagged pointers, and a nil gets encoded as a zero value with a zero tag. It's simple and easy to check for, and you won't have any problems as long as you always remember to do so. However, this is not a Lisp value; it's a pointer to one. Specifically, it's a pointer to memory set aside to store a specific Lisp variable's value. Leaving it zeroed makes no sense, because eventually someone is going to store a value in there and it'll have to be allocated anyway. Better to do that all in one large block, rather than a thousand tiny ones. Even if we wanted to lazily allocate these, we can't leave a simple Rust reference (or pointer) null past the end of the unsafe block. Rust does have an Option type, and if you use it on a type that isn't nullable, then the compiler will use the zero value for None variant and all other values for the Some. Since references can never be null, an Option<&T> will always take up the same amount of space as a &T; there's no additional overhead. At some point, when enough of the C code is ported to Rust, I'm sure we'll start using this to represent all Lisp values and a Lisp nil will always be a Rust None.
- tom_mellior 8y ago> Even if we wanted to lazily allocate these, we can't leave a simple Rust reference (or pointer) null past the end of the unsafe block. So make it an Option, and get rid of the unsafe block altogether.
- db48x 8y agoPerhaps one day we will be able to do so.