Hacker News new | past | comments | ask | show | jobs | submit login
Learning To Drive a Stick Shift: Why Programmers Should Know C/C++ (codingthewheel.com)
12 points by dnaquin on July 20, 2008 | hide | past | favorite | 32 comments



The simile is imperfect.

Driving a manual car, rather than an automatic, teaches you nothing about cars, possibly bar the fact that they have gears. Even that is tenuous: the interaction between the clutch, stick and accelerator is a very abstracted interface to the actual drive mechanism of a car. Manually changing gear is just an extra dexterity skill to learn.

And the opinion is out of date.

The "learning x will make you a better programmer" argument has been made before. However, last time, x was Lisp. This makes sense, because in that case you're sacrificing performance to gain better tools to problem solve. But, in this article, the argument is that learning C++ teaches you about computing basics - memory allocation, storage, retrieval etc. But these things just aren't that relevant anymore. Problem solving tools are generally useful. Technical details are specifically useful, and thus less enriching.


Driving a stick shift well teaches you not only that cars have gears, but that the power output by an engine depends on RPM, that your car has synchronizers and that you can reduce the wear on them, etc.


I live in Norway. Most people here drive stick-shifts. I can guarantee you that the vast majority of people driving stick-shifts have no idea what synchro rings are, nor would they be able to point them out if you cracked a gearbox open and told them to point them out. So yes, the simile is flawed.

As for the usefulness of learning C or C++, I do think it is useful as a learning exercise. As would assembly programming be. I have met developers who considered themselves "experienced" who are unable to estimate memory requirements for simple data structures. I've had people tell me that pointers are "about one byte" and people who insist that the most compact way to store a boolean value is as an int value.


Note that he said well. Yes, you can drive a stick to work and the grocery store without learning anything significant about it at all, just like you can write "Hello World" programs in C++ without really knowing anything about pointers, dynamic mem allocation, etc. But in both cases, to be able to do anything significant, you'd need to learn more than the absolute basics.


I am so sick of people mixing up C and C++ when making this argument.

I can think of thousands of reasons to use C. C is much like learning to drive a stickshift.

C++ is an utterly broken language. It's just an exercise in bad compiler errors, strange and inconsistent language constructs, and strange conventions and boilerplate you need to follow to produce correct code.


Bollocks. C++ is a way to achieve everything C does with a fraction of the code and greater safety.


    * No compile time encapsulation
    * Outstandingly complicated grammar
    * No way to locate definitions
    * No run time encapsulation
    * No binary implementation rules
    * No reflection
    * Very complicated type system
    * Very complicated type-based binding rules
    * Defective operator overloading
    * Defective exceptions
    * Duplicate facilities
    * No high-level built-in types
    * Manual memory management
    * Defective metaprogramming facilities
    * Unhelpful standard library
    * Defective inlining
    * Implicitly called & generated functions
</quote> Defective C++ http://yosefk.com/c++fqa/defective.html


Everything in that list that includes the words "defective", "complicated" or "unhelpful" is an opinion.

If we eliminate those, the list reduces down to about eight objective criticisms, of which several are just wrong (No high-level types? Bzzt. The STL is part of the language), and others that are minor variants of the same complaint (that it's not a dynamic language).


The quoted site explains in depth the words "defective", "complicated" or "unhelpful" (and about STL being high-level too).

I've posted a short outline to provide a context for the link. It is easy to read and the critique it provides is worth reading by any C++ programmer.

Do not believe my words, just try to read it and see for yourself.

EDIT: I want to make it clear. C++ is a valuable tool for some tasks. But.. No size fits all. And knowing the weaknesses of the tool at hand does not hurt either.


Yes, I've read the site before. I don't have the time or inclination to rebut every point that he makes, but many of his criticisms boil down to the fact that he just doesn't like the complexity of C++ (which is fair, but it's still just his opinion.)

The "high-level" criticism, in particular, quickly devolves into a complaint about the complexity of template generics, and how the error messages emitted by current C++ compilers are cryptic. It's unclear what his solution to the problem would be, short of a fully dynamic type system.


Sure, if you know (to pick just one example) what a protected abstract virtual base pure virtual private destructor is, then yes, you're probably right to choose C++ over C.

(http://amalp.blogspot.com/2007/10/what-is-protected-abstract...)


"protected abstract virtual base pure virtual private destructor"

That's a troll example, designed to be maximally unreadable. The first four words refer to the class, and the last four refer to the function; moreover, one of the words in the former is implied by the latter. So, when you munge it all together, and include more words than necessary, then yeah, it sounds complicated. Thing is, nobody actually does that, unless they're writing articles that bash C++. (In this case, you'd say that you have a protected base class, whose destructor is pure virtual and private. The fact that the base class is declared "virtual" is of no consequence to the destructor.)

There's no doubt that C++ is a complicated language, but if you're going to criticize it, at least reach for something that's a bit more insightful than "you can obfuscate your code!"


OK. It's a poor example. I think the problem with C++ is that it contains far too much syntax, and there are all manner of weird edge cases which you basically have to learn by rote. (For example, how templates interact with the preprocessor and vice versa).

And why is the keyword 'virtual' even necessary? Surely all methods should be virtual by default (and the compiler ought to be able to replace virtual calls with direct calls based on the type information). Can anyone cite an example of where you'd actually want to call different methods depending on whether you're using a base or a derived pointer?

I think trying to bolt an OO model onto C while retaining 100% source compatability was an interesting idea, but it turned out to be a bad one in the long run. 90% of the complexity in C++ you don't actually need, you can get by just fine with C, and you have the added bonus that you can hold pretty much the entire language and a significant portion of the standard library in your head the whole time whilst you code, which I never managed to do with C++.

Admittedly, my experience is probably informed by having to maintain some seriously hideous C++ code over the last 10 years.

So, there, C++ is a complicated language. Some might say it's too complicated, but I guess everyone has to do their own cost/benefit analysis on that.

Is that better?


"why is the keyword 'virtual' even necessary? Surely all methods should be virtual by default (and the compiler ought to be able to replace virtual calls with direct calls based on the type information)."

And how is the compiler supposed to determine the (possibly dynamic) type of an object at compile time, in order to determine when to make the call statically?

If you declare a method virtual, you're telling the compiler to use late binding. If you don't, you're telling the compiler to use early binding. You always know what you're going to get. That's why the keyword is there -- so you don't have to guess.

"Can anyone cite an example of where you'd actually want to call different methods depending on whether you're using a base or a derived pointer?"

Not sure what you're asking here. Are you talking about the ability to hide a base class method with a derived class method? It's not really considered a good idea to do such a thing (see: http://www.parashift.com/c++-faq-lite/strange-inheritance.ht...), but it's an inevitable consequence of mixing early- and late-binding features in the same language.


Are you talking about the ability to hide a base class method with a derived class method? It's not really considered a good idea to do such a thing, but it's an inevitable consequence of mixing early- and late-binding in the same language

Yes. It sounds like we agree that overriding a non-virtual method is a bad idea, and i think "mixing early- and late-binding" probably captures it quite well. The C++ compiler makes the programmer decide whether to use early or late binding, and handle the consequences.

In some other languages (let's say Self, for example), the distinction between early and late binding is handled by the compiler, so it's invisible at source level, and all methods are (implicitly) virtual unless the compiler can prove that a static call is safe, in which case it can inline the call. That means that the "early-binding conflict" situation can't arise in a language like Self.


I think trying to bolt an OO model onto C while retaining 100% source compatability was an interesting idea, but it turned out to be a bad one in the long run.

Oh, I don't know, Objective-C seems to do a reasonable job of it. C++ just took the wrong object model...


Love the metaphor. But people said the same thing about learning assembly, and assembly is inessential.


Inessential, yes. But I'm pretty sure that there are cases where knowing Assembly makes you a better C programmer.

It lets you understand, for instance, why accessing the elements of an array in one order is faster than in another order. Or something. I don't know, because I don't know Assembly. :( But I'm pretty sure that if I did I might be a slightly better C/C++/Fortran programmer than I am.


Learning assembly actually probably isn't going to teach you that either, because the reason one access ordering is beating another is probably due to the cache, and that's microarchitectural.

Not to be, you know, pedantic about it or anything. I liked your response. =)


Ah, well there you go. If I knew Assembly I'd know have known that knowing Assembly wouldn't have helped me. Either way, it's apparently a useful skill that I lack.


funny. i helped a friend of mine recently with their C++ homework. in their school C++ is the introductory programming class. i likened it to trying to drive a manual car up and down san francisco without first learning to manage the wheel

apparently it's a weeder course


I think its handy to have a start in the programming world with C or C++. It being your first language, you will definitely have a good grasp of pointers, memory etc (as they are closer to the machine). Infact, I had taken an assembly language class(sopho/junior year) as well in school where we had to sometimes hand compile an Instruction to Binary. I thought it was really cool to actually see a PSHA (Push register AR) convert to say 1011 1001 and how it triggers the gates in a microprocessor. I hardly use assembly in work or personal projects, but knowing all these memory saving techniques definitely help you in writing good code in Higher Language Languages.


Can we please stop calling these two languages C/C++? I cringe every time I see it.


Nowadays we should certainly use C/C++/D.


Understanding the algorithms in your code, both the ones you wrote and the ones that the the compiler/interpreter are adding, is the useful thing in my view. In as far as C forces you to explicitly deal with many of these issues manually it would help with your understanding of this. Usually however the difference in complexity (both space and time) between the algorithm you think you are using and the one the computer is using constant or at worst Log(n) which doesn't justify delving into the lower levels such as C or machine code.


In freshman science labs, students often repeat classic experiments from the past. Even if the experiments are outdated, the idea is to learn techniques and methodologies that are relevant even today.

I grant you the simile is imperfect, but I'm a firm believer that learning C/C++ can make you better.


C yes, C++ definitely not. C will help because it will introduce people to how things are actually stored in memory and because quite a few high level tools are implemented in C. C++ will just confuse the learner with excessive syntax.


I generally agree, C comes in really useful in a lot of places. It's certainly the best nuts-and-bolts language.

Although at the same time, I find that C++ can be quite useful if you are disciplined in what parts of it you use.

I think it's great that you get some decent data structures (Standard Template Library) out of the box.


yes. i've come to the conclusion not that learning c is helpful but that writing malloc is helpful. i'm eternally grateful that was assigned as a project my sophomore year.


Could you provide details on what the project requirements were? I'm interested in doing a similar exercise.


_Tons_ of computer systems courses are taught out of the same book from CMU: _Computer Systems: A Programmer's Perspective_.

You can search for "malloc lab" and find tons of copies of the assignment (with only the instructor names and course numbers changed), but here's one:

http://www.cs.cmu.edu/afs/cs/academic/class/15213-f02/L6/mal...


mine was http://www.owlnet.rice.edu/~comp320/2007/assignments/malloc/.... or something similar a handful of years prior.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: