Comment by pizlonator
2 years ago
> How do you handle unions?
This union is fine:
union {
int* x;
foo* y;
}
It's fine because they're both pointers. This union is also fine:
union {
int x;
float y;
}
It's fine because Fil-C treats both members as "ints" in the underlying type system.
This union has to change:
union {
char* a;
int b;
}
You can turn it into a struct or you can move the `char*` member out of it.
> In the worst case, this seems like you must simply never reallocate memory, or we're discarding parts of the type. If I successively allocate integer arrays of growing lengths, it seems to be it must either return memory that had previously been used with a different type (e.g., a int[5] and an int[3] occupying the same memory at disjoint times) or address space usage in such a program is quadratic, or we're not considering array length as "part of the type", i.e., we're discarding it. (I'm not sure if this is acceptable or not. I think that should be fine, but I'll have to think harder.)
int[3] and int[5] are both integer typed but have different size. The allocator also uses size segregation. It so happens that the virtual memory used for int[3] will never be reused for int[5] for that reason.
There's no problem with this; it's just a more aggressive version of segregated allocation.
The allocator still returns physical pages when they go free. It's just the virtual memory that only gets reused in a way that conforms to type.
And, that part of the system is the most well-tested. The isoheap allocator has been shipping in WebKit for years.
> This union is fine:
I can type pun int & float pointers. (I think this is the same sort of behavior that I'm going to note at the end.)
> You can turn it into a struct or you can move the `char` member out of it.*
A struct is a product type. A union (at least one combined with a tag) is a sum type. I suppose one could use a struct like a union, and the members not corresponding to the variant are just wasted memory …
This is also a breakage from vanilla C, but it's not the first in your language, so I'm assuming that's acceptable. (And honestly sum types beyond `enum` are pretty rare in C, as C really doesn't help you.)
> [isoheaps]
Yeah, so I think your isoheaps are "memory-safe". I would stress that Rust's guarantees are a good bit stricter, and remove behavior you'd still see in your language. Your language wouldn't crash … but it would still go on to do undefined-ish things. (E.g., you'd get a integer, but it might not be the one you expect, or you might write to memory that is in use elsewhere, assuming the write was in-bounds within a current allocation.)
> I can type pun int & float pointers. (I think this is the same sort of behavior that I'm going to note at the end.)
Yes. And yes.
> A struct is a product type. A union (at least one combined with a tag) is a sum type. I suppose one could use a struct like a union, and the members not corresponding to the variant are just wasted memory …
Yup, wasted memory.
> This is also a breakage from vanilla C, but it's not the first in your language, so I'm assuming that's acceptable. (And honestly sum types beyond `enum` are pretty rare in C, as C really doesn't help you.)
Exactly. I'm fine with the kind of breakage where I don't have to rewrite someone's code to fix it. I'm fine with breakage that doesn't slow me down, basically. It's nuanced.
> Yeah, so I think your isoheaps are "memory-safe". I would stress that Rust's guarantees are a good bit stricter, and remove behavior you'd still see in your language. Your language wouldn't crash … but it would still go on to do undefined-ish things. (E.g., you'd get a integer, but it might not be the one you expect, or you might write to memory that is in use elsewhere, assuming the write was in-bounds within a current allocation.)
You're 100% right. It's a trade-off.
Here's the cool bit though: Fil-C has no `unsafe` and no other `unsafe`-like escape hatch. In other words, Fil-C has a lower bar than Rust, but that bar is much more straightforward to meet.