I love C. It's my favorite language. Of course, as I work in the embedded systems field, I'd be very unhappy indeed if it were otherwise.
I love how it is a simple language (it's been said that it is a language that you can "hold in your head in its entirety", unlike C++). I love how the original reference book is the ultimate example of a well-made and concise manual. I love how it is universally supported. Most of all, I love how it maps to assembly in a pretty straightforward manner*.
But I'm still young, and I guess it's a sign of maturity that I start to realize its shortcomings and quirks.
- the difference between putting an include between or between "" ends up being arbitrary. Between carets, it is supposed to be a system include, and between quotes, it should be a user include. But with all the add-on user-libraries we install system-wide nowadays, the difference ends up being arbitrary and useless.
- multiple inclusions. A.c includes B.h and C.h, but B.h also includes C.h. Thus the compiler will complain that stuff defined in C.h is redefined. Hence the wonderful protections against multiple inclusions (#ifndef FOO\ #define FOO\ \ #endif FOO) that exist in header files around the world. Why this isn't yet handled automatically at CPP's level is beyond me.
- Actually, the whole include system is pretty broken. It stems from a technical problem, of course, but having to run around trying to find the include file that defines the function you need is unnecessary, nowadays. We've got powerful source-navigating engines, why aren't they included in the compilers?
- No multiple comment levels. When debugging, it is really useful to comment out a section of code, often increasingly larger. Or to comment out a section that includes comment. Nope, comments end at the first */, so not possible.
- why do people insist on hiding structs and enums inside opaque type names such as ts_thingie instead of a nice struct thingie? I find the latter so much clearer when going over code.
- portable code is a bloody mess full of #ifdef. Good luck trying to follow the flow of your code in that.
- TODO: put more stuff here.
Conclusion: this is just a rant that I needed to breathe out. Each problem I raised exists for a good reason and hasn't been universally solved for other good reasons, which I'm too lazy to research and give here (besides, that's not the point of a rant).
However, it's good spirit to know the limitations of the tools you're using.
I've got to do some Java some day.
*depends on the optimization level, of course, but that I can find the correspondence pretty easily most of the time never ceases to satisfy me.