C has a static type system. You can call it limited and you'd be right. But to say it's not a type system is just silly, and just makes the term more confusing. There are types, they're checked, there's a type system.
Calling C's type system 'limited' is asking it to be something that it's not. A skateboard isn't limited because it doesn't have a steering wheel and airbag; if it did it wouldn't be a skateboard.
C's type system is different enough in scope and goals from many other type systems that it leads to confusion to lump them together. That's really what this article is about. The author has miscalibrated expectations.
No, they don’t. Nobody expects to dive into a C program and find that every single function parameter is a void*. That’s just abusive. Yea, the language technically allows it, but it eliminates all possibility of effective cooperation between developers.
> C's type system is different enough in scope and goals from many other type systems that it leads to confusion to lump them together.
C does have a type system, it makes C better than languages without one (like assembler), and faulting C for not incorporating ideas invented in the decades after C was invented is also abusive. Claiming that it isn’t good enough to be called “a type system” is just an attempt to change the language so that you are always right.
"type system" actually means something substantial in the era of C's relevance, and C specifically didn't have one.
But nobody apparently cares about the in-context meaning of these words anymore.
Operating system, UNIX system, the system() function, system calls are costly, try find any mention of type system in the K&R C book [0]. Search for the word system, it's always in the context of something relatively huge, complex and usually runtime-dynamic vs. the C language.
To call C's type checking a type system is to completely misunderstand something fundamental about the language.