What a C++ programmer needs to learn

greenspun.com : LUSENET : Joel on Software : One Thread

Charles Lin asks Joel: "What do you think are the important things students need to learn if they are to become good C++ programmers." I would like to analyze Joel’s response one item at a time:

1. the relational model and modern DBMSs An important topic regardless of programming language choice. I would like to point out, however, that C++ is probably not the best language in the world to use for your DBMS development projects. For example, for DBMS front ends I would probably recommend VB and for server-side access maybe Java.

2. user interface design and usability Again, an important topic regardless of programming language. And again C++ may not be the best choice for building UI. At the very least some frame-work will be used.

3. techniques for coding on large teams 4. software design and writing functional specifications Can’t argue with these, though again nothing here specific to C++.

5. Debugging Not a C++ specific issue but debugging C++ applications (particularly those using STL) is certainly an experience ...

6. Windows and COM programming Funny, MS calls Windows (Win32) and COM programming "legacy". They say you should be learning .NET, and using C# not C++

7. sockets programming and common Internet protocols For sure.

8. database-backed web site development C++ is currently not the language of choice for building web applications. The future looks like Java, EJB and JSP or C# and .NET

9. writing! Because great programmers are great communicators This item probably needs to be a separate course.

I would add that a C++ programmer needs to learn: 1. The C++ standard 2. STL and the rest of the C++ Standard Library (Indeed Stroustrop seems to encourage teaching std::string before classes) 3. OOP 4. Design patterns (and anti-patterns) 5. UML 6. Generic programming (sort of goes with STL) You'll be amazed (or not) at the number programmers I've seen using C++ (with classes) to write spaghetti code. If a programmer can write good, clean, understandable C++ code using the Standard facilities then she is on the way to being a good C++ programmer (better than the average that's for sure.)

Dan

-- Anonymous, August 23, 2001

Answers

Well, my positing really came out formatted badly :(

Two additional items that should be on the C++ student's colloquium:

1. Defensive programming - proper use of asserts and traces, preconditions/post-conditions etc (sort of related to debugging or avoid there off). Important for any programming language but very pertinent for C++ ;)

2. Error handling - How many of said students know when they should use error return values vs. exceptions vs. assertions? Proper error handling is the difference between a programming exercise and a real- world application.

Dan

-- Anonymous, August 23, 2001


I notice the lack of things like 'assembly' and 'compilers', which is interesting since they seem to be shibboleths of computer science these days - gotta have 'em. I'm not sure why they should be required at this point.

Strikes me as a bit like an art school teaching students how to grind up clays and minerals to make pigments to make paint, just because that's what the field's originators did.

Sure, one student in 1000 might have an interest, but there are well-paid chemists working on pigments, and companies that produce pigments of better quality (fade-resistance, etc) than an artist is likely to be able to match. And many artists will just buy pre-made materials, and not even be interested in working at the level of pigments. (And other artists won't be working with such media at all.)

Likewise, most developers who aren't in Comp.Sci graduate programs can probably do without knowing assembly. And in the unlikely even that a typical corporate developer came upon the need for a compiler or parser, they'd probably be well advised to not rely on some long-forgotten compiler class, and find some way to use a third party solution (flex/bison-based, some sort of easily-parsed format like XML).

The same argument could be applied to the math requirements in some Comp. Sci. programs. The curricula seem to be designed for someone who will go on to foundation-level graduate research in Comp. Sci., as opposed to someone who will go on to write user-level applications using a mix of third-party code and original code - which, I'd guess, is what the vast majority of developers are doing. Chances are those legions of PeopleSoft and SAP developers aren't laboring over new phoneme recoginition algorithms or path-finding algorithms.

Other fields seem to have acknowledged the ability of its practitioners to specialize, so why not CS? Not everyone in CS needs to be trained as mini-Knuths.

-- Anonymous, August 24, 2001


I heartily disagree! Every good programmer should know at least a little about assembly language, compiler writing, and computer architecture. And math, for that matter. Particularly proofs.

Programming is in essence giving orders to a computer. The goal is to give orders as well as possible. The computer should be able to do its job efficiently and correctly. This requires knowing how the computer works, knowing how algorithms work, and knowing how some standard software works. Without this information, the programmer is essentially a tribal shaman trying to figure out what combination of herbs and spices in his sacrificial chicken will make the harvest successful next year.

The programmer needs to know which algorithm will do the job quickly and correctly. That requires mathematics - analytic thought. The programmer will need to know what inputs to the program are possible, and what they mean. This requires knowledge of standard software - for example, a network programmer may have to know the standard contents of a TCP/IP packet.

Finally the programmer will have to know how to diagnose problems in software, including some very potentially weird ones. Why did the JVM crash for my pure Java program? Why is my C program not doing anything? Why is this JavaScript code causing my browser to hang? These are bugs which I guarantee will stump anyone who chooses to specialize in Java, C, or JavaScript to the exclusion of assembly and architecture (and browser architecture, in the latter case).

Now, I'm not saying every programmer should write at least one program for a PDP-11. Or deal with punchcards or switches. Or design a chip. I've been programming for almost 20 years, and I've never done any of these.

However, I deem it necessary to get some exposure to things like the difference between your C++ source, the C code equivalent for it, and the machine code for that. You need to know what sorts of things a compiler may do to your code, so that you don't waste hours carefully optimizing a program that is optimized automatically, or write something that would use up all memory by accident, or write a security flaw into your code. You need to have at least some idea of how the instructions are followed by the CPU, and how data is shunted to registers, RAM, the graphics card, etc. In this way, the programmer is like an experienced farmer who knows the roles water, sunlight, soil, chemicals, and wildlife play in making the crops grow.

Computer hardware and software is based on layers. A layer is intended to abstract what's below from what's above, to make it easier to build the stuff on either side. These layers aren't perfect. Some layers have cracks and holes, some being bugs, some being intended. The good programmer knows not only the layer of specialty, but is also familiar with a few layers up and down.

-- Anonymous, August 27, 2001


"I've been programming for almost 20 years, and I've never done any of these."

What was your education in? CS?

The flaw in the argument is that there are, in fact, quite good developers who have been educated in Music, Econ, and other non-CS fields.

"However, I deem it necessary to get some exposure to things like the difference between your C++ source, the C code equivalent for it, and the machine code for that."

Sometimes. For some kinds of code. Not for others. What kind of code do you primarily work on? These would be more appropriate for someone who is working close to the metal. Most developers don't.

" You need to know what sorts of things a compiler may do to your code, so that you don't waste hours carefully optimizing a program that is optimized automatically."

This is pretty much covered by the adage, "Don't optimize prematurely". I suspect most developers would get more mileage out of knowing how to optimize SQL.

", or write something that would use up all memory by accident,"

You don't need assembler, compilers, or Differential EQ to know that.

" or write a security flaw into your code."

Or this. I'm sure plenty of security flaws have been written into code by people with CS degrees. What's Microsoft's excuse?

" You need to have at least some idea of how the instructions are followed by the CPU, and how data is shunted to registers, RAM, the graphics card, etc."

You can get enough of an idea without an assembler course. You'll have to revisit the topic anyway if you change processors. I doubt most Java developers worry about it.

Likewise, you don't really need a ton of math to understand Big-O notation. I expect most developers will use library- provided algorithms as a first choice (and they probably should), second choice would be grabbing one from a text like Sedgewick, and only the rare developer will be getting into heavy math to invent a new algorithm.

An understanding of big-O notation isn't that difficult. Kernighan and Pike cover it in less than 2 pages in _The Practice Of Programming_. No higher math involved.

I'm still not convinced.

-- Anonymous, August 27, 2001


My education is in CS/Math. Why, is my bias showing? :-) Perhaps I am biased. On the other hand, I'm big on quality programming mostly because of my perspective as a user, and less so as a mathematician. I've seen countless bugs, and I know the causes. The causes are mainly cultural.

I'm going to retread a very old argument. It has to do with the math student who asks the teacher when any of the stuff in math class is really going to be useful in real life. The question is ironic, because the very question illustrates the answer. The answer is, very little higher math is directly applicable to real life. Rather, it's the mental exercise one necessarily accrues on the way, which is useful, and vital.

I've learned a lot of math, to the point that I derive a perverse enjoyment from doing integrals in my head, solving infinite sums, diff-eqs, trig trivia, etc. In programming, not counting some astrodynamics code I once wrote, the most complicated math I've ever had to do was simple division. But, I think about things all the time, and that probably saves me a lot more grief in programming than I can estimate.

In other words, math is useful because it teaches one to think. That's why I mentioned proofs before; courses like geometry force you to analyze a problem.

To be fair, math has no monopoly on critical thought. Not even natural science does. Liberal arts courses I took in college stressed it highly. I like math, or really logic, rather, because it's pure.

[PB]: "However, I deem it necessary to get some exposure to things like the difference between your C++ source, the C code equivalent for it, and the machine code for that."

[JH]: Sometimes. For some kinds of code. Not for others. What kind of code do you primarily work on? These would be more appropriate for someone who is working close to the metal. Most developers don't.

I currently program in Java. That's pretty far away from the metal. However, there are myriad little things I have to know about my computer's and software's inner workings in order to write various programs. This is true for any programmer, even those who specialize in, say, networking, or databases, or graphics. Typically one will have to write programs to do all sorts of things which may be mainly in one's expertise, but which border on another. So sometimes I may have to write native methods. Sometimes I may have to link in a DLL. You never know. And if I were relying solely on design patterns out of a book, I wouldn't be able to cope with any but the most menial problems.

[PB]: " or write a security flaw into your code."

[JH]: [You don't need assembler, compilers, or Differential EQ to know that...] I'm sure plenty of security flaws have been written into code by people with CS degrees. What's Microsoft's excuse?

MS is probably having to play nice with legacy apps which were themselves badly written. That forces the OS to be lenient. Then, Nifty Featurz syndrome forces the client apps to take advantage of that leniency.

Anyway, the examples I cited - when to optimize, memory hogging, and so on - are just that: examples. They are examples of the broad, general information a programmer needs to be exposed to in order to do the job well. If computers are like the human body, then programmers are like doctors, possibly specializing in one part, but having to have some knowledge of the rest, because of the chaos inherent in the system.

-- Anonymous, August 28, 2001



I agree with you, Paul.

There are always at least two reasons to learn anything: 1) Because you need to know it 2) Because it trains your intuition and insight

Assembly language is excellent for #2, even if you never have to write a line of it to solve a problem in your entire life. So, for that matter, is LISP. They're a bit like "wax on, wax off" in _The Karate Kid_.

For example, the first time I saw the Palm SDK, I knew instantly which C++ constructs were appropriate for Palm programs and which were dangerous. No effort of thought was involved.

-- Anonymous, August 31, 2001


Moderation questions? read the FAQ