← Back to context

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.