Shlomi Fish has written a new essay titled “When C is the Best? (Tool for the Job)”. Its theme is giving several reasons (besides high speed and low memory consumption) why some code should still be written in C.
Shlomi Fish has written a new essay titled “When C is the Best? (Tool for the Job)”. Its theme is giving several reasons (besides high speed and low memory consumption) why some code should still be written in C.
I had to suffer through a 100+-email, week-long battle between C and Fortran on the Computational Chemistry List, and yet this guy doesn’t even mention it?
So, Fortran 95 rules! Go usable arrays and libraries of good numerical routines! C sucks.
There we go.
Its pretty obvious that for low-leveled stuff, integrability, and speed/memory consumption, C is best. All the other reasons are almost specific to Java (and/or mono/.net). So basicly he is reiterating the first well known reasons.
Then he comes and brings an example from his own program and why he would be uncomfterble using anything else. Then he goes and assumes how in every other no-C language it would be slower without even proving his claims. I actualy think that it would of been interesting to see an actual comparison between his C program and another implmentation in some compileable functional language. Well, that is if he would of actually DONE some comparison.
Last, who the heck ever argued with this article? Infact, afaik, in the python community it is a well accepted paradigm to write some time critical code in C and then add it as a module to the rest of your program. Heck there have been quite a few commercial games that had thier game engine written in C and everything else written in python (like implementation of the different units, map scripting, etc…)
What games out of curiosity?
I’ve noticed a lot more coverage of Python lately. Pretty cool.
if I remember correctly, E.V.E. used Python, I might be wrong though.
All the time, we hear repeated that C is portable. This is a misnomer. It gives the wrong impression that identical code will work in the identical way on different architectures. It’s not the PROGRAM that is portable, it’s the LANGUAGE. It was abstracted so that programs could be written using the same language constructs on different machines; so that you as a programmer could immediately get familiar with another environment on another system; because the compiler was easy to port. But not that the compiler, or your program would give identical results.
This to my mind is one of C’s greatest weaknesses – this illusion of portability.
There is a reason for C’s longevity. But it’s more due to the innate conservativeness of the internal computing world, which is paradoxical given the radical changes IT has brought to the external world, than any inherent strengths in C itself.
Geoff Gigg
C code should function the same on different architectures if you mind your types…
It’s only when you get into things that aren’t really within c’s logic you get into trouble: Using ints as pointers, using shift operators, and writing asm sections.
As long as you are on a “c machine” and since Lisp machines seem to have dissappeared (physically speaking), I think you can be pretty sure you’ll be on a “c machine.”
Developers are conservative because they don’t like menial tasks like porting that c code to the latest fad language. It’s not perfection you need in a language, it’s having it still be there in 10 years that you need. (Not to mention all the other important stuff, like not sucking so bad you can’t do anything in it).
I’d say that code written in a portable language is portable…. It sort of “inherits” its portability from the portability of the compiler/runtime/machine. The trouble is that a lot of c code is written with a specific machine in mind, and that machine wasn’t the c machine it was say Intel x86. So they did nice things like assuming sizeof *int == sizeof *(char *). Or assuming that int x = 1; x = x >> 48 would equal x >> 16.
As long as you are on a “c machine” and since Lisp machines seem to have dissappeared (physically speaking), I think you can be pretty sure you’ll be on a “c machine.”
Good Lisp implementations have existed for both Lisp machines and C machines. Good C implementations have never existed for a Lisp machine. What does that say about C’s vaunted portability? You’re basically saying: C is portable as long as you only try to port it to machines designed for C. Duh. Does that mean it is portable, or does that merely mean that it’s so popular that most machines are designed for it?
If I was slightly unclear: the reason a good C implementation never existed for a Lisp machine was because the LispM couldn’t emulate C’s lack of type and memory safety. A good Java or Perl implementation would have been entirely possible on a LispM.
> This to my mind is one of C’s greatest weaknesses – this illusion of portability.
Illusion ? It is the most portable language (of course, by portability we mean source code portability).
Illusion ? It is the most portable language (of course, by portability we mean source code portability).
It’s portable as long as your program only does portable things, like text processing and math.
However, C is a portability nightmare when it comes to things like networking, graphics, and several other things. Additionally, people talk about C like there’s only one version of it. There are in fact several, the most popular of which are K&R, ANSI C 89, ANSI C 99, and GNU C. Yes, GNU C does add its own extensions, and yes programmers do use them. (It is possible to have vendor lock-in in open source, it just isn’t as big of a problem when it happens.)
C is also unportable during the act of compiling and linking. There are several different C compilers that use different command line options. Commonly used C libraries can be placed in any number of locations and given any number of names on people’s computers. That’s why we have the mess that is the GNU autotools.
You must see how Plan9 has archieved the higher portability grade with C.
And you can see why the creators choose to back to C instead of the original language used.
“Most portable language”?!? You know how easy it is to get endianess wrong or to use non-portable libraries in C (yes that’s source compatibility even)? Now compare that to java or c#, or look at all the apps for ms-windows that can’t/won’t be ported to linux/unix and then look at all the java apps that run out of the box on linux, macos/x and windows.
Code portability with C means to the same compiler on a different platform. C Compiler compatibility is a different matter. Each compiler seems to have its own features and quirks which can cause the same C code to behave differently depending on which compiler it was compiled with (assuming it will compile the foreign code at all). And then of course there are platform dependencies in the actual code which are hard to avoid because nothing shields you from the system specific hardware and system specific libraries except programmer discipline.
Java has the advantage of a well specified language (unlike C), well specified run-time environment (unlike C) and well specified APIs (unlike C). The behavior of Java programs on different implementations of the run-time engine and compiled with different versions of the compiler against different implementations of APIs is well defined: anything deviating from the spec may be considered a bug. So you can can compile with the ibm compiler on AIX and test on webshpere, run on the sun jvm on solaris and jboss or use Jrockit to run it on win32 with bea weblogic. If any of this requires code changes you have encountered a bug in either the compiler, run-time environment or the API implementation. The before mentioned application servers are known to have interoperability issues due to different implementations of the huge amount of APIs they support.
Hopefully you’ll understand that source portability is probably pretty damn close to perfect. Most of the portability problems of java programs from one platform to another are caused by api portability problems. For example the oracle implementation of the servlet API is on paper equivalent to the apache tomcat implentation. Indeed many applications that use this API run fine on both, but not all. The reason is that oracle did nog quite get all the semantic details right in their implementation. If you depend on the correct behavior of some of these things, you will encounter problems.
The problem isn’t any different if you compare the SUN linux jvm and the win32 jvm. Indeed most of the java code of the library is identical for both platforms (no problems there). The native code it depends on however is not. A considerable part of the java API has been designed to cover up for native code portability issues (graphics, io, processes & threads). Sometimes it fails to do that properly and that’s when you encounter problems porting java applications from win32 to linux or vice versa.
“C is a disease, and it’s spreading”
I read that line many many years ago, I believe on BYTE magazine.
C is still spreading, and yes, it’s a disease!
I programmed in C for 15+ years, and when I found Python, I will never look back at C again!
C is good for intermediate target language, because of the availability of many ANSI C compilers. So what we’ll see in the following years, is many high level languages creating C/C++ code to create final executables.
So basically C will move down a layer.
I’ve never seen the point of C when compared to Pascal. It seems needlessly complex to me (pointers to arrays of chars instead of strings ? why oh why !)
An array of chars _is_ a string
All languages are similar.
According to Tiobe, which has reasonable metrics (for what can be an unreasonable, difficult to measure, clannish subject), C is currently number 2 in programming language popularity. This after leading recently until Java 5.0 came out, which propelled Java back to the number one spot.
So why is C still in such widespread use? C has a lot of detractors, yet it’s still being used massively to build real world systems and solve real world problems. In spite of some of the difficulities with C programming (it’s mid level, almost lower level, and requires handling bits, pointers and direct memory management), C is still a very effective tool.
Personally, I’m very glad that C remains in widespread use. I hate bloated, slow, memory consuming software, and “managed” languages, like Java and .Net, seem to invite the programmer to make their code as slow and bloated as possible, plus the huge overhead of the virtual machine and garbage collector. Yes, memory is relatively cheap, and yes, CPUs, even cheap ones, are quite fast these days. But when you start using resource hungry programs, it all adds up real quick.
So, Viva C!
That’s not a misfeature. In the hardware, strings ARE arrays of chars. A string is an abstraction and C doesn’t hide that from you.
Most modern pascal compilers let you use a string also as an array of chars. While it’s true that string is an abstraction, the notion of string exists even on hardware implementations – check scas* opcodes on x86. (And yes, I’m aware those aren’t string-specific, on the sense of char array)
The lack of abstraction is C’s problem. You are being tricked into thinking your program is portable when it isn’t. Just because you can compile your C program on any platform doesn’t mean it’ll do the same on every platform:
C doesn’t abstract endianess. It doesn’t abstract a platform’s native memory alignment or pointer size. Strings as null-terminated byte arrays don’t work with 16bit Unicode (which you should expect that one or the other function on a target platform may actually return – like a file name).
From the article:
“ANSI C is portable for every architecture there’s a gcc backend or any other compiler for.”
ANSI C shouldn’t have to rely on GCC for portability, that’s kind of the point of it being ANSI C in the first place. Later, he laments about the aspects that he cannot use when trying to run cross platform compiling against Visual C++ etc.
“With Java you rely on Sun’s whims.”
With Java, you have to rely on Suns Java Compatability Kit and testing. There are several JVMs that appear to meet this standard, otherwise they could not be called “Java”. Not just Sun, but IBM, BEA, HP, Apple, as well as several Java implementations on embedded devices. I acknowledge that there are other platform and higher level issues with portability at the embedded layer that are not part of the the Java language and JVM itself per se.
“Open-source high level languages are better (especially if they can be compiled using gcc or supply a gcc back-end), but nonetheless, C is still more portable than anything written using it.”
Since these are simply C programs, their portability is manifest to the ability of the coders to create portable code. They are no more or no less portable than other C programs that leverage similar facilities exposed by the operating system.
“gcc is a full-featured and robust compiler for ANSI C, and it’s open-source. Sun’s Java distribution has a very problematic license. It’s not distributed as part of most Linux distributions due to this.”
License has nothing to do with portability. I imagine, but do not know, that Auto Lisp in AutoCAD is quite portable, for a contrived example.
“You cannot effectively duplicate a struct containing other structs in Java or in Perl as you can in C. This is due to the fact that in these languages every struct is a reference. You cannot work with interrupts, DMAs, and other hardware elements. It’s much harder to write your own custom fine-grained memory-management routines.”
Hmm, a quick google seems to conflict with those claims, as there seems to be at least some folks doing real time embedded Java.
“Many problem domains call for ANSI C.”
True, but those domains are getting fewer and fewer.
“You can compile a C library and distribute it as is. With Java or Perl one often needs a substantial run-time.”
I can compile a Java library and distribute that alone to anyone who has the Java runtime. There are a gazillion of the libraries available on the internet. Arguably, I’d say there are more (at least in terms of variety and number) of these than for C, particularly higher level frameworks and development runtimes (I don’t know if there is an equivalent C Library to something like, say, Spring for example). In fact, it can be argued that simply the simplicity of distributing and incorporating 3rd party libraries is what has lead to the rapid rise and use of Java in the first place.
Finally, that Java library binary is portable to the PC, Mac, Solaris, AIX, HPUX, Linux, FreeBSD, AS/400, PowerPC, i386, ARM, etc. Whereas a C library binary typically is not.
“There’s no fork() in Java, and not many other UNIX system calls. You need to create bindings for them (which require JNI) or work around them. Perl and other languages, usually don’t have this limitation.
To some extent, this is also true when working on Microsoft Windows, where some of the system calls and APIs are not available in the Java distribution by Sun.”
That’s ok, C has to jump through a lot of hoops to leverage the JVM, so, what’s your point? UNIX programs have to jump through there own circles of Hell to run on Windows, and it’s even worse running Windows programs on UNIX. What’s this have to do with C as a language?
“A C library can be used by Perl code, Python code, Tcl code, Ruby code, to a lesser extent Java code, etc. Code written in a high-level language is mostly usable only in that language.”
Ah HA! The crux of the issue. I see here you don’t consider C a high level language.
“And naturally there’s speed and memory consumption. Often when speed or low memory consumption is the issue, one cannot use a high-level language, because it may have a lot of overhead in both areas or both. Many real-time applications (i.e: applications that should respond to events within a given time) must be written in a low-level language for that reason.”
Umm…no, Real Time Applications must not necessarily be written in a low level language. Real Time has to do with guaranteed dispatch and response, much of which is dependant on the runtime. It all depends on the environment, how fast your processor is, and how much you’re doing in your real time event handlers. Lots of applications that need real time response can be handled with all sorts of runtimes. There are and have been real time systems written in Lisp, for example, and folks are doing that in Java today.
“Other applications like that are applications that simply can never be fast enough: various APIs, virtual machines, simulations, graphics, audio, video and 3-D programs, etc.”
And of the billions of lines of code written each year by developers around the world, less and less and less of it is in that low level space, most of it is in integrating those low level aspects into high level applications. Even modern video games are more and more runtime engines driven and integrated by scripting languages.
Back in the day, we’d write assembly interrupt handlers to be leveraged by C code. Once we could do that, assembly dropped from mainstream to a very nichey area of development. C is suffering the same fate. Now we’re writing C handlers for Java/Python/Ruby code, and most of the folks writing in those languages are not looking back. The domain they develop in rarely need the pain of writing C code to perform the task they need.
Certainly there are exceptions, and certainly C has its place in the world, but that place is getting smaller and smaller every day.
I don’t doubt that if he ported his freecell solver to java, the c version would still be faster. But he doesn’t seem to be very knowledgeable about java in general. He just likes to ring off things and say that they’re automatically slower, just because they’re java.
Functions? Must be slower! For loops? Must be slower!.. I don’t think he realizes what a JIT compiler can do. A final method is easy for a compiler to inline, which would make it roughly equivalent to a macro. And if you’re porting directly from c, it’s obviously very easy to make many of your methods final.
You can’t compile and distribute a c application as is, unless you limit yourself to one architecture and most likely one operating system. Java doesn’t have that restriction. Nor is java limited entirely by sun (yes, it is to a degree). Lots of other companies have made jvms for their architectures and as the free vms get farther, it will get even better.
Imho, with regards to his sample app, the most important factor in determining which language to use is where you want to use the app. If it’s extremely memory constrained, then maybe a jvm is too much. If you’re trying to incorporate it into an existing java app, any performance gains are no where near worth the trouble (and security hole) of going with jni.
I’m not sure why one would use anything but c/c++ for libraries… Simply for ease of portability to other languages, but also as he mentioned minimum nested dependencies (besides, the best high level languages provide their own, fairly complete, libraries; and use of other libraries is probably by advanced programs or niche programs).
IMO, he’s totally wrong on memory consumption. A well written program in anything, including java, can be just fine on memory consumption. And when you compare it to a graphical (obviously, console programs are a different bear) program in c you’ll find similar memory consumption (because the GUI toolkit will suck RAM up). Of course, embedded code is another story; if Sun had its way your embedded code would be Java running on a Java machine .
Speed is also a load as well. For most programs, a loss factor of 100% is not noticeable (your GUI toolkit will suck far more speed than most of your program). The little bit of benchmarking I’ve done indicates that Java is VERY similar to c for arithmetic performance… Python is about 30 times slower (I still prefer the language though).
People discount c as a waste of time too often IMO. It may not be faster or less memory intensive. But in the end, all these quick fix things to fast productivity seem to end up producing buggy code: “Oh, I have a garbage collector so I can write: strcat(z,strcat(v,strcat(x,y))) (a modified strcat that returns the pointer to the ‘