back

by uecker·2y ago·view on hn ↗
1. Type safety for generic interfaces such as qsort. 2. Language interoperability. Then you need to have a dynamic framework for constructing types and function calls.
2 comments
Hi Martin, thank you for writing this proposal. This is just my two cents, but one-off void* functions, like qsort, are less of a pain point relative to generic containers. With generic containers it's common to have a collection of void* functions that must be consistently invoked with identical type T. Correct me if I'm wrong, but this proposal cannot genericize a struct field, i.e. it can genericize type 'T' but not 'T->someField'. The latter would be useful for something like 'vec_push(v,p)' where 'v->data[]' is the type T needed to determine if 'p' is a compatible type.

Tangentially related, the macro-based containers you've written here [1] are the best answer for type-generic containers I've come across. One "gotcha" is the container name must be a valid C identifier otherwise it doesn't token paste correctly (see Example #2 of your REAMDE where you typedef'd string* as string_ptr to workaround this). Would you give consideration to a new preprocessor mechanism for concatenating a list of tokens into a single valid C identifier? i.e. Something like CONCAT(struct Foo *) would produce struct_Foo_Ptr? The result is guaranteed token paste-able.

[1] https://github.com/uecker/noplate

Thanks. I agree that data structures are even more important. So I plan to make this for for data structures too (this is not a full proposal yet, just testing the waters):

#define foo(tag, T) struct tag { _Var(T)* p; }

then we also need a solution for the problem you mention. One option I thought about is to allow strings as tags: https://godbolt.org/z/cMc3aPjsK And if the builtin that transforms types to strings you be used as a string literal, this could work nicely. But even better may be to just all parametrizing the tag with a type: struct foo(T)

I am still thinking about this.

If you’re in a situation where you “truly need” type safe generic interfaces, why wouldn’t you just use a different language?

I don’t understand your second point.

The other point: For interoperability with other languages you often need to construct function calls at run-time. For this one needs to be able to describe types. Adding this by external libraries is always a pain because one has to carefully support the ABI of all supported architectures. A compiler can support this seamlessly. A _Typeof operator that returns a type that can be passed around and interrogated at run-time solves this in a very elegant and simple way.
There is no other languages with the same advantages as C and a good type system.
What advantages do you have in mind? Why not just use C++, Ada, or Rust?