I feel bad for people that think imperative-style programming is the only way things can be done.
C is not the anti-Java. It's Java minus modern features and with more rope to hang yourself with. (Then again, someone actually told me that spending an entire day with Valgrind hunting down a memory leak was fun.)
If you want power, non-Java-ness, and modern features, learn a language like Lisp, Haskell, OCaml, etc. And learn Perl for actually getting things done.
There's nothing wrong with learning and using C. It may not be your favorite flavor, but it's a perfectly valid and reasonable choice.
I didn't say not to use C; there is plenty of good software written in C. Like... everything :)
But, I don't think it's very valuable to know. It doesn't put you in a good position to write correct, maintainable software. There are no tools for that, only for twiddling bits. Therefore, I think C should be relegated to interfacing with UNIX (which you Just Have To Do) and small number-crunching routines. In those cases, there's really nothing to screw up (UNIX interface -- allocate resources, mutate them, deallocate; number crunching, call a function with some arguments). For both of those uses, C has been very successful. Just don't write a big application with it, there are much better tools for that.
I'd actually claim that C is very valuable to know, and while I'm at it, so is assembly. Pretty much all high level languages are written in C (or in a language that is itself written in C). Anyone that doesn't understand enough about how a modern CPU operates and cannot implement a compiler/interpreter for a higher level language in C should not claim to be a hacker.
I've been hearing how obsolete C is ever since high school (1994) yet pieces of successful programs not written in C-family is an order of magnitude less common: everything form web-servers to browsers, OSes and office suites and imaging software - all C. Meanwhile I've never had to install JVM on any of my computers, somehow I never run across a single piece of useful software written in Java (with exception of evaluating Jython and toying with Eclipse&Netbeans at work).
Perhaps it's running on my phone. If so, that's probably why the damn thing feels so anemic compared to Objective-C powered iPhone.
I don't know how C programmers do it, but somehow they just get things done.
Moreover, C remains the only choice of writing the most portable code ever. There isn't a reasonably popular CPU on this planet that doesn't have a C compiler for it, while Java runs only on "java computers".
You seem to think that Java is C's competition. It's not. I think we can all agree that Java is one of the worst programming languages ever created. (The VM is nice though.) Nobody is telling you to use Java or C++. They are telling you to use a dynamic language (Perl/Python/Ruby) or a functional language (Haskell/OCaml/Lisp).
I don't know how C programmers do it, but somehow they just get things done.
Sure, but their programs usually leak memory (ever use Firefox?), and their libraries handle errors by terminating the whole program (see PulseAudio; any error condition immediately calls exit(1)).
There isn't a reasonably popular CPU on this planet that doesn't have a C compiler for it, while Java runs only on "java computers".
I don't optimize my life for solving problems I don't have. Every machine I want my code to run on has Perl, Lisp, Haskell... whatever. If C was the highest-level language I could use, then obviously I'd use it. But it's not, so I don't.
Finally, gcj will compile Java down to machine code; ghc compiles Haskell to native code. So I don't ever see a situation where I will absolutely have to use C for some reason (other than interfacing with C libraries, of course).
That's a poorly written program. You can just as easily System.exit(1) in Java, or to do it a more Javaesque way, throw new Error("im too lazy to do this right").
One (exit) makes the code simpler, but makes the consuming application extremely flaky; the other bloats the code with a weird API where functions modify their arguments:
errorcode_t do_some_work(int arg1, int arg2, int *result)
and forces the client code to check every single error and decide right then and there what to do.It's possible to write code that way, but why would you want to? This is a solved problem; why keep using a square wheel when round ones are available?
(Yes, there is longjmp. Still a lot of work to use that square wheel.)
In the end, don't think I care what programming language you use. It doesn't matter. But I do think that C should be dying off now; it is much less useful than it was 30 years ago.
Of course it does, in fact you just said it yourself - long jumps. Back in late 90s I worked with the firmware for the Point of Sale terminals, PIN pads, etc. It was written in C and its error handling was exception-based. Behind the scenes it was just a handful of long/setjmp wrappers, but it did nevertheless implement semantics of try/catch/etc.
Additionally, "exiting or returning false" are not the only two options, nor they even the most commonly used ones. At least in the projects that I was exposed to. Kernel code (e.g. Linux, BSD) routinely uses int as a return value and it still somehow manages to be both readable and functional without being "bloated" or using "weird API".
Yet another thing to consider is that optional exceptions (such as those in C++) come with a non-negligible performance hit, so it is considered an absolute no-no to use them in a "fast path" parts of the code.
> But I do think that C should be dying off now
But it just doesn't. Bummer :)
David Hanson's book "C Interfaces and Implementations" explains how this is done and provides (very high quality) source code you can use/learn from.
In case you're familiar with gcj, what's the status of that project? Their page hasn't been updating lately, is it being actively maintained? It looks like the most painless way to integrate some Java code I have with Ruby... and I don't wan to bet on a dying horse :)
And as a side note, regarding "Beating the Averages": there are many ways to beat the averages, and beating them ONLY by using a higher level language is like beating them with Aeron chairs: yes, some languages give you productivity boost over others, but I disagree with Paul on magnitude of that effect - in fact I'd say that availability of certain libraries beats any boost provided by language alone.
And, to conclude, here's a little example from real life: a group of programmers I know were working on some nifty AI stuff for automated document processing, and they were doing it in C++, which I disliked. They just discovered a totally different market in the embedded space, which allows them to grow and make money. Thanks for their language of choice (C++), they were able to beat an average Java/Python/Lisp-powered startup that doesn't have access to that segment.
Just saying... :)
C will not be obsolete for a very long time. It is however completely silly to compare it with Java. Completely different and created for different purposes.
You've missed the point. Learning C is not about imperative-style programming. It is about seeing one abstraction level down relative to your favorite programming language.
http://news.ycombinator.com/item?id=235727
Using:
And C is not inferior to Java. They serve different purposes.
Java is #1 in the industry. I'm not saying I like it but your school is just trying to make sure you can easily get a job after school.
But anyway, no arguing about this because it's been beaten to death (and I just woke up from a nap, don't anger me! :P)