In an article several years ago that struck a bit of a nerve in the industry, Joel Spolsky discussed the phenomenon he called a “JavaSchool”—those university CS degree programs which have removed the C programming language from their curricula and replaced it with Java, or at a minimum have moved C to an advanced, elective course and made Java the students’ introductory programming language. In these JavaSchools, it is possible for a student to obtain a CS degree learning only Java.
This is unfortunate, Spolsky argues, because:
a) Mastery of pointers and recursion are the two CS concepts that separate great software engineers from poor to mediocre software engineers, and, unlike C, Java hides the power and complexity of pointers from the programmer
b) Pointers and recursion help to refine one’s mind in ways that simply referencing 3rd party libraries and calling their functions never does—i.e. the kind of programming typical to Java
Therefore, C programmers have sharper minds and can think in more levels of abstraction. Quoting selections from Joel’s article:
…what I'd like to claim is that Java is not, generally, a hard enough programming language that it can be used to discriminate between great programmers and mediocre programmers.
You used to start out in college with a course in data structures, with linked lists and hash tables and whatnot, with extensive use of pointers. Those courses were often used as weedout courses: they were so hard that anyone that couldn't handle the mental challenge of a CS degree would give up, which was a good thing, because if you thought pointers are hard, wait until you try to prove things about fixed point theory.
The lucky kids of JavaSchools are never going to get weird segfaults trying to implement pointer-based hash tables. They're never going to go stark, raving mad trying to pack things into bits.
But beyond the prima-facie importance of pointers and recursion, their real value is that building big systems requires the kind of mental flexibility you get from learning about them, and the mental aptitude you need to avoid being weeded out of the courses in which they are taught. Pointers and recursion require a certain ability to reason, to think in abstractions, and, most importantly, to view a problem at several levels of abstraction simultaneously. And thus, the ability to understand pointers and recursion is directly correlated with the ability to be a great programmer.
Similar sentiments are expressed by Dr. Robert B.K. Dewar and Dr. Edmond Schonberg in their article Computer Science Education: Where Are the Software Engineers of Tomorrow? Dewar and Schonberg, industry practitioners looking to hire competent programmers, make their point this way:
Because of its popularity in the context of Web applications and the ease with which beginners can produce graphical programs, Java has become the most widely used language in introductory programming courses. We consider this to be a misguided attempt to make programming more fun, perhaps in reaction to the drop in CS enrollments that followed the dot-com bust. What we observed at New York University is that the Java programming courses did not prepare our students for the first course in systems, much less for more advanced ones. Students found it hard to write programs that did not have a graphic interface, had no feeling for the relationship between the source program and what the hardware would actually do, and (most damaging) did not understand the semantics of pointers at all, which made the use of C in systems programming very challenging.
This blog is for BIOS programmers. You know, the Green Berets of the software industry. We can’t afford to be victims of JavaSchools. UEFI is firmly grounded on C pointers and data structures. A UEFI protocol is a structure of function pointers, for goodness sake. So, what are we to do? Well, I just finished a fine book and I recommend it: Understanding and Using C Pointers, by Professor Richard Reese. This book goes into detail on all the ins and outs of C pointers—how they work at their lowest level and all the various ways people make mistakes with pointers.
This is not an introductory book on programming, nor is it even a book that teaches the reader C. It is specifically a book that discusses the use of C pointers in all their many facets. Here is how I would summarize the book’s contents:
- how the C compiler manages memory
- pointer arithmetic
- dynamic memory management
- memory leaks
- assigning NULL to freed pointer
- double free()
- dangling pointers
- passing pointers as arguments to functions
- returning pointers from functions
- function pointers
- pointers and arrays
- pointers and strings
- string literal pool
- passing strings as arguments
- returning strings from functions
- pointers and structures
- data structures with pointers
- security issues arising from improper use of pointers
- aliasing pointers
- pointers and threads
- object-oriented programming in C with pointers
Professors who teach C programming know that everything begins fine at the beginning of the semester. The students are absorbing the material and writing simple programs that work well. Then, pointers get introduced and the wheels fall off the wagon. Some students never recover. This book is one professor’s attempt to remedy the situation.
If you are already an accomplished C developer with 10+ years of experience, then you’re probably not going to learn much new with this book. But if you found my summary of the book (above) interesting, and/or you’re in the intermediate state between solid command of C fundamentals but not yet becoming a C wizard, I think you will find this book helpful. The one thing I wish the book did have was programming exercises. The book is text and examples, but no exercises. Maybe in a second edition?
I’d love to hear your comments if you’ve read this book, or have an opinion on the JavaSchool issue. Don’t be a JavaSchool loser! Checkout this book today!