in

ASP.NET Weblogs

J e r o e n ' s   w e b l o g

C is (still) everywhere

Jon Galloway posted that he disagrees with one of the points in Joel Spolsky's Career Advice column, specifically this one: Learn C before graduating. Jon goes on to provide six arguments why you shouldn't learn C anymore if you're not familiar with it now and you want to get into software development. I disagree with most of his points, but the most important one (and therefor the one I'll respond to) is this one:

Quote from Joel's article:

I don't care how much you know about continuations and closures and exception handling: if you can't explain why while (*s++ = *t++); copies a string, or if that isn't the most natural thing in the world to you, well, you're programming based on superstition, as far as I'm concerned: a medical doctor who doesn't know basic anatomy, passing out prescriptions based on what the pharma sales babe said would work.

That sounds good on the surface, but does his code sample really tell you how the string is being copied? It's a symbolic representation of a process which is moving memory, sure, but still several levels of abstraction away from shuttling the bits through memory. Why is this the magic level of abstraction that gives you the edge? Why not assembler?

Worse still is that it can make you think that programming is about telling the computer what to do with its registers and memory. Oops, wait, that memory was magically paged from disk without your knowlege. The compiler applied some optimizations behind your back. Your code is running on top of an operating system, which is rationing out the CPU cycles between tens of processes, and yours gets a measly 10% timeslice. And, hey, what CPU are you on? Any sneaky little tricks going on with your 64 bit hyperthreaded chip? What about two years from now, when you run your app on a virtual server on a multicore chip?

Thinking that you're in the pilot's seat because you're handling pointers is silly. Better to understand that you're asking the CPU(s), through multiple levels of abstraction, to copy a string. Do it politely - this ain't no rowboat anymore, it's a durned space ship.

However, All popular spaceships (and a bunch more) for now and the forseeable future are written in C. So while it's absolutely true that the level of abstraction that C teaches you is far from all possible angles you can have with regards to what happens with the software you write, it's currently the one that undoubtedly matters most. Whenever you find a weird quirk in functionality exposed by an API, be it a .NET Framework class library, a Java package, an STL template or an opensource GUI toolkit, chances are that it will be related to the original implementation of that functionality in the operating system. And all of them are written in C. So what's a good language to learn before you graduate?

Comments

 

SBC said:

February 16, 2005 8:48 AM
 

Jon Galloway said:

My spaceship metaphor comes back to haunt me...

I meant that programming's complexity has gone up quite a bit. Many junior programmers have the idea that because they can pass a pointer they're master of the machine. Things aren't always so simple.

But I have to agree with you that just about everything that's a program runs on top of C at some level. You've got me there.

I still don't think that it's the right language for all college students, though. What percent of college students will one day write embeded systems or compilers? Compare that with the number of number of college students who will one day need to write a spreadsheet macro.
February 16, 2005 11:24 AM
 

Steve Hall said:

Four main points about your assertions:

1) Even IF the 3 predominant OS's (Windows, Solaris, and Linux) were completely written in C, this does NOT mean that programmers should have to worry about the language in which the OS was written! The whole purpose of an OS is to provide a platform on top of which the application programmer can use higher abstraction languages and techniques (e.g., RAD languages like VB or Delphi and application frameworks such as MFC, COM libraries, .NET Framework, etc).

E.g., until 20 years ago, most OS's were written in assembler, but most applications were written in FORTRAN or COBOL, NOT assembler. In fact, at most data-centers, application programmers were FORBIDDEN from using assembler, just to prevent the kind of errors that we're now seeing in a lot of C and C++ applications causing security problems, namely buffer overruns. (Using COBOL prevented buffer overruns due to strongly static-typed strings and paranoid RTL, and FORTRAN was never used for heavy string-based applications.) Today, knowledge of C is certainly NOT necessary to be successful to write higher-level-abstraction-based apps.

2) There are still millions of applications consisting of billions of billions of lines of code) written in COBOL. But you (and Joel) are not encouraging programmers to learn COBOL (which has a FAR better track record at NOT having buffer overruns, etc.). Why is that? Pure and simply because COBOL has fallen out of favor and few new applications are being written in it. The same thing has happened to C in the past 10 years with the advent of RAD languages such as VB, Delphi, Java, and C#. Thus, if we're to follow tradition, why should we require programmers to know an out-dated languages like C, when we're not requiring them to know COBOL and FORTRAN ???

3) Your assertion that "all popular spaceships are written in C" is incorrect. Last time I browsed through Solaris or Linux source code, they were mostly in C++. And the Windows NT kernel and subsystems were written mostly in C++ from scratch (versus the Win3.x/Win9x kernel and subsystems, which WERE written in C...and were THROWN OUT for just this reason!). (Even most Windows NT/2K/XP device drivers are now in C++...) I would have agreed with Joel if he had said that learning C++ was important, as a lot of "industrial strength" apps have been written in them and are ISO/ANSI-standardized and cross-platform compatible (for the most part).

4) Joel's example of a pointer-based string-copy statement is pretty low-level, compared to more modern higher ADTs and methods, such as using the new (soon to be) ISO/ANSI-standard "safe" C++ string functions (strcpy_s) along with the C++ string data type. Such low-level code also nicely (unwisely) side-steps (ignores) the underlying string encoding, whether it be pure ASCII, another SBCS, a DBCS, or Unicode. These days, there's absolutely NO NEED for emphasis to be placed on knowing low-level pointer-based string copy techniques, except for embedded applications (and even those are being written in C++ more and more). Rather, there should be an emphasis on producing programs that are easily internationalized due to being based upon the use of Unicode, higher abstract ADTs, and "safe" string functions. Most programs that contain such low-level pointer-based string copies were written presuming ASCII strings and are usually dificult to internationalize.

SB Chatterjee has a good comment on his blog, which I completely agree with. Unfortunately, in the past 10 years many colleges have reduced data structures and algorithms into a single course (instead of what used to be 2 or 3 courses 25-30 years ago), and are teaching it as an upper-class (junior year) topic, instead of a freshmen or sophomore course. I blame the rush to embrace Java in college curriculums for this, as most professors now believe that all any students need to know are the Java ADT classes, and not the underlying concepts. Most recent college grads I've worked with are missing about half of what they should know about both data structures and algorithms, since they've got the attitude "well, if it's not in Java, why do I need to know it?!?!?!" (To make things worse, most colleges are no longer using Knuth's seminal work, "The Art of Computer Programming". Most college gradudates have never even seen the books or heard of them...)

In way too many interviews during the great DotCom Boom a few yeara ago, 20-somethings would ask me very low-level questions to determine if I knew the C RTL inside-out. Of course, upon probing I would find that each of those jobs entailed using C++ or Java, not C. I've since established a policy of never working for a company that has programmers on staff who think that knowing C programming skills are more important than knowing C++/C#/Java programming skills. (I walked out of a few interviews when it becamse obvious they were interviewing for the wrong skill-sets...) Knowing the lingua franca of the day, the application framework of the day, and CS concepts (such as data structures and algorithms) is far more important than knowing low-level details of a language that's fallen out of use...



February 16, 2005 11:24 AM
 

SBC said:


DS-A (ADTs) are still around in Distributed systems and are more needed than before (good books by Schwartz & Tel).

The past 10 years has also introduced a lot of 'band-aid'/chewing-gum programming (eg Perl, Python, etc) which is fine & has its uses but unfortunately, the Perl/Python programmer sees it as an end-all to all problem-solving.

Talking about Knuth -
http://weblogs.asp.net/sbchatterjee/archive/2005/02/05/367674.aspx
:-)
February 16, 2005 12:38 PM
 

Jeroen van den Bos said:

Jon: I'm not saying that you have to know C in case someone wants you to write a compiler or OS. I'm saying that it's good to understand the perspective of whoever wrote the foundations of what you're using. And nearly everything everyone is using at the moment has its foundations in C.

Steve: First of all, I understand that the purpose of an OS is to never have its implementation language/tool matter to anyone, but that's just not the reality of using those systems.

Secondly, I don't recommend learning COBOL because none of the foundations of systems currently in use have their roots in COBOL.

Thirdly, saying that most operating systems are written in C++ and not in C is pointless. C++ is nothing more than an enhancement of C to make it easier to use to implement an object oriented design. You can do that in plain C as well but C++ provides a bucket of syntactic sugar to help you out with that. It doesn't fundamentally change the way the language works or how, at the lowest level, actual functionality is implemented.

I agree that a lot of knowledge that didn't matter 20 years ago but matter a whole lot now (such as handling UNICODE, common STL constructs, etc.) are also of vital importance to learn. But that doesn't mean that it's not useful or in fact very important to learn how all that is implemented deep down.
February 16, 2005 3:47 PM

Leave a Comment

(required)  
(optional)
(required)  
Add