24 ms·
The Unreasonable Effectiveness of C
- lukego 14y agoI can relate to what he's saying. I've also been falling back to C pretty often over the years and finding it pleasant when I arrive there. LuaJIT+C is my latest experimental compromise. My thoughts in more depth at http://blog.lukego.com/blog/2012/09/25/lukes-highly-opinionated-programming-language-roundup-2012/ http://blog.lukego.com/blog/2012/09/25/lukes-highly-opiniona...
- cageface 14y agoC is a fantastic high level language. Nonsense. This sudden C fad is totally baffling to me. C is a great language for low-level work and it does have an attractive minimal elegance but is in absolutely no sense of the term a high level language. A language with next to no standard containers or algorithms, manual memory management, raw pointers, a barely functional string type and minimal standard library and concurrency primitives is just the wrong choice for any application that doesn't need the kind of low-level control C provides. Go ahead and jump on the bandwagon but don't come crying to me when you wind up with an unmaintainable mess riddled with security holes and fiendishly subtle memory errors.
- Cacti 14y ago"A language with next to no standard containers or algorithms, manual memory management, raw pointers, a barely functional string type and minimal standard library and concurrency primitives is just the wrong choice for any application that doesn't need the kind of low-level control C provides." That's what libraries are for, numbnut.
- jsaxton86 14y agoYou can wind up with "an unmaintanable mess riddled with security holes" in any language -- that's not unique to C. Regarding the flaws you have mentioned in C: Its flaws are very very well known, and this is a virtue. All languages and implementations have gotchas and hangups. C is just far more upfront about it. And there are a ton of static and runtime tools to help you deal with the most common and dangerous mistakes. That some of the most heavily used and reliable software in the world is built on C is proof that the flaws are overblown, and easy to detect and fix.
- munin 14y agoSecurity holes you wind up with in a Java or whatever codebase take the form of logic errors allowing for compromise of user information, or SQL injection or command injection. These are bad, they totally compromise data and systems. Security holes in C applications allow for the injection of low-level programs. This is way more annoying, IMO. also the static and runtime tools for C are good, and getting better, but still very far from being a replacement for writing code in a memory-safe language.
- jerven 14y agoAgree and in C you still have all the bugs of the type that you describe for Java or whatever... It just there is a lot of C out there which means we will see it for ever in our systems somewhere. It will get better over time as tools improve the existing C code base.
- MichaelGG 14y agoThat's a misleading statement and I think you know it. In general, you have to go extremely out of your way to end up with a remote code execution exploit with Java or C#. Look at Microsoft's CVEs for 2012. Approximately all of the serious ones would be impossible with a proper type system. This is after all of Microsoft's static analysis tools and code reviews and security focus.
- betterunix 14y ago"You can wind up with "an unmaintanable mess riddled with security holes" in any language" Sure, but it is much, much, much easier to do in C than in other languages. By default you have unchecked array access, fixed width integers, strings terminated by a special character, and tons of exploitable undefined behavior. Writing secure code in C takes substantial effort, substantially more than in other languages.
- theootz 14y agoC is (more specifically) a 3rd generation language, and when I was going through high school I remember it always being on the list of high level languages. It's more recently now I think, that we consider it otherwise...
- seiji 14y agoIn traditional circles (read: not rubymongojs land), C is considered a high level language because you aren't writing assembly or maintaining stacks by hand.
- rayiner 14y agoNot in this decade... I used to do embedded programming and even we considered C/C++ to be somewhere in the middle, with Java being the "high level" language for our management software and C/C++ being the "low level" language for our embedded devices.
- betterunix 14y agoYou are, however, dealing with pointers, memory deallocation, the bit widths of integers, etc. C as a high level language is a questionable idea.
- afandian 14y agoIt's not particularly controversial to say that C is a high-level language. Maybe a bit historical, but it hasn't lost any features since it was new and ultra-high-level for its time.
- timbre 14y agoThe author makes the point more effectively when he writes "It's blown everything else away to the point it's moved the bar and redefined what we think of as a low level language."
- Thrymr 14y ago> C... is in absolutely no sense of the term a high level language. Of course it is. You're not worrying about how many registers your CPU has, or when you swap a register out to memory. All that has been abstracted away for you. The fact that you can access memory locations directly gives you some low-level access, but in a very real sense C is a high-level language. There are higher-level languages with more abstraction, of course. From the article: "It's not as high level as Java or C#, and certainly no where near as high level as Erlang, Python, or Javascript."
- ryeguy 14y agoThe problem is that the "level" of a language is relative to other languages. If C is a high level language, that means you can group it into the same pool as Java, C#, Haskell, Python, and Ruby. Don't you see a bit of a difference here? Unless there is a significant number of actual languages, not concepts, that are below C, it logically has to be called a "low level language" because there really isn't much below it but there are TONS of languages above it. At the very least, it's something like a medium-level language. Grouping it with much higher-abstracted languages is just wrong.
- afandian 14y agoYou can do some very interesting things with function pointers, structs, unions and judicious use of void pointers. I would absolutely group it with Java. Not saying they are very very similar, but you can do similar things. Now grouping Java with Haskell, that doesn't seem like a reasonable grouping. Of course, it's all swings and roundabouts really. You can draw lines anywhere.
- meaty 14y agoThat's why we have valgrind and glib. At the core, a good language shouldn't really have any of these things you say built in - they should be built on top of the language itself.
- rayiner 14y agoHaving strings, containers, etc, not built into the language itself means that you can't practically use them. Libraries will all have their own incarnations, and as a result you get stuck dealing with the lowest common denominator of C arrays.
- oinksoft 14y agohttp://developer.gnome.org/glib/ http://developer.gnome.org/glib/ http://apr.apache.org/ http://apr.apache.org/ Choose one.
- mpyne 14y agoThat's kind of the point. Why do you have to choose? Why isn't it possible with the language and its standard libraries? What happens when you mix APR code with glib-using code?
- matthiasv 14y ago1. Because there is no standard defining that. 2. Because there is no standard defining that. 3. Nothing. Functions in both libraries are prefixed to avoid name clashes.
- mpyne 14y agoThe lack of standard for 1+2 is the complaint here. Prefixing in the libraries is a workaround to make it possible at all for their separate (but similar) basic types to co-exist, but the libraries shouldn't have to define sane basic types for these things. At most they should have to add extended operations. But because they don't, it must be reimplemented in each library that needs them, which adds to code size and semantic overhead. Which might be helpful is for a good basic type library to be created which could be a common dependency for each (perhaps host it on CCAN), but the fact that this would be needed at all is the base complaint.
- mschaef 14y ago> a barely functional string type There's a string type in C? All I see are character arrays and a few (poorly thought out) conventions for using them.
- dionidium 14y agohttp://en.wikipedia.org/wiki/Null-terminated_string http://en.wikipedia.org/wiki/Null-terminated_string
- pjmlp 14y agoForget to place that NULL in the right place and boom!
- runarb 14y agoIt may be cumbersome, but C has string handling: http://en.wikipedia.org/wiki/C_string_handling http://en.wikipedia.org/wiki/C_string_handling
- deelowe 14y agoThis is an article about the standard library. C has no built in string handling. As an example, there are embedded systems that do no have support for string types due to a lack of support for libraries that handle it, yet they are 100% compliant with the C spec.
- tedunangst 14y agoHow you can be 100% compliant with the C spec by omitting strlen is a mystery to me.
- caf 14y agoThe C standard library is specified as part of the language specification document. The language defines two kinds of implementations: "hosted", which must support the entire standard library; and "freestanding", which do not. Those embedded systems that do not support the full standard library are 100% compliant freestanding implementations, but are not compliant hosted implementations.
- michaelochurch 14y agoC is a mid-level language and it dominates that space. The high-level space still doesn't have a winner and it probably won't for some time. It has a lot of excellent languages that are all radically different (Clojure, Haskell, Python, Scala, Erlang) and each is really cool in some ways and very infuriating in others. C, of course, is really cool in some ways and very infuriating in others as well. I've taken up learning C, and my feeling about it is that it's not a "jump in and figure it out" language, in the way that most technologies are, because you're absolutely right. Naive or "cargo cult" C is going to be a disaster from a security, code-quality, and production stability perspective. For most technologies to qualify as safe, sane, and consensual, they have to be secure even when wielded by a programmer who cobbled together incomplete knowledge from a few dozen Internet articles about how to do stuff. Not C. There are "quick adoption" technologies with quick learning curves and "lifer" technologies that are quirky and hard to learn at first but provide long-lived knowledge. C is a lifer language. If you don't treat it as such, you'll faceplant.
- stcredzero 14y ago> C... is in absolutely no sense of the term a high level language. One problem with the term "high level language," is that it was coined many, many decades ago. C is a "high level language" like FORTRAN is one. Remember, when C was invented, programming via punch cards was still a routine activity in many shops. This is why the assertion that, "C is a fantastic high level language," or even that it's a high level language at all is so controversial: It exploits a term which is so old, changing expectations have tectonically shifted the programming field into a place where there is an opportunity for surprise and controversy. There are "high level languages" which are minimal, and those which are not. There are "high level languages" which offer a large amount of abstraction and those which offer less. Right there are two spectra which can be used to classify languages, and C is stuck near the extreme lower left corner. (A minimal language which offers less abstraction.) Then you have languages like Lisp and Smalltalk which are even more minimal, but which offer higher degrees of abstraction. When one says, "high level language," one is talking about a very broad category. Which is why you can do this: http://news.ycombinator.com/item?id=5037315 http://news.ycombinator.com/item?id=5037315
- MichaelGG 14y agoIt's not actually controversial, it's just arguing about the definition. Change the phrasing to "C is fantastic abstraction over the machine, but it's not in the same high level like, say, Erlang" and everyone agrees. The article uses an old standard as a little trick to try to put C in a category it doesn't belong.
- corresation 14y agoC is hardly a fad given that it is the foundation for the vast bulk of software that you interact with everyday (if not the top layer, ones below it). But of course at some point there is a looping back when silver bullets fail to pay off in the longer term.
- venomsnake 14y agoC is not a fad. The sudden love for C is the logical backlash caused by the abuse of lasagna layer upon layer of enterprise oo mvc enabled, xml configurable, orm supporting, osgi friendly huge monolith frameworks. A whole generation of developers have barely known simple and small. And they got tired of big enterprise and are searching for something "not as clumsy or random as a blaster. An elegant weapon, for a more civilized age." . Maybe it is the wrong direction in which they are searching - but I think that C mastery pays off in the long term.
- johncarpinelli 14y agoTotally agree. Learning object oriented frameworks gives me a headache. I learned C back in 1991 for first-year CS classes. Consider all the software built in C: Linux, FreeBSD, Apache, etc. It's the dominant infrastructure of the web. What language will be used to build the first human-level AI? I think it will probably be C, and less than 1 million lines of code.
- Munksgaard 14y ago> What language will be used to build the first human-level AI? I think it will probably be C, and less than 1 million lines of code. I don't think so, but I respect your opinion.
- asveikau 14y agoAs someone who's happy writing C, has written a lot of C at work and at home, I have to say "C fad" sounds a bit weird. What I see talking to people and looking at forums (this one for example) is the exact opposite of a C fad. Frankly I wish it were the other way. I encounter fewer and fewer people with C knowledge, and especially fewer people who say they are happy writing C. New college grads sure as hell don't graduate in large numbers knowing C, even if a good chunk of them can churn out acceptable Java.
- hobbyist 14y agoIsnt high level relative. I was once speaking to a friend who is an electrical engineer. While discussing some dsp stuff with him I explained some asm instructions, and suddenly he says you are going high level :) I am pretty sure if he speaks to some physics/semiconductor guy he probably will get the same answer back from them
- skrebbel 14y agoTo nitpick on a single statement: > C has the fastest development interactivity of any mainstream statically typed language. What? Despite all its shortcomings, Java in a modern IDE effectively has zero build time. The level of interactivity is as fast as that of interpreted languages. I haven't seen anyone manage this with C yet.
- henrik_w 14y agoAgree completely about zero build time! I've been using IntelliJ IDEA for Java development for the last 4 years, and before that I used C and C++ using Emacs for 7 years. I am way more productive in IntelliJ IDEA than I was before. One reason is the instant feedback on syntax errors when I type the code. I don't need to compile to see them, as I used to in C and C++. Another reason is the navigation support you get in an IDE. I've written more about the differences in development environment here: http://henrikwarne.com/2012/06/17/programmer-productivity-emacs-versus-intellij-idea/ http://henrikwarne.com/2012/06/17/programmer-productivity-em...
- alexkus 14y agoThat's the IDE not the language. Java, itself, does not highlight your syntax errors. Nor does C. There are IDEs out there that will do exactly the same thing for you for your C code.
- chadzawistowski 14y agoThe difficulty of writing static analysis software does depend on the language, though. In Visual Studio, for example, intellisense and autocompletion are vastly superior in C# compared to C++. As a matter of interest, which C IDEs are you referring to? I'd like to check them out.
- octopus 14y agoTry Xcode 4.5.x (wich uses Clang as the default C compiler). VS2012 has similar capabilities for C++.
- zvrba 14y agoOh, spare me, high-level language that can't even do arithmetic properly. It's anything but "damn successful as an abstraction over the underlying machine". Case in point: Whenever you're doing signed arithmetic, and it overflows, you're in the land of undefined behaviour. (See here for an example of how this can bite you: http://thiemonagel.de/2010/01/signed-integer-overflow/ http://thiemonagel.de/2010/01/signed-integer-overflow/) Another case in point: type-punning with through pointer casting is also UB. [Going through union is legal though.] I'm pretty sure the author hasn't written a line of ANSI-C compliant code in his life, otherwise he'd never write something like this.
- cookiecaper 14y agoThe author doesn't claim it's perfect or that there's no way to improve on it, but I think he has a very salient point, which is that most of the OO buzzwords and programming fads that come and go in "higher-level languages" simply end up making a bigger mess of things as a project grows. Basically, the author loves C because it is simple, straightforward, and restrictive -- it forces you to write [relatively] simple, straightforward code too, instead of concocting a terrible Frankenstein of custom classes and types intertangled into a grotesque, intractable mass of dependencies and subdependencies. If something is in C, you know it is going to be built from the basics, and in many cases, this simplicity is a life saver as a project matures. There are definitely annoyances and issues, but they are known and can be taken into account with much less hassle than attempting to grok a Java project that requires you to traverse into the basest-level of classes like BusinessObject2013SingletonDispatcherFactoryFactory every time something needs to be debugged or fixed. It doesn't mean you should use C for your Web 2.0 startup, but his point is well taken. I heard someone 'round these parts once acknowledge that the modern equivalent of spaghetti code (i.e., code that intractably descends through hundreds of code paths with gotos, etc.) is OO hell, i.e., code with huge dependency stacks and equally intractable and unjustifiable inheritance models, where you have to descend into all kinds of classes and special cases to make a meaningful change. >I'm pretty sure the author hasn't written a line of ANSI-C compliant code in his life, otherwise he'd never write something like this. Damien Katz is actually fairly accomplished, and it definitely sounds like he's written multiple lines of C to me.
- voidlogic 14y agoIts often worked out well to write the 10% most CPU bound parts of large Java or PHP applications in C. C defiantly has its place. I wonder if this gentlemen has tried Go? If he is a big C fan, Go might be a great choice for the other 90%. Not only is Go a safer version of C with lots of great modern features, it integrates very well with C via cGo. If memory usage and speed are your preeminent concerns, C is certainly a force to be reckoned with: http://benchmarksgame.alioth.debian.org/u64q/which-programs-are-best.php?calc=chart&gcc=on&gpp=on&ghc=on&go=on&sbcl=on&java=on&csharp=on&scala=on&fsharp=on&hipe=on&php=on&erlang=on&python3=on&yarv=on&perl=on&xfullcpu=1&xmem=1&xloc=0&nbody=1&fannkuchredux=1&meteor=1&fasta=1&fastaredux=1&spectralnorm=1&revcomp=1&mandelbrot=1&knucleotide=1®exdna=1&pidigits=1&chameneosredux=1&threadring=1&binarytreesredux=1&binarytrees=1 http://benchmarksgame.alioth.debian.org/u64q/which-programs-...
- galaktor 14y ago"I always have it in the back of my head that I want to make a slightly better C. Just to clean up some of the rough edges and fix some of the more egregious problems." I immediately thought of this: "Go is like a better C, from the guys that didn’t bring you C++" — Ikai Lan [1] And that's what it feels like to me when I use it. [1] http://go-lang.cat-v.org/quotes http://go-lang.cat-v.org/quotes
- dschiptsov 14y agoWhy not just stay with the definition that C is a portable assembler to white OSes and Lisps?)
- stcredzero 14y ago1) Pick a popular language 2) Figure out something controversial to say about it and a justification for that 3) Write it up and post it to reddit, HN, &c 4) Enjoy the hits EDIT: Which is enabled by this - http://news.ycombinator.com/item?id=5037649 http://news.ycombinator.com/item?id=5037649
- manish_gill 14y agoPretty much this. Instead of reading about how awesome C is, I would much rather read a concrete example of a problem which you were facing and how you used C to solve it. Get to learn something in the process.
- borlak 14y agoVery true, but I do end up learning a lot from the HN discussions. I'm a C guy myself, but I try not to be biased. I always tell new programmers to try and not favor any language, as they all have their uses.
- shadowmint 14y agoIt also has a few downsides: - The build system is broken. vs. make. qmake. cmake. autotools. scons. 'modern' makefiles (>_> what does that even mean? Yes, I'm looking at you Google) There's a whole ecosystem of tools out there to solve this. - There are a few rubbish IDEs, most of which support c as a second class candidate. VS has officially abandoned C; xcode grudgingly supports it. The CDT is mediocre. There's little or no support for refactoring or doing other things on large code bases, and the majority of the time the work has to be done manually. - Because the build system is broken, dependency management is hell Got one library that uses scons, another using autoconf, and what to build a local dev instance of a library without installing it into the system path? Goooood luck. This is made even worse by arcane things like rpath, which mean that dynamic libraries only work when they are in specific paths relative to the application binary (I'm looking at you OSX). - Its a terrible collaboration platform. Why? Because the barrier to entry is high. To submit a patch that works and doesn't break other things, doesn't introduce serious security holes or memory leaks is hard. Astonishingly, some successful projects like SDL are actually written in C, but most C projects are not collaboration friendly. - There are no frameworks for doing common high productivity tasks in C, only low level system operations, or vastly complicated frameworks with terrible apis (>_> GTK). I'll just whip up a C REST service that talks to mysql and point nginx at it. Um... yeah. I'm sure there's an easy way to do that. ...perhaps...? How about a quick UI application? We'll just use GTK, that's portable and easy. ...Or, not very easy, and vastly complicated to setup and build. These issues aren't unique to C, but they're certainly issues. I'm not really sure I'd happily wonder around telling people how amazing C is at everything. It's a tool for some jobs; definitely not all.
- makmanalp 14y agoFor the record, I found cmake to be the best. The output is great, the convenience is awesome, the only thing that bugs me is the strange syntax, which is fine because once you set it up it gets out of your way fine.
- JulianK 14y agoThough it doesn't reach all the dark corners that cmake does, I found premake to be much easier to figure out and customize. All the configuration is done in Lua and you can customize the state with a normal programming language as opposed to the crazy cmake arcana you sometimes have to resort to.
- afandian 14y agoThe author's next love affair will be Go, and he won't be back. I see it as a very real successor to C. I have written about 6k lines of Go (on a project that I had previously written in C) and I'm deliriously happy with it (partly because its just more fun to write than C). Granted, you can't write a dylib or kernel, but it sounds like for the author's case it would be a good fit.
- unphased 14y agoI am not sure about this. Every analysis of performance when it comes to Go shows it lagging behind even Java. It is simply not mature enough.
- scott_w 14y ago"But amazingly it's proven much more predictable when we'll hit issues and how to debug and fix them. In the long run, it's more productive." That's nothing to do with C. It's because Damien worked on CouchDB first, and learned a lot from that. If I were to go and rewrite our current system in Java or Scala, I'd also be able to predict where performance, and other, issues would crop up, simply because I've already encountered a number of them before.
- mavelikara 14y ago"It wasn't, it was a race condition bug in core Erlang. We only found the problem via code inspection of Erlang. This is a fundamental problem in any language that abstracts away too much of the computer." Another way to look at this is that all languages which offer poor abstractions force you to write more code, by definition. Up front you will have to write much more code, but when the inevitable bug comes up, you will have the luxury of debugging code you authored. For some individuals and teams, this trade-off is a sensible one.
- scott_w 14y agoBoth Jeff Atwood[1] and Patrick Wyatt[2] have written posts pointing out that the bug is more likely to be in your code than in the platform. There are instances where writing it yourself is the better option, but more often than not you will want to offload that burden onto a library that deals with the details so you can focus on doing what's important to your system/business. [1] http://www.codinghorror.com/blog/2008/03/the-first-rule-of-programming-its-always-your-fault.html http://www.codinghorror.com/blog/2008/03/the-first-rule-of-p... [2] http://www.codeofhonor.com/blog/whose-bug-is-this-anyway http://www.codeofhonor.com/blog/whose-bug-is-this-anyway
- AshleysBrain 14y agoI always get bashed for saying I like C++, but I genuinely don't get how C programmers manage without code like this: std::map<std::string, std::vector<std::string>> foo; One line and you've set up a nontrivial data structure with automatic memory management. No macro horrors (which are a diabolical way of implementing what C++ templates do well). Since you can code like C in C++, I'm not sure why more people don't use C-with-templates as a programming style.
- gcv 14y agoIn the past, when I worked on a C++98 project, I would have disagreed with you for one simple reason: template debugging sucks. gdb did not provide good template information (but may have improved in the last few years, I have not checked it recently). g++ had horrific template error messages. Today, I'm looking at C++11 and using Clang, and I like what I see. Vastly improved compiler error messages, lambdas, very decent type inference, standardized smart pointers, good standard library (and Boost is always an option). I haven't tried heavy-duty debugging yet, but I suspect it still sucks. Overall — I'll probably be using C++ quite a bit more in the future. It is no longer the nasty pile of kludges on top of C which it used to be ten years ago.
- xamuel 14y agoC guy here. I'm assuming you're serious and not being sarcastic... which is a nontrivial assumption, because that line you posted looks like something out of the foul depths of hell. You aren't going to run out of lines any time soon. Who cares whether your data structure definition is 1 line or 5?
- larskinn 14y agoFoul depths of hell? I've never programmed in C or C++, but this seems to me to be a map from strings to vectors of strings. Reads easily. I don't like the :: namespace separator, but what can you do...
- abrichr 14y agobut what can you do... using namespace std; map<string, vector<string>> foo;
- mjs 14y ago"bolted-on support for concurrency"--just what are your options when it comes to concurrency and C?
- RodgerTheGreat 14y agoIf you agree with Hans Boehm, "Threads Cannot be Implemented as a Library": http://www.hpl.hp.com/techreports/2004/HPL-2004-209.pdf http://www.hpl.hp.com/techreports/2004/HPL-2004-209.pdf
- pdw 14y agoThe C11 standard added concurrency primitives to the language.
- deleted 14y ago[deleted]
- fusiongyro 14y ago> I've had intense and torrid love affairs with Java, C++, and Erlang. Oh, but this time it's different, this time it's the real thing?
- mschaef 14y agoI've recently been doing a little bit of C hacking on a small app with a web based interface. I've missed the higher level collections and I/O facilities, but some parts of the experience have been really refreshing. There are mature tools, the softwawre builds in no time at all, and it's been easy to make it fast to both run and startup. Dropping down to C has taken an attitude adjustement, and a willingness to drop certain kinds of features, but it's really been quite refreshing.
- deleted 14y ago[deleted]
- geophile 14y agoC/C++/Java. A programmer's version of Rock/Paper/Scissors. Ignoring pre-history (BASIC, FORTRAN, PDP-11 assembler, Z80 assembler, Pascal), I started out in C, many years ago. I found myself using macros and libraries to provide useful combinations of state and functions. I was reinventing objects and found C++. I was a very happy user of C++ for many years, starting very early on (cfront days). But I was burned by the complexity of the language, and the extremely subtle interaction of features. And I was tired of memory management. I was longing for Java, and then it appeared. And I was happy. As I was learning the language, I was sure I missed something. Every object is in the heap? Really? There is really no way to have one object physically embedded within another? But everything else was so nice, I didn't care. And now I'm writing a couple of system that would like to use many gigabytes of memory, containing millions of objects, some small, some large. The per-object overhead is killing me. GC tuning is a nightmare. I'm implementing suballocation schemes. I'm writing microbenchmarks to compare working with ordinary objects with objects serialized to byte arrays. And since C++ has become a hideous mess, far more complicated than the early version that burned me, I long for C again. So I don't like any language right now.
- BenDaglish 14y agoI have very much the same pre/history, along with years of Perl. Then I discovered Go, and can't recommend it highly enough for exactly the reasons and specific case you state.
- geophile 14y agoI attended a tutorial on Go, and while I liked much of what I heard, the tutorial was so poorly done that I did not leave with a good high-level understanding. I also left with the impression that it is very early days with Go, in the sense that several parts of the language are evolving. (Or maybe I have this impression because the presenter loved diving into ratholes.)
- jasonkostempski 14y agoIf you have an hour go through http://tour.golang.org/#1 http://tour.golang.org/#1. If you're like me and can't enjoy a new language without connecting it to the network and passing some JSON around, check out http://golang.org/doc/articles/wiki/ http://golang.org/doc/articles/wiki/ and take a look at http://golang.org/pkg/encoding/json/#Marshal http://golang.org/pkg/encoding/json/#Marshal (if, also like me, you're picky about field name casing, pay attention to the little bit about `json:"myName"`)
- deleted 14y ago[deleted]
- madhadron 14y agoOh 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.
- 14y ago
- michaelochurch 14y agoI'm a language design buff, so you might be able to guess my biases: FP is good, OO is bad, every language should have higher-order functions, yadda yadda. I finally decided to get a deeper knowledge of C, something I've been saying I "should do" for years. I'm learning it via Zed Shaw's Learn C The Hard Way and I'm very impressed by the language. It does what it does very well. I wouldn't use it for a complex web app, but it's a fine language for things that are small but in which quality (which includes performance) is extremely important. I'm growing to like C a lot, and I think people who don't bother to learn it are short-changing themselves in a major way. That said, there are a lot of great languages out there that are better-suited to high-level projects... so long as the concerns remain high-level.
- hackinthebochs 14y agoInteresting, I would have considered deep knowledge of C a prerequisite to being a language design buff. Did you have experience implementing languages?
- michaelochurch 14y agoNo, most of my experience was with high-level languages like Haskell, Python, and Clojure, with my original interest being more in design than implementation. One of the reasons I'm learning C is to have a better grasp of implementation, and eventually (if needed) be able to competently implement languages. For most of my time, I focused more on user experience (syntax, type system, workflow) and its effects on development culture. Watching language choices make or break companies made me very opinionated. That said, as I get older, I'm finding it harder to call specific languages "good" or "bad". They all have their niches. Enterprise Java is horrible, but that's not James Gosling's fault.
- e12e 14y agoI'd be interested to hear what you think of D.
- michaelochurch 14y ago
- guilloche 14y agoMy humble opinion: Scripting languages like python do have merits. As a 20+ years C++ programmer, I sadly found there seems no scenarios that C++ can play very well. Compared to C, C++ projects are much harder to maintain. Whenever C++ should be used, C is always a better option.
- zmmmmm 14y agoWell, I think people forget history a bit sometimes. For 20 years or so the most common exploit in any system was a buffer overflow, often in string manipulation. I think we're finally getting past that, but C's lack of abstraction over string pointers was a major, major problem and even today if I was writing a secure system I would choose C++ if only to use the std::string class.
- dakimov 14y agoThis is not exactly the C language problem, but the design flaw of the C standard library. Also, there are folks out there that still use unprotected buffers in C++ instead of safe types.
- dakimov 14y agoI believe it depends much more on how the code is written, rather than on C vs C++. Believe me, I am able to write as obfuscated and impossible to maintain code in C as in C++ :) (Hopefully) my code in C++ is easy to maintain because of clear concise architecture, simple interfaces, good naming and the use of complicated things such as template metaprogramming only where it is necessary. I would prefer to maintain a C++ codebase written with a concise architecture and the KISS principle in mind than a C codebase written by unqualified programmers without the clear understanding of the task. Also, if you have have 20+ years of experience, then you have started long before C++ became a stable, developed and seasoned tool. I think the finally good enough state of C++ across the platforms was achieved at least in mid 2000s, although it is still in process with the new standard. Early C++ code was a mess (even Boost still contains tons of ugly workarounds for the early compilers).
- sramsay 14y agoI feel like I'm always trying to make this point to people, and doing so with far less eloquence. The fact that Katz is (a) an experienced and accomplished developer and (b) someone with very non-trivial experience with hot, hip, super-high-level languages should not go unnoticed. He's not some cranky old embedded systems programmer; he's doing thoroughly modern development. Someone the other day said that the great thing about C is that you can get your head around it. When Java, or C++, or Erlang, or Common Lisp, or Haskell programming becomes unbearable, it's almost always because the chain of abstractions overwhelms the person building the system. And to be honest, it's why I'm a little less enthusiastic than most of the people here about Rust.
- MichaelGG 14y agoCan you give me an example of a problem in Haskell, where the abstractions are so complicated you can't get your head around it, but putting it back in C makes it easy enough to deal with? A more plausible explanation is that you wouldn't even attempt a similar design in C because it'd be obviously impossible.
- sramsay 14y agoSo, there are problems that are so complex that they can only be dealt with in Haskell? That would explain why there are so few Haskell programs that anyone actually uses.
- dmpk2k 14y agoAn industrial operating system. In C, you know what you've got: its exact dimensions, location, and lifetime. Since you're not relying on a GC, you can make latency more predictable and with much lower upper bounds. On that topic, I'd rather write crypto code in C too.
- pcwalton 14y agoWhat do you feel is too complex about Rust? The region system is obviously a source of complexity. But I feel as though sacrificing safety at compile time in the name of simplicity just leads to complexity later—you either pay the complexity tax at compile time, or you transfer the complexity of correct memory management to runtime, resulting in sessions sitting in front of gdb or valgrind.
- stiff 14y agoThis should have been an article about having made the wrong language choice for the project to be done, as an attempt of an objective evaluation of C it seems very confused in several places: Faster Build-Run-Debug Cycles [...] C has the fastest development interactivity of any mainstream statically typed language. I could understand someone praising Go for this, because the language designers specifically targeted fast builds for example by making the syntax easy to parse efficiently, hence achieving good build times while keeping the language relatively high level, but C simply does little for the programmer and hence the builds are faster than in Java or Haskell. You could maybe admire the decades of work put into C compilers, but not C the language itself for it. Also, if you criticize high-level languages for being far removed from the computer it would be fair to point out that wider understood "development interactivity" of C compared to something like Smalltalk is rather bad. Consider also that this removal from the computer could be as much an argument against our current computer architecture as it is an argument against high-level programming languages. That we have invested decades into a technology and can't easily switch to a different one doesn't mean we should stay uncritical about its weaknesses. Ubiquitous Debuggers and Useful Crash Dumps I suspect this is a sign of disappointment with Erlang, where debugging seems to be a complete mess, the last time I was doing some development in it I had to fire up some really weird looking debugger and run the program under it just to get something reassembling a stack trace with the filename and line number for the error I got in the program. But you do have lots of debuggers and crash dumps in the JVM for example and I don't think you all that often need to examine the level below the JVM when debugging JVM-based programs. It's somewhat funny to praise C for being convenient in interactions with other C code. Contrast this to OO languages where codebases tend to evolve massive interdependent interfaces of complex types, where the arguments and return types are more complex types and the complexity is fractal, each type is a class defined in terms of methods with arguments and return types or more complex return types. I don't know what this is even supposed to mean. From what I know most large scale C programs end up desperately trying to emulate some of the features of higher-level languages to create more strict module boundaries and prevent implementation details from breaking the library interfaces.
- eriksank 14y agoC is the language someone would create if he just came out of a 5-year long attempt to build an operating system such as multics and wants to do it right this time ;-)
- jws 14y agoClosures? HA! If you are working in C and think you might like closures and a different concurrency model than pthreads, then you should look into clang+libBlocksRuntime+libdispatch. That gives you the blocks(closures) known to OS X and iOS programmers and a pretty spiffy queue based concurrency model. I'm never going back to pthreads. You can't make me. Slightly sadly, I haven't seen a distribution shipping a modern version of libdispatch. There is one in github, but it may or may not have a problem in its read/write support. I use the old version that comes in my distribution.
- pimentel 14y ago"C is a weak, statically typed language" Wouldn't that imply that a variable of one type could be coerced into another type? I would say C is strong typed...
- kscaldef 14y agoC is weakly-typed. You can cast anything to anything else and the compiler won't stop you.
- emeraldd 14y ago> Wouldn't that imply that a variable of one type could be coerced into another type? Yup! It's quite common to cast things from a void * to a more specific one. You do it every time you call malloc.
- dspeyer 14y agoint i; float f = *(float*)&i; I'm not saying you should do this, but you can. Or to use an example the author didn't regret: struct foo { int a; int b; int c; }__attribute__((packed)); void print(foo* f) { int *p = f; int i; for (i=0; i<sizeof(foo)/sizeof(int); i++) { printf("%d,",p[i]); } }
- emeraldd 14y agoHere's one I used in a GC implementation a while back. That last 'uint_8t obj[]' is used to hold the object that was actually allocated. struct meta_obj { meta_obj_type *next; // next object in our list mark_type mark; size_t size; gc_type_def type_def; uint8_t obj[]; // contained object }; Or another (contrived) example: struct obj_type { obj_type_enum type; }; struct string_obj_type { obj_type_enum type; char *c; }; You start with a collection of obj_type pointers and cast them to the appropriate pointer type when you have identified the actual contained struct. Useful if you need to have a heterogeneous list of things.
- martinced 14y agoRegarding the performance of C, it is interesting to note that although hardly anyone does it, Java, for example, can still be very very low-level if you want. You can still allocate a gigantic primitive array (say of Java 32-bits integers) and mess with it, including doing bit-trickery, etc. and that is amazingly fast. When people want the uttermost speed in Java, they dodge objects as much as they can to prevent too much GC'ing. For example that is how the people behind the amazing LMAX disruptor "pattern" (hardly a "pattern" in the OO sense) manage to handle, on a single thread, to process about 12 millions events... Per second. In Java. "Thankfully" Java still allows to create a gigantic primitive array and to directly mess inside that array.
- plg 14y agoIf you tried to use an F1 racecar as your day to day commuter, of course you would complain about it. It would be horrible. Tune the engine every day!? Tire grip changes over TIME? Must watch oil temps so carefully? What a pain in the ass. Also easy to crash. If you tried to use your soccer-mom minivan to participate in F1 races, of course you would complain. I can't tune the engine? I can't tinker with the oil pressure?!? How do I adjust performance for different tracks?! This thing sucks. Also it's slow. These kinds of debates about C and other "higher" level languages are growing tiresome. We live in a wonderful world full of different tools for different purposes. Maybe your grandma doesn't want to worry about details under the hood, and she also doesn't need to race F1 cars, so a minivan suits her just fine. Maybe you value being able to tune your code for maximum speed and you don't mind (or even enjoy) the challenges involved in C code. Good for you. yawn...
- kscaldef 14y agoI take significant issue with this paragraph: When you write something to be fast in C, you know why it's fast, and it doesn't degrade significantly with different compilers or environments the way different VMs will, the way GC settings can radically affect performance and pauses, or the way interaction of one piece of code in an application will totally change the garbage collection profile for the rest. The implementation of malloc & free that your C implementation uses significantly impacts performance (both time and space) just like the choice of GC implementation in other languages. It is not uncommon for memory fragmentation to be a serious problem for large or long-running C programs, and at the point that you have to start worrying about that and working around it, you've broken the abstraction in just the same way that the author complains about for Java, Erlang, Haskell, etc. Also, as others have pointed out, performance can also depend significantly on how well C's machine model maps to the actual machine architecture you're running on.
- sharjeel 14y agoI re-read the article as a satire on C and thoroughly enjoyed it
- darwinGod 14y agoTo folks who think C code is in general a mess of Pointers, macros, and goto's - Go download Postgres codebase,build cscope,open vim.. and try browsing the code. Arguably, one of the most beautiful C-code bases you can get hold off.
- millerm 14y agoI just did. I agree with you.
- vannevar 14y agoWhen you're an expert in C, you tend to forget how much you've really learned. And not just about the language itself, or the available libraries, but about your own coding style. As an experienced programmer, you have habits and intuition that make developing and debugging your code vastly easier than for a novice. The reason that C has given so much ground to a language like Java is not that Java is intrinsically more powerful, but that novice and intermediate programmers can be much more productive with it from the start. Companies don't want to hire a 10-year C veteran at $125/hr to code up their CRUD app, even if one were readily available. They want to be able to hire interchangeable $50/hr Java guys with a bit of experience, who won't have to waste days at a time trying to track down intermittent memory problems or re-writing the wheel because they aren't aware someone wrote a C lib for something Java has built-in.
- cunac 14y agoActually they will ake java 125/hr guy and still be ahead in terms of time/cost
- njharman 14y ago> Faster Build-Run-Debug Cycles Interactive languages blow anything with a Build-Run cycle away. "Faster" doesn't matter. Having a Build cycle is not one of C's advantages. It is a trade off (and a good one, if you care about speed of execution vs speed of development).
- haberman 14y agoC is the language that doesn't force any preconceived notions about how the world should work onto you. Sure, C strings are NULL-terminated by convention, but even that is something you can almost completely ignore if you want to build up your own parallel stack of software that does it differently. It is for this reason that C (and sometimes C++) are what people use when they have a new idea about higher-level programming abstractions. With C, you can be totally free of other people's big ideas (and their associated costs/complications) and invent something new. Anyone who wants you to give up C in favor of their language/framework/VM/runtime is selling their own vision for how the world should work. That's fine and sometimes buying in will save you a lot of hassle. But what they're offering was almost certainly written in C or C++. Essentially their pitch is equivalent to "I have written the last C program you'll ever need." In the early 90s that was Perl. In the late 90s, Java. In the early 2000s, .NET, then Ruby, then fast JavaScript. This history is an oversimplification of course, but the real question is: would you really prefer a history in which we had, at some point, decided that the current VM that was in vogue should become the new replacement for C? That we'd tailor all our hardware to it, and no future VM would be "native" but would have to run on top of a different VM? C is the key to why we have general-purpose computers that can run a wide variety of different languages efficiently, and why programs that need to be particularly efficient can always drop down to lower-level programming to get extra performance.
- kscaldef 14y ago> C is the language that doesn't force any preconceived notions about how the world should work onto you Some preconceived notions forced upon you by C, off the top of my head: - problems should be solved by describing a linear sequence of steps (as opposed to logic/declarative programming) - a variable can have different values at different times in the execution of a program (in contrast to standard mathematical conventions) - a function can return different results when called multiple times with the same arguments (again, in contrast to the standard mathematical meaning of the term) - there is random access storage of information (with constant time access and update)
- haberman 14y ago
- taylodl 14y agoIf you're C code is portable then you've chosen the wrong language. C is best when assembly would have been appropriate but you want to write something in a more maintainable, higher-level language. C shines when you need to optimize for a specific operating platform.
- alexakarpov 14y agoso, with you kind of experience, how often did you prove Greenspun's tenth rule in practice? =)
- robot 14y ago"With C++ you still have to know everything you knew in C, plus a bunch of other ridiculous shit." So true. C++ is designed by someone who is a moderately smart but not a great engineer. There are too many details without much benefit, and you are encouraged to hide things in obfuscated manners, rather than doing straightforward programming.
- shmerl 14y agoI can't agree that C is as high level as C++. C++ templates and many features in C++11 are way higher level abstractions than C.
- alexchamberlain 14y agoTemplates and namespaces are reason enough to use C++; add in STL and you have a massive winner.
- rve 14y agooh so many comments
- linuxhansl 14y agoC is a fine language. So is Java, and so are Python, Perl, Javascript, as well as Lisp and Scheme. Saying C is always effective without further qualification is like saying that high speed racing cars are always effective. You need vans, trucks, bulldozers, etc, etc. Then there is the question of what is really meant by "effectiveness". Is the code execution speed, maintainability, collaboration, compile-execute cycle, extensibility, etc? As always, it depends on what you want to do. In many cases C is the most logical choice. But in other case Java or other languages get the job done more "effectively". Anybody who is limiting him/herself to a single language to "rule them all" is certainly not effective. Edit: Usual spelling mistakes.
- Roybatty 14y agoThe C language is wonderful is because you can look Quake I, II, III, and instantly see the intent. In C++ you can't.
- VMG 14y agoQuake3 is written in C++
- gillianseed 14y agoAlthough Quake 3 contains some C++ code (in splines/ iirc), it's probably 99% pure C code so I don't think it can be labeled as being written in C++ . https://github.com/id-Software/Quake-III-Arena https://github.com/id-Software/Quake-III-Arena
- krizzz 14y agoThank you for writing that. It makes me feel like I'm not completely insane because there are other people who think the same. If you know what you are doing - C is your best option. The problem is that there are thousands of people these days who do not know what they are doing and basically they do not understand how computers and operating systems work. They need very high levels of abstraction which is costly and usually introduces a whole bunch of new problems. Add all those weird frameworks/libraries on top of that and you end up paying 10x more for hardware and get 10x slower product. Though, it's really hard to find a decent and productive C programmer today, so people settle for what's easily available. Another problem is that those "cheaper resources" are defining what programming is these days. I think there is a huge difference between programming and scripting... Call me Dino. BTW, loved the banana example :)