8 ms·
the cake implementation cannot be mapped to rust. I am not rust specialist but one concept for instance is that a owner pointer owns two resources at same time,
by thradams 3y ago
the cake implementation cannot be mapped to rust. I am not rust specialist but one concept for instance is that a owner pointer owns two resources at same time, the memory and object. In rust it is one concept.
Owner pointers take on the responsibility of owning the pointed object and its associated memory, treating them as distinct entities. A common practice is to implement a delete function to release both resources, as illustrated in Listing 7:
Listing 7 - Implementing the delete function
#include <ownership.h>
#include <stdlib.h>
struct X {
char *owner text;
};
void x_delete(struct X *owner p) {
if (p) {
/*releasing the object*/
free(p->text);
/*releasing the memory*/
free(p);
}
}
int main() {
struct X \* owner pX = calloc( 1, sizeof \* pX);
if (pX) {
/*...*/;
x_delete( pX);
}
}
- pitaj 3y agoI don't see why that couldn't be represented like this in Rust: struct X { text: Option<Box<str>>, } fn main() { let pX = Box::new(X { text: None }); // automatically dropped (freed) at end of scope }
- thradams 3y agoIn cake object and memory are two resources. We can for instance, delete the object and reuse the same memory. For instance, this code is correct. #include <ownership.h> #include <stdlib.h> struct X { char * owner text; }; void x_delete(struct X * owner p) { if (p) { free(p->text); free(p); } } int main() { struct X * owner p = malloc(sizeof(struct X)); p->text = malloc(10); free(p->text); //object text destroyed struct X x2 = {0}; *p = x2; //x2 MOVED TO *p x_delete(p); //no need to destroy x2 }
- Arnavion 3y agolet p: Box<X> = Box::new(X { ... }); let x2 = X { ... }; // Moves x2 into the same memory as the first X. // The first X is automatically dropped as part of this assignment. // Also consumes x2 so x2 is not available any more. *p = x2; // Drops the X that was originally assigned to x2 and then moved into p. drop(p); // No need, nor is it possible, to destroy x2.
- masklinn 3y agoAnd as bonus there is no temporal hole where you could access a null or dangling text. Here it is as a runnable snippet: https://godbolt.org/z/fc4Gfxrfd https://godbolt.org/z/fc4Gfxrfd
- thradams 3y agoIn cake there is no temporal hole, we cannot reuse the deleted object. This prevents double free and use after free. int main() { struct X * owner p = malloc(sizeof(struct X)); p->text = malloc(10); free(p->text); //object text destroyed //p->text is on uninitialized state. //cannot be used (except assignment) struct X x2 = {0}; *p = x2; //x2 MOVED TO *p x_delete(p);
- thradams 3y agoThanks for the rust sample. It looks very similar. Can the allocator be customized? As I said I am not Rust specialist. Also, in my understanding is that in Rust, sometimes a dynamic state is created when the object may or may not be moved. In cake ownership this needs to me explicit ( and the destructor is not generated) I also had a look at Rust in lifetime annotations. This concept may be necessary but I am avoiding it. Consider this sample. struct X { struct Y * pY; }; struct Y { char * owner name; }; An object Y pointed by pY must live longer than object X. (Cake is not checking this scenario yet) Also (classic Rust sample) int * max(int * p1, int * p2) { return *p1 > *p2 ? p1 : p2; } int main(){ int * p = NULL; int a = 1; { int b = 2; p = max(&a, &b); } printf("%d", *p); } This is not implemented yet but I want to make the lifetime of p be the smallest scope. (this is to avoid lifetime annotations) int * p = NULL; int a = 1; { int b = 2; p = max(&a, &b); } //p cannot be used beyond this point*