I'm developing a language like Vala and OOC that compiles back to C.
This means that, eventually, every feature needs to be adoptable to C code in some way or another. Generics is one of the features I'd like to implement in my language.
As you probably know, C is a strictly typed language. Except for the opaque void pointer, there is no way to pass an argument of a unknown type. This is because the compiler needs to know the exact size of the argument passed or returned.
The following solutions come to my mind:
- Boxing: Create a union that can store every possible type
- Pass a pointer to the parameter, rather than the parameter itself.
Both of these have their downsides:
- The size of the generic type
T
will be equal to the largest possible type - The sizes are predetermined, a struct with a different size cannot be passed by value
- Slower, because every argument has to be boxed/unboxed
- The size of the generic type
- The parameter is not copied onto the new stack scope
- Memory management issues because of the above
- Not the desired behaviour because of the above
I'm interested in knowing how I could adopt this high-level principle in a lower level language, and also how other high-level languages have conquered this problem.
EDIT
As @delnan has pointed out, another possibility is Monomorphization, creating a new function for every data type. This has a few of the same downsides:
- The type
T
needs to be defined beforehand (not very generic) - The binary size gets larger (which, granted, isn't very relevant nowadays)