Jach's personal blog

(Largely containing a mind-dump to myselves: past, present, and future)
Current favorite quote: "Supposedly smart people are weirdly ignorant of Bayes' Rule." William B Vogt, 2010

Some problems with C and C++

First off, let me list the two things I love about both C and C++.

  1. They're freaking fast

  2. You can muck with logical memory directly

If it weren't for these two features, I'm certain the languages would have died long ago.

To get my bias out of the way, I'm a Pythonista at heart, though I have experienced Lisp in all its glory and love it (closures for the win), as well as seen the Perl side and mostly enjoyed it.

Anyway, I think most of my problems in C and C++ can be generalized to their obsession with imperative style programming and static types (and can be generalized further with their lack of abstraction). If you're a die-hard C/C++ fan, you're probably already hating me for spitting on your language, and a typical reply I've heard when I say language X can do something C can't, is that "Wrong, C can do anything."

On a technical level, yes, C and C++ can do anything. But so can Assembly. In the end, it's all just a series of voltages that correspond to physical instructions that change the state of your hardware. The Game of Life is even Turing Complete, it too can do anything.

But if C and C++ can really do anything, then why aren't they the only two languages around? Because Assembly can do anything, but the amount of work required to do even trivial things like division is annoyingly large. Additionally, the amount of work required to do anything now considered trivial in C is equally annoyingly large. The language just doesn't support tools for abstraction. Too many things are hard-coded in the language itself.

Yes, C can do object oriented programming, and the syntax isn't awful for trivial cases where you only need "a struct with functions". But you have to allocate memory and deallocate it yourself. You can't overload the syntax of your language to make what you're doing cleaner. Good luck doing inheritance without banging your head in frustration. After you become sufficiently frustrated, you'll likely make a C program that will take some text file you wrote in a way that makes sense and converts it into the ugly C that kills your brain. But when you do this, you've invented a new language. (People don't do this much because unlike in Lisp, it is very hard to parse anything in C.)

C programmers have blindspots they're not even aware of having, like moral crusaders out to eliminate or reduce some cause of death without thinking about stopping death itself. I can get some to admit dynamic typing would be nicer. Though the C++ people shored up that problem with templates, introducing a whole new set of problems that simple dynamic typing solves much more elegantly. (And in various Lisps, you can even give type-hinting to produce faster code, therefore dynamic typing isn't required either. Python has ctypes and other tools to speed it up.) It's very difficult to think of strings as strings, or even sentences, in something like C or C++ when even with a string class you always have to be aware of the underlying array of characters.

C and C++ have their abstractions, but they only abstract the syntax, not the thinking. You can make OOP-like syntax in C... But in C, you can't ever forget you're dealing with function pointers and structs. You can make convincing strings in C++, but you can't ever forget it's a character array at the bottom (and you have to remember all of C++'s OOP rules to boot). With Python, you can make whatever you like, and think in terms of that, forgetting what's at the bottom if you want. In Scheme, people don't even realize that it's all functions and pairs until later, and after that it's just a cool feature they can use, they don't have to think that way. In C and C++, you can't ever forget it's all pointers.

What makes a language great is in how much it lets you change the language. Lisp has obscenely powerful macros. Python lets you change almost everything but the forced indentation and duck typing. And of course, being Turing Complete, even these limitations aren't strict, but by the time you've gotten around them you've pretty much invented a new language.

Imagine if you could change the #include directive of the C preprocessor. Instead of just blindly copy-pasting the file contents into the current file, what if you could make it do something smarter? At the very least, how about only copy-pasting a small portion of the other file's contents into the current file?

I could rant on and on, but I need to do some real work (unfortunately a bunch of it is C and C++ programming). I'll finish by saying the smugness C++ programmers have when they look down their noses at C programmers is annoying at best, especially when the Lisp world has had more powerful features than anything C++ has for over 50 years. It's annoying to see an attitude of superiority when it's clear from the outside view that there's nothing to feel superior about. C++ still has many of the warts C does, such as static typing. Really, it's sad to see people excited about something when if they knew better they wouldn't feel that excited. OOP is an old idea, and C++'s way of doing it isn't even the best way. I'm happy that more attention is being placed into just-in-time compilers these days, because there's no reason a higher level language should be slower than handwritten C or C++ on the account of simply being higher level. Obviously interpreted languages (which for some reason snobbish programmers stuck the label "scripting languages" to in a derogatory way (though that attitude's mostly gone these days)) have some speed implications on account of being interpreted, but even that shouldn't matter as much as people think it does, especially on code run for the second time.

I'm getting myself into the game industry, one of the last refuges of C and C++. It would make me nothing short of ecstatic to see those two languages uprooted, because it's perfectly clear to anyone who has seen the higher plane they're only there for brute-speed.

You can do anything in {C++, Python, a Turing machine}, but you might want to choose a language that's well suited for your task at hand even though any of them can do it in principle.

Addendum Addendum: I think I just get really irritated when I see metaignorance.

Posted on 2010-04-06 by Jach

Tags: c, c++, programming, rant


Trackback URL:

Back to the top

Back to the first comment

Comment using the form below

(Only if you want to be notified of further responses, never displayed.)

Your Comment:

LaTeX allowed in comments, use $$\$\$...\$\$$$ to wrap inline and $$[math]...[/math]$$ to wrap blocks.