13 ms·
Oh for heavens' sakes. Yet more ignorance. A more realistic view of C: - C is straightforward to compile into fast machine code...on a PDP-11. Its virtual mac
by madhadron 14y ago
Oh for heavens' sakes. Yet more ignorance.
A more realistic view of C:
- C is straightforward to compile into fast machine code...on a PDP-11. Its virtual machine does not match modern architectures very well, and its explicitness about details of its machine mean FORTRAN compilers typically produce faster code. The C virtual machine does not provide an accurate model of why your code is fast on a modern machine. The social necessity of implementing a decent C compiler may have stifled our architecture development (go look at the Burroughs systems, or the Connection Machine, and tell me how well C's virtual machine maps to them).
- C's standard library is a joke. Its shortcomings, particularly around string handling, have been responsible for an appalling fraction of the security holes of the past forty years.
- C's tooling is hardly something to brag about, especially compared to its contemporaries like Smalltalk and Lisp. Most of the debuggers people use with C are command line monstrosities. Compare them to the standard debuggers of, say, Squeak or Allegro Common Lisp.
- Claiming a fast build/debug/run cycle for C is sad. It seems fast because of the failure in this area of C++. Go look at Turbo Pascal if you want to know how to make the build/debug/run cycle fast.
- Claiming that C is callable from anywhere via its standard ABI equates all the world with Unix. Sadly, that's almost true today, though, but maybe it's because of the ubiquity of C rather than the other way around.
So, before writing about the glories of C, please go familiarize yourself with modern FORTRAN, ALGOL 60 and 68, Turbo Pascal's compiler and environment, a good Smalltalk like Squeak or Pharo, and the state of modern pipelines processor architectures.
- niggler 14y agomodern FORTRAN is absolutely horrific, to the extent that F77 is far more popular than more recent flavors (like F90 or F95). It suffers from the same types of problems that the author identifies in C++ and Java. As for standard library, I learned from K&R and have never been surprised by the library (insofar as I can reasonably predict what will happen, given the guidelines). I cannot say that about the C++ standard library (don't get me started on STL) or Java And as for debugging, it took me years to become adept at parsing STL error messages (wading through cruft like basic_string to get to the essence of the error). however I do agree that Borland and turbo pascal are exemplary.
- phillmv 14y agoIt's not about being surprised by the standard library, there are no surprises there, it's about being appalled by the standard library.
- niggler 14y agoThe overarching point in the erlang example is that the bug stemmed from something in erlang itself. C and the standard library are sufficiently documented and tested that there is no ambiguity. (Regarding the natural counterpoint on indeterminate expressions like I++ + ++I, the language specification is also clear on the nature of indeterminate forms)
- niggler 14y agoThe overarching point in the erlang example is that the bug stemmed from something in erlang itself. C and the standard library are sufficiently documented and tested that there is no ambiguity. (Regarding the natural counterpoint on indeterminate expressions like I++ + ++I, the language specification is also clear on the nature of indeterminate forms)
- madhadron 14y agoFORTRAN 77 is far more popular because it took so long for a GNU FORTRAN 9x compiler to appear, and meanwhile there are millions of lines of FORTRAN 77 in enormous libraries. The problem with the standard library is that it is tiny and its basic types are often ill designed. Certainly it's fairly consistent, and so fairly unsurprising, but that's not the argument.
- opk 14y agoIt also has to do with the type of people that program in FORTRAN. They often have backgrounds more grounded in Maths or Physics than computers. I don't think the GNU compiler had much to do with it because people using FORTRAN are more likely to be using something else (we use Solaris Studio where I work).
- hga 14y ago
- rootbear 14y agoCan you elaborate on your first point a bit? How, specifically, does C's machine model not fit current architectures well, aside from multiple cores. How is Fortran's model better?
- jbooth 14y agoC is based on a simplistic view of the computer as a turing machine (or von neumann machine, if you'd prefer). Since the 70s or 80s, CPUs have gotten a lot faster while memory access has only gotten incrementally faster. This means that CPU manufacturers have put an increasingly sophisticated caching system on the CPU die to speed up access to main memory contents. C's simple model allowing pointer arithmetic, aliased pointers that overlap to the same memory, etc, mean that compilers can't produce the optimal cache behavior on the CPU, because they can't reason definitively about when a given region of memory will be accessed based on the variables being accessed (pointer might have been modified or might overlap another one). They also have trouble invoking things like SIMD instructions which do math quickly on vectors. Fortran, with stricter rules about arrays, is more conducive to this.
- gsg 14y agoAliasing is not really an architecture specific concern. Furthermore the vast majority of languages allow free aliasing, differing from C in what things pointers are allowed to point at and not in the number of pointers which may point at them.
- AnIrishDuck 14y agoPointer aliasing can cause additional problems with today's multiple dispatch CPUs, which are nothing like the CPUs of the 80s. Because pointer aliasing ties the compiler's hands, compilers may have trouble reordering code to maximize a single core's instruction level parallelism.
- DigitalJack 14y agoI'm pretty ignorant about this stuff, so please don't think I'm trolling. I'm confused when you speak of a virtual machine with regard to C... can you explain what you mean by this? I had to wikipedia the Burroughs machine. I guess the big deal is that it's a stack machine? It looks very interesting and I plan to read more about it. But I guess I don't understand why that is a hindrance to C. The JVM is a stack machine, isn't it? btw, I haven't read the article yet. It's my habit to check comments first to see if the article was interesting, and seeing your comment made me want to reply for clarification.
- michaelochurch 14y agoI'm also a novice on low-level stuff, but if I had to guess... I'd guess that the virtual machine of C pertains to the addressing and the presentation of memory as a "giant array of bytes". Stack addresses start high and "grow down", heap addresses start low. These addresses need not exist on the machine. For example, two running C processes can have 0x3a4b7e pointing to different places in machine memory (which prevents them from clobbering each other). Please, someone with more knowledge than me, fill me in on where I'm right and wrong.
- minimax 14y agoC pointer aliasing defeats certain compiler optimizations that can be made in other languages, and is frequently brought up in C vs FORTRAN comparisons. I think that's probably what the GP had in mind.
- michaelochurch 14y agoThat makes a lot of sense. Thanks!
- eropple 14y agoC99 includes restricted pointers, but support is a bit spotty. Microsoft's compiler (which is of course really just a C++ compiler) includes it as a nonstandard keyword, too. http://en.wikipedia.org/wiki/Restrict http://en.wikipedia.org/wiki/Restrict
- _yosefk 14y agoThe article argued that C was effective in practice, not that it was better than X in some other sense. Would you prefer to write production code in FORTRAN, ALGOL 60 and 68, Turbo Pascal, or Smalltalk to writing it in C today?
- madhadron 14y agoYes. Though I tend to use PLT Racket these days when the choice of language is not constrained by other factors.
- _yosefk 14y agoSeriously? Actual production code in ALGOL in 2013? If I ever had to deal with that code, I think I'd feel about like you would have if I wrote this comment in Aramaic because I prefer it to English on numerous grounds. I'd very much prefer the extremely unpopular Racket which is at least alive to some degree. I think the author's criteria for "effectiveness" are very much different from yours, hence the different conclusions.
- qznc 14y agoYou might enjoy this link ;) http://cowlark.com/2009-11-15-go/ http://cowlark.com/2009-11-15-go/
- _yosefk 14y agoI've read this comparison between Go and ALGOL-68, and I did enjoy it. Here are quotes from it that explain the difference between "good" and "effective" - exactly the point that I was making here (the article we're discussing claiming that C is effective, not that it is good in whatever sense): "So why am I comparing Go with a language 41 years older? Because Go is not a good language." But... "I'm not suggesting that everyone drop Go and switch to Algol-68. There's a big difference between a good programming language and an effective programming language. Just look at Java. Go has a modern compiler, proper tools, libraries, a development community, and people wanting to use it. Algol-68 has none of these. I could use Go to get proper work done; I probably couldn't in Algol-68. Go is effective in a way that Algol-68 isn't." Note that the author of a parent comment actually claimed to prefer ALGOL-68 to C for writing production code today, in practice.
- stephencanon 14y agoFortran compilers sometimes produce faster code for a limited subdomain of problems because fortran's language semantics are less restrictive: all arrays are assumed to not alias and the compiler has more freedom to reassociate arithmetic and apply other unsafe arithmetic transformations that are disallowed by C's stricter model. C compilers let you specify that you want similarly relaxed semantics via compiler flags and language keywords; however, they also allow the programmer to have stricter behavior when necessary, e.g. allowing one to operate on memory that may actually alias and still get correct behavior.
- sampo 14y agoAlso in Fortran you can get aliasing pointers, if you ask for it (mark the pointed variables or arrays as 'target').
- SeanDav 14y agoMadhadron, you make a lot of claims but provide no detail. Also using terms like "virtual machine" with respect to C is plainly ridiculous and a case of bullshit baffles brains. Turbo Pascal vs C? Really? In its time Turbo Pascal was an amazing piece of software but in the grand scheme of things it is a pimple compared to the whale that is C. Please compare all software written in Turbo Pascal as opposed to C if you have any doubts. The same goes for Smalltalk, Lisp, Algol 60/68. All great products/languages but very niche. Fortran can be faster than C in some areas but again it is a niche language. I could go on a lot more but quite frankly I don't think your post merits much more discussion and is borderline trollish.
- stephencanon 14y agoI believe he actually intends to talk about the C abstract machine, which is a well-defined technical term (and is actually used extensively in the C standard).
- eropple 14y ago> Madhadron, you make a lot of claims but provide no detail. Also using terms like "virtual machine" with respect to C is plainly ridiculous and a case of bullshit baffles brains. C as a very thin virtual machine is a common conception and not an incorrect one--C runs on many systems with noncontiguous memory segments but presents it as a single contiguous space, for example. The idea of C as a virtual machine is much of the basis of LLVM, and to the best of my knowledge I've never worked on a computer where C represented the underlying hardware without significant abstractions. If you're going to accuse somebody of trolling, you should know what you're talking about first.
- smosher 14y agoC as a very thin virtual machine is a common conception and not an incorrect one--C runs on many systems with noncontiguous memory segments but presents it as a single contiguous space, for example. C does no such thing. That is the job of the MMU, and C has nothing to say about it. You're going to have a hard time convincing anyone that a language without a runtime somehow has a VM. That's nonsense.
- woodchuck64 14y ago> So, before writing about the glories of C, please go familiarize yourself with modern FORTRAN, ALGOL 60 and 68, Turbo Pascal's compiler and environment, a good Smalltalk like Squeak or Pharo, and the state of modern pipelines processor architectures. All true, but how are you going to implement a single project using just the best parts of FORTRAN, ALGOL 60, Turbo Pascal and Smalltalk?
- madhadron 14y agoYes, and that's the tragedy of it all...and the real reason everyone uses C. It's not that C is a well designed language appropriate for highly optimized compiling, with wonderful tooling and an elegant standard library that takes care of the difficult or insecure or repetitive tasks. It's that I used to be able to sit down at any Unix machine in the world, shove some code into an editor, call some system libraries, get it to compile, and maybe even step through it in a debugger, and go home at the end of the day, and I could do that because that's what its designers were doing with it, so they made sure that all of it at least functioned at a good enough level to get through the day. Not always anymore, since a lot of Linux distributions no longer install the C compiler by default.
- chipsy 14y agoThe fact that is it "not always anymore" may be a blessing in disguise. The focus of attention in the last decade or so has been all around heavier, VM-centric languages like Java or Ruby, but opportunities for new systems programming technology are coming up more often these days.
- papsosouid 14y agoNone of what you said supports your initial claim that the author is ignorant. In fact, even if we pretend that everything you said is true, none of it contradicts the article, or the authors conclusions. Yes, C has lots of areas where other languages are better. And yet, it is still the most practical language to use because of the combination of things that it does well.
- betterunix 14y ago"it is still the most practical language" Only in extremely limited contexts: low-level code for operating systems that happened to have been written in C. Otherwise, there is a better language for pretty much every use-case of C.
- angersock 14y agoHow might you suggest that I write a good compression, hashing, or encryption library with a lot of bit twiddling? Any good alternatives to C?
- betterunix 14y agoWell, there is always Lisp: http://psg.com/~dlamkins/sl/chapter18.html http://psg.com/~dlamkins/sl/chapter18.html At least SBCL will generate efficient machine language for bit vector manipulations if you tell it the sizes of the vectors (or if it can infer that information). It might just be a matter of opinion, but I would say that Lisp beats the pants off C in terms of programming; you are almost never going to have to keep track of pointers or memory allocations, you have far less undefined behavior to deal with, and it is generally a more expressive language. SBCL and CMUCL also support a non-standard feature that is similar to inline assembly language in C, the VOP system, that allows you to utilize obscure instructions or change how your code will be generated, if there is some reason for doing that (e.g. if your encryption library will use AESNI). Of course, since you said "library," I assume you meant for this to be used in other programs, possibly programs not written in Lisp. Unfortunately, SBCL's support for that is still rough; commercial Lisp compilers may have better support for it. Of course, if you were targeting an OS written in Lisp, things would probably be different -- my view is that C's popularity is mostly a result of how many systems were written in C i.e. how much legacy code there is, and that were it not for that momentum C would be written off as an inexpressive and difficult to work with language.
- muyuu 14y agoI agree with all of that. Basically C is where it is because of a combination of timing and market forces. Market forces are usually underestimated by theoretical computer scientists, but they have a much stronger say in the success of a language than anything else. However I still believe knowing C inside out is an essential skill, and as bad as it is, it's better than most of the alternatives for "low level" code. They usually either try too hard to be different or don't offer enough to substitute C and all the traction, coders, literature and codebase around it. And, as you mentioned, the fact that architectures became historically forced to play nice with C's machine abstraction.
- dspeyer 14y agoIs there any way for software, even in assembly, to make intelligent use of on-cpu ram caches? I thought they were completely abstracted by the hardware.
- ori_b 14y agoYes. You read about how the cache works, and design the code to take that into account. This is usually done through techniques like cache coloring (http://en.wikipedia.org/wiki/Cache_coloring http://en.wikipedia.org/wiki/Cache_coloring), loop tiling (http://en.wikipedia.org/wiki/Loop_tiling http://en.wikipedia.org/wiki/Loop_tiling) and other techniques that depend on the way that the cache works internally. In addition, many CPUs provide prefetch instructions to make sure data is in cache before it's used, or cache-skipping loads and stores to prevent polluting cache with data that's only ever touched once.
- betterunix 14y agoWell, I am not as well-versed in optimization, but there is this: https://en.wikipedia.org/wiki/Cache_timing_attack https://en.wikipedia.org/wiki/Cache_timing_attack If you can exploit the effect that cache has on latency, it is reasonable to assume that you can manipulate it in other ways.
- kelvin0 14y agoThe C 'virtual machine' and its effectiveness is mostly at polarizing otherwise rational individuals. The use of the term 'virtual machine' for C is appropriate in the case of an individual wanting to purposefully show that he has a 'better' handle on the semantics, and that a mere mortal surely would not understand his glorious knowledgs.
- zem 14y ago> The social necessity of implementing a decent C compiler may have stifled our architecture development the idea that specific requirements of c had started driving architecture development blew my mind the first time i came across it. it is still a point that does not get discussed nearly enough at a popular level.
- honr 14y agoI agree. C is outdated and does not represent current machines very well. Nor does it benefit from fruits of years of programming language research. Different layers of cache? Multiple cores? Stream processing? A type-system that is the equivalent of stones and sticks in the age of guns? The joke of "macro"-system that is a miniscule improvement over sed expressions in your Makefile? However, it is here to stay, just like Inch, Foot, and Fahrenheit. Not that the alternatives are worst, just the cost of switching over and training a whole lot of people is back-breaking. Note that most unfortunately, it is being taken over by javascript (false == '0'), which is a far worse language in many aspects.
- exDM69 14y ago> - C is straightforward to compile into fast machine code...on a PDP-11. Its virtual machine does not match modern architectures very well, and its explicitness about details of its machine mean FORTRAN compilers typically produce faster code... Nothing is straightforward to compile in to efficient machine code, and FORTRAN is not at all easier than C. Many compilers (e.g. GCC) use the same back-end for FORTRAN, C and other source languages. FORTRAN's clumsy arrays are a little nicer to the compiler than C's flexible pointers but the "restrict" keyword solves this. > - C's tooling is hardly something to brag about, especially compared to its contemporaries like Smalltalk and Lisp. Most of the debuggers people use with C are command line monstrosities. Yes, C debuggers may be a little clumsy compared to modern source level debuggers. But you can plug gdb in to almost anything, from a regular user space application, a microcontroller chip like Arduino, a kernel image running in QEMU, remotely debug Win32 code on Linux, a live CPU with a debugger dongle, etc. > - Claiming a fast build/debug/run cycle for C is sad. It seems fast because of the failure in this area of C++. Go look at Turbo Pascal if you want to know how to make the build/debug/run cycle fast. What's the point in compiling slow code quickly? Turbo Pascal was not really a good compiler, especially if you'd compare the output to a modern compiler. Also take a look at the progress going on with LLVM/Clang/LLDB, they're working on better debugging and REPL-like environments for C.
- primitur 14y agoDisclaimer: I am a C programmer. C is straightforward to compile on pretty much every single CPU out there. A C compiler is required to certify many very common CPU's before they go into manufacturing, in fact. You cannot go to silicon, in many fabs, unless you have demonstrated the CPU can handle code; most of the code doing all this testing, is in C (lots of Assembly too). C is a front-line language, at the fabrication level. - C's standard library may be sparse, but the diversity of other libraries out there means that you can do your own thing, and have complete control over what gets packed into your final binary image. This is a given, because it is powerful. A scan of /usr/lib,/usr/local/lib, or a search for .so/.dylibs in /Applications, for example, gives me, quite literally, nothing I can't like to with a C compiler. -My fast edit/build/run/debug cycle goes like this: hit the hot-key in my editor, watch output, done. Of course, I also have periods where I must sit and compile a larger collection of libraries; usually at point breaks in my development cycle, but this is all taken care of by my build server, which runs independently of development servers. With C, I've been able to easily scale my build/release/developer binary packaging requirements from "needs to be instant interaction between new code and running tests" to "needs an hour to generate keys and dependencies and be prepared for a solid few years of use". C's build time scales according to the productivity of the developer. -C is highly productive, if you do not trip over key things. Yes, building your own libs package should be a core part of professional C competency; no decent C developer worth their salt, who can't add a few lines of code to a multi-million-line codebase and figure out how to not sit there waiting for the kettle to boil while it builds for testing, should be allowed in any production environment. A proper C Makefile can build entire operating systems-worth of applications; for domain-specific apps, I hardly even notice the build time any more, in between edits and updates. C code is built so fast and integrated so well in repository/testing tools, that in my opinion the system is so well integrated its not relevant. Now, if you need a prepackaged thing, and don't want to hassle with needing to know how to assume an iron grip over the dependencies issue, then of course C is a big hassle. Other languages have their time, and place. You know what else I like about C? Lua. With C and Lua, and a careful selection of optimal libraries, you can build a development environment beyond compare in any other realm. The pure joy of understanding how a table-driven application goes from: work_q = {} and work_q = { {name="empty trash", when=os.now(), msg="The system trash is emptied.."}, {name="copy file", when=os.now()+1000, msg="A backup is being performed..", cmd="tar -cvf /mnt/backups /home/*"}, } .. to a working C-layer on multiple platforms, all functioning exactly the same way, all working from a single binary .. well then, this joy is greater than many other language/systems of development. Welcome to C in the 21st Century.
- shurane 14y agoCould you give a few links to papers on Burroughs systems and the Connection Machine? Is this article on LtU [1] and Daniel Hill's Connection Machine paper and book the sources I ought to look at? Titles to some papers or some comparisons on a mailing list would be awesome to have if you know any off the top of your head. [1] http://lambda-the-ultimate.org/node/87 http://lambda-the-ultimate.org/node/87