Writing Type-Safe Generics In C

The fun part about a programming language like C is that although the language doesn’t directly support many features including object-oriented programming and generics, there’s nothing that’s keeping you from implementing said features in C. This extends to something like type-safe generics in C, as [Raph] demonstrates in a blog post.

After running through the various ways that generics are also being implemented using methods including basic preprocessor macros and void pointers, the demonstrated method is introduced. While not necessarily a new one, the advantage with this method is that it is type-safe. Much like C++ templates, these generics are evaluated at compile time, with the preprocessor handling both the type checking and filling in of the right template snippets.

While somewhat verbose, it can be condensed into a single header file, doesn’t rely on the void type or pointers and can be deduplicated by the linker, preventing bloat. If generics is what you are looking for in your C project, this might be a conceivable solution.

13 thoughts on “Writing Type-Safe Generics In C

    1. And a number of the explanations I’ve seen in trying to prepare to understand the blog post that is the subject here, don’t really explain it, either. They try to explain an abstraction by giving abstract examples.

      What I have been able to determine is that a generic is a way of declaring objects where we don’t know what type they refer to until they’re used. With the tricky part being that you somehow have to ensure that each type is handled correctly. But I’m writing from relative ignorance, here.

      But I would agree: a sort of primer on what generics are and why they need to exist would probably find an audience here.

      1. First you have to understand what a type is, in the first place. A type is a set of values, given by extension (enumeration) or by rules, with their valid operations. Then a generic type can be thought as a parametric type, that is, a set of sets of values, which you can select one instance of by specifying parameters.

    2. I agree. I think it means: If you want to implement say a stack (to use the example in the linked blog) so you push things onto the stack and pop them off again… what are those things? chars, ints, longs, floats, arbitrary structs? If you use generics it doesn’t matter… you write the code once and can have a stack of any type you choose. A stack is pretty trivial but it could be a sorted doubly-linked list with functions to add and remove items from front, middle or end – you only need to write the difficult bit once. (Although here it seems messing with the C pre-processor was the difficult bit.)

    3. I think BrightBluJim hits it pretty close. I don’t know the exact “computer science” definition, but with my experience in C++ and FreePascal/Delphi I have come to think of them as “super macros”. I like the C++ term “template” better than the much too generic “generic”. :))

      The idea is that many algorithms apply equally well to many data types. The problem with a strongly typed language is that you end up “copy & pasting” the same code to make it work with different types so that you can change the data type in the new copy.

      Think of a sort algorithm. If you replace the type declaration of your values to be sorted with a replaceable parameter you can write the sort once and have the compiler write new copies to deal with which ever types you want to sort: strings, ip address, integers, floats, specific record/structure types, …

      I hope this helps. I can’t wait to read this blog post to see how he handles things. Fun, fun!

  1. It’s clever because he’s using a feature of the C preprocessor (macro expansions) to do things in C that the preprocessors in object-oriented languages take care of to implement generics.

    It seems like there’s long been a thing where people try to do things in one language that they brorrow from another language. I’ve had some success in doing some OO-like things in C that aren’t part of C but borrowed from C++. In one example, I used the variable ‘this’ to refer to the current instance of an object in functions in that class. Which is perfectly valid in C++ but isn’t a keyword in C, and even though I had declared it as a variable, gcc wouldn’t let me do that because ‘this’ IS a keyword in C++, and it knew that I was probably doing something shady. I ended up changing it to ‘ths’, which quashed the warnings.

      1. This was about 15 years ago, so a) I’m not sure whether or not I tried that, but it seems like I would have, b) I consider it a bug either way, and c) they may have fixed it by now.

        And on the other hand, I try to write C code so it won’t barf too badly if compiled in C++, so I don’t mind considering that a reserved word anyway.

  2. “The fun part about a programming language like C is that although the language doesn’t directly support many features including object-oriented programming and generics, there’s nothing that’s keeping you from implementing said features in C.”

    Basically someone did exactly that! A guy named “Stroostrap” or something. You can find his projects here: https://softwarepreservation.computerhistory.org/c_plus_plus/

    Note that if you want to build any later version, you will have to build the previous versions because they all build on each other.

    :P

    1. Yes, well, some of us aren’t too happy with the job he did (and your last sentence serves as an example), so there’s still a case for finding your own way to do object-oriented coding in a REAL language.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.