11 ms·
Linus vs C++, again
- j_baker 16y agoI actually rather like this quote: Anybody can say "yes". Somebody needs to say "no"
- dman 16y agoI actually liked his point about context very much. In fast moving projects changes are visualised in terms of diffs, and the closer the code is to what will be executed, the more chances that obvious flaws will be caught. btw related discussion in an older thread - http://news.ycombinator.com/item?id=1318489 http://news.ycombinator.com/item?id=1318489
- rpledge 16y agoLinus has a touch of what I think makes Steve Jobs great: the ability to say no and stick by those convictions. No argument from me that Linux is wildly successful and one of the most important tech developments in the last 10 years. However, I always cringe when I read some of his comments that seem to reject any element of forward progress. While C++ certainly has its share of issues, Linux will never evolve if the programming paradigm stays in the 60s. My gut feel is there is a lot of opportunity to do better over the next ten years.
- desponsible 16y ago> Linux will never evolve Do you terribly mind elaborating on this rather bold statement?
- deleted 16y ago[deleted]
- silentbicycle 16y agoRob Pike already has: http://herpolhode.com/rob/utah2000.pdf http://herpolhode.com/rob/utah2000.pdf
- rpledge 16y agoGreat way to edit my comment, what I actually said was: > Linux will never evolve if the programming paradigm stays in the 60s C is a great language, but I firmly believe that OOP creates more maintainable code that is more robust. Sure, a simple C program is easy to understand, but the kernel isn't an easy program. Don't get me wrong, C++ has major downsides, but C isn't a magic bullet.
- nitrogen 16y agoThe kernel does use object-oriented paradigms.
- sophacles 16y agoThe kernel is also shockingly simple. Sure there are some tricky bits, but writing kernel code is very straight-forward. In fact every time I've written kernel code it has always been a "it can't really be this simple" type moment -- but some of that code is still running production machines today so... it must have been. NOTE: this is not me bragging, it's me suggesting the mystique is a bit undeserved.
- nitrogen 16y agoI definitely agree. It is the simplicity of the POSIX userspace APIs and the Linux kernel internals that make me enjoy Linux so much. I still think there is some art to writing simple, efficient code, though. Most system-level code looks quite simple when it's done, but it may have taken several iterations to get it fast, clean, and small enough (particularly on embedded devices -- I once had to find 200 spare bytes to fit a bug fix in a 256KB firmware by hand optimizing various ancient parts of the code base).
- MarkPNeyer 16y agoC as a context free language? Bullshit. How many global variables are there? How many functions with ridiculous names like htons? Edit: I realize that "context free language" was a poor choice of words; i meant it in the sense that linus did - his claim that you can 'look at a piece of code and understand what it does' is laughable in the face of accepted c programming styles.
- stcredzero 16y agoIronically, this is an overloaded usage to the words "Context Free Language." (Whether you intended it or not.)
- j_baker 16y agoI'm not really sure you understand what a context-free language[1] is. I suppose global variables can be seen as being context-sensitive, but functions with weird names definitely don't qualify a language as context-sensitive. [1] http://en.wikipedia.org/wiki/Context-free_grammar http://en.wikipedia.org/wiki/Context-free_grammar
- koenigdavidmj 16y agoNo, what he means is that something like foo * bar; Can mean two different things. If foo is a defined type (typedef int foo, for example) then that declares a variable bar of type foo. If it is not, then we're multiplying variables foo and bar.
- j_baker 16y agoYes, that is context-sensitive, but it's pretty tame. First of all, if I look at that, I can tell it's probably a pointer. After all, it doesn't make much sense to multiply two variables and then not do anything with the result, does it? On the other hand, it can mean a variety of things in C++. Are we multiplying numbers? Is foo or bar an instance of a class that has the * operator overridden? Is there a global overload of the * operator? Are we declaring a pointer?
- huherto 16y agoIt is funny how a very simple and innocent looking question by "newbie" started a big discussion. It is like watching somebody drop a candle in a bed. Can you use C++ in Linux kernel? In windows kernel you can, with some restrictions.
- viraptor 16y agoWhat are the chances he's just a troll? A simple google search would show many similar debates. I'm pretty sure you could cause the same in a month or two, by asking "I know there are projects using different languages to create kernel modules - even crazy ones like haskell. Can I use C++ in the kernel?"
- steveklabnik 16y agoNewbies? Not Google before asking a question on a newsgroup? What's the world coming to? It's gotten to the point now that when I can't find a question asked previously, I start getting nervous, and 3/4ths of my initial post to a group starts off by explaining how I really did Google, honest! This is what I tried, and I still couldn't find anything, so if it's been asked before, please just point me to the right place, sorry!
- Daramarak 16y agoYes, but it is good to have such debates. It allows the Linux community continuously to reassess its choice of a c-only environment. Such introspection is necessary, and when people are ready to move on, I think the community will.
- yonilevy 16y agoThere's not much "Linus vs C++" in there (except for several random bashes with nothing to back them up). It's mostly Linus sharing his POV as the maintainer of the kernel as to why C++ would be harder to work with in a project that has many contributors due to code being more context dependent (i.e member functions, function overloading).
- stcredzero 16y agoThat is a huge problem for communication. It immediately makes it much harder to describe things, because you have to give a much bigger context. It's one big reason why I detest things like overloading - not only can you not grep for things, but it makes it much harder to see what a snippet of code really does. I think this is a limitation of our using flat text to program in. So long as our primary means of communication is linear speech and flat text, we will have this communications overhead. Collaborative systems that display the context to all concerned can overcome this. In fact, this is already happening! (Exercise for reader.)
- JustinSeriously 16y agoI came here to quote that same piece, but for a different purpose. I am in complete agreement with him. I think writing grep-friendly code is a good thing. I do my best to make all my Perl code easily grepped, it just makes debugging infinitely easier.
- protomyth 16y agoWould a search tool other than grep change how you write code?
- JustinSeriously 16y agoProbably not. I just said "grep" because it's such a basic standard, I really meant "easily searchable from a command line."
- stcredzero 16y agoWhat about a syntax-aware search? If this were as responsive as grep, wouldn't that be better? I think so. I use one in Smalltalk all the time.
- cageface 16y agoAs I get older and grumpier I tend to appreciate Linus' point of view more and more. It's easy to get swept up by arguments of the expressiveness of a language, particularly in small examples. However, I think in the long run it's better to have very explicit code. The less jumping around and inference I have to do to figure out what a block of code does the more likely it is that I understand it and that I can quickly verify that it does what it needs to do. If that makes code a little more verbose I think it's usually still worth it.
- j_baker 16y agoAs with most things, there are tradeoffs. If the expressive code was written with a good level of abstraction, it should be pretty straightforward to figure out what it does. Of course, it means that you need to understand those abstractions before you understand the code, and you might have to do more jumping around to figure them out. But in the long run, it makes it much easier to remind yourself how certain features work. On the other hand, you can write obtuse and difficult to understand code in expressive and non-expressive languages. I suppose a point could be made that bad code in say Haskell or Lisp might be worse than bad code in Java.
- cageface 16y agoIf the expressive code was written with a good level of abstraction, it should be pretty straightforward to figure out what it does. Abstractions are necessary, of course, but they also leak. Good judgment in these issues is one of the hallmarks of an experienced programmer. I'm just finding in my own code that I'm gravitating towards less abstraction, not more. Clojure in it's current incarnation is a great example of this problem, IMO. It provides a very expressive and highly abstract interface to the JVM and java libraries, but once you hit a stack trace the abstraction comes tumbling down and you have to start picking through the mixed java/clojure stack trace to figure out what went wrong. Throw macros into the mix and things get even hairier. I've found that in some cases it's better to just bang out vanilla java. Sure it takes more LOC to get the same things done, but the result is often dead-easy to understand and debug. Like everything else in engineering though, it depends a lot on exactly what you're trying to build.
- desponsible 16y ago> One of the absolute worst features of C++ is how it makes a lot of things so context-dependent - which just means that when you look at the code, a local view simply seldom gives enough context to know what is going on. Good point. Very good point. Having spent few years developing for the Linux kernel I can say that the most cluttered code I dealt with was the network stack. And exactly because it was done in C++-ish way. It makes an extensive use of tables of function pointers, which is basically an analog of a C++ virtual table. A socket depending on its type would get a pointer to a different table and that table would define the actual flow, say, of the recv() call in the kernel. The concept is very elegant, and it translates into a more compact code, but it also makes tracing the code by hand hard. So, yeah, Linus got a point there :)
- jrockway 16y agoActually, you refute his point. If they were actual classes instead of ad-hoc vtables, the flow would be clear.
- bnoordhuis 16y agoNo, he didn't. A call to ipv4_recv() is obvious, a call to impl->recv() less so.
- sliverstorm 16y agoThis leaves me with a burning curiosity. Linus, if you could change the Linux kernel to another language, would you? In a perfect world (i.e. migration concerns and such aside), if you were changing the Linux kernel to another language, what language would you choose? If you feel C is still the #1 choice, what would the #2 choice be?
- huherto 16y agoI would like to hear Linus opinion on Go.
- portlandFan12 16y agoLinus gives his opinion on Go later the referenced thread: http://www.realworldtech.com/forums/index.cfm?action=detail&id=110624&threadid=110549&roomid=2 http://www.realworldtech.com/forums/index.cfm?action=detail&... > Hey, I think Go picked a few good and important things to look at, but I think they called it "experimental" for a reason. I think it looks like they made a lot of reasonable choices. > But introducing a new language? It's hard. Give it a couple of decades, and see where it is then.
- mkramlich 16y agoOr D. I had thought D was designed to be, among other things, a reasonable next-generation replacement for projects that would otherwise use something like C.
- steveklabnik 16y agoYep. I'm actually contributing a bit to an exokernel written in it.
- deleted 16y ago[deleted]
- ananthrk 16y agoSomewhere down the list, someone asks about Go Hey, I think Go picked a few good and important things to look at, but I think they called it "experimental" for a reason. I think it looks like they made a lot of reasonable choices. But introducing a new language? It's hard. Give it a couple of decades, and see where it is then. Linus (http://www.realworldtech.com/forums/index.cfm?action=detail&id=110624&threadid=110549&roomid=2 http://www.realworldtech.com/forums/index.cfm?action=detail&...)
- johnrob 16y agoI think Linus is making the right call here. At a 10,000 foot view, the real argument is about style. The style of C happens to be one that lends itself to easier groking of code amongst hundreds of developers (as he illustrated well). Sure, C++ may be a more modern tool with some more powerful features, but using it may not be the best thing organizationally. This kind of thinking is refreshing and is seemingly rare in classrooms. There, you mostly learn 'what to use' and not 'how to determine what you need'. Just as I'd expect, over design is the most consistent issue I come across in co-workers' code. 'Write code to be read' is a metric that seems to have gone out of style. Code that does X-Z-Y should, in my opinion, look like code that does X-Y-Z. Otherwise the reader has to invest time and energy figuring out the design. There had better be a good reason to justify a hard-to-grok design, because it will continue to be a drain for the life of the project.
- protomyth 16y agoI know no tool would solve every problem, but I can't help but wondering if someone developed and IDE that truly got C++ would that allow C++ to be used by more projects. Seeing grep referenced for code searches reminds me that grep has no knowledge of the context of anything in a searched file. It almost seems like C is the only choice if you can't go beyond context-less tools. //a grep specifically for C++ code - hum
- beza1e1 16y agoOne problem with C++: It is hard to build tools for, because parsing it is nearly impossible. Clang and GCC plugins may change this situation, though.
- rpledge 16y agoAre you implying C++ isn't widely used? I'm sure that isn't what you truly believe...
- protomyth 16y agooh no, I know it is widely used (Visual C++ and the ilk). I was more thinking in these huge C open source projects.
- Daniel_Newby 16y agoThis rings hollow. It's like saying "C++ feature X can go horribly wrong when used without adult supervision, therefore C++ is unusable." This is especially silly coming from someone who favors a professional stunt language like C. If somebody uses too much overloading, reject their patch. If somebody makes a template tarpit, abuses operator(), or gets too fancy with operator overloading, send it back to 'em. Context dependency bad? I like having the superclass define a contract so that you can ignore which subclass is being used. And C++ even rubs your nose in the name of the superclass, to avoid duck typing (which Python/Ruby use with near impunity anyway). Polymorphism also gives you what amounts to functional programming without touching C's awful function pointer syntax. I suspect a lot of Linux code uses baroque switch/case or "if" statements just to avoid the pain of function pointers. Edited.
- jafl5272 16y agoI'll deal with this in order of decreasing insanity: 1) Polymorphism is NOT functional programming. Using function pointers, which you seem to detest, is one aspect of functional programming. If you've only used C++, then you don't know what you're missing from languages like Lisp or JavaScript. (I should know. I was once like that.) 2) I seriously doubt the Linux kernel avoids function pointers. Ever heard of dispatch tables? Good C hackers know that smarter data structures make for simpler code. 3) Any feature that can go horribly wrong will go horribly wrong when you have a large project with lots of contributors. Everybody who successfully uses C++ on a large project has a huge "coding standards" document to keep the project from crashing and burning. I know Google has it, and I've seen others, too. Even I have it for my own personal C++ projects! 4) What Linus meant by "context dependency" is that you have to know the object's type in order to know what the function will do and you even have to figure out which version of the function will be called, based on the arguments. This is hell when you get a small patch in the middle of a larger function.
- Daniel_Newby 16y ago1) You can pass around worker objects and apply them to things. 2) Declaring, initializing, and using dispatch tables requires a boat load of syntax, or GTK+ style macro hell. To the best of my recollection, Linux only goes to the trouble for a few large, complex subsystems, like networking and filesystems. Many other areas could probably benefit from it but cannot afford the price. 3) True. But once you climb the hill, you get to offload a lot of crap onto the compiler. Forever. 4) Linus already applies his +18 Axe of Correction to large functions and nesting depth. Anybody who reviews patches without a color-highlighting code browser deserves what they get.
- mkramlich 16y agoRegarding C and C++ I sometimes think of them like this: If you want a language that's like C but better, tough, just use C. If you want a language that is better than C, do not use C++.
- snorkel 16y agoEven if the Linux kernel were rewritten in Erlang and it won't change the fact the vast majority of *NIX systems level code is entrenched in C. The most popular LAMP stack ingredients are also written in C. Face it; it's a good language.
- eru 16y agoNon sequitur?
- jheriko 16y ago"And the best way to avoid communication is to have some "culture" - which is just another way to say "collection of rules that don't even need to be written down/spoken, since people are aware of it". Sure, we obviously have a lot of documentation about how things are supposed to be done, but exactly as with any regular human culture, documentation is kind of secondary." This is so true - I have zero problems with context sensitivity and difficulty reading C++ if its all consistently done according to my prefered standards (which I mostly inherited from an especially well managed employer), avoiding the "bad practices" that introduce these problems like namespaces and such. Yet if I dive into some poorly organised and written code I can easily spend a whole day debugging a trivial problem - simply because the time is wasted trying to understand what is happening. The sad truth is that the latter case is more common - its not C++'s fault though (although it could just /not/ try and provide every imaginable feature) - its more bad management than anything else. Though I can't help but wonder if that is just unavoidable for inherently difficult to manage projects like this...
- ecaradec 16y agoWow, Linus is getting older : he didn't flame the poor guy down. I feel a bit concern that Linus don't write code anymore but still decide on how code is written, etc... Happily, he has some experience. Linus has good reasons, nobody is going to rewrite linux in C++ anyway, this has been debated to death. Why I am still loosing my time commenting on this ?
- d0m 16y agoI've seen some pretty clean C++ code and some ugly C code. I think what's important is how a programmer use a language rather than what language he uses. I mean, if someone enjoy writing clever one liners, he/she will probably do it in all languages, might it be Perl or C. However, the important point here is that C does a good job and the programmers are used to it and like it. THEY, people that submit patches, like it, period.
- jongraehl 16y agoBecause the Linux kernel is so important, and so difficult to replace, people will put up with whatever language inconveniences they must in order to get their contribution accepted. Therefore, I don't see Linus' choice as having any larger significance. I already know that C++ is a vastly superior language to C for small to medium scale programs where computational time+space efficiency is paramount.
- _0ffh 16y agoCome again, please? All computational time+space efficiency of C++ comes from the "C", not the "++" part!
- jongraehl 16y agoYou misunderstand - I'm just qualifying the experience I'm speaking from. I've used both languages, but only when time and space efficiency can't be sacrificed. I've never worked on a large program in either. Under those conditions, I know from experience that C++ is better. It allows me to abstract safely (I benefit from some compile time type-checking) with little or no run-time cost.
- Daramarak 16y agoExcuse me but C++ is only vastly superior of C if you are a C++ programmer and do not know C. I am a C++ programmer, and I would never make such a claim. And for time and space efficiency? That doesn't make sense.
- jongraehl 16y agoI know C and C++ very well. I don't use either language unless I need to be as efficient as possible.
- albertzeyer 16y agoMany of the arguments he gave are mostly just based on the fact that there aren't that much powerful tools around which can do what he requests (and what of course is something you want to have). Like grepping for all usages of some function. Or getting some code snippet in a way that it comes with all necessary context. Or whatever. Though, with recent development (particularly on clang), these things may become much more easier. Of course, you will not be able to do magic things (like checking at what places what particular virtual function implementation is called exactly) but it will be trivial to check for example all calls on std::string::size etc. In the same way, you could also implement some small helper tool for sharing code snippets which will add some meta information about the context. So that when you share some code like 'a += "foo";' it will contain the meta information that a is an std::string. LLVM/clang is anyway also kind of a disprove to his arguments about maintainability. I would say that one reason that working on/with the LLVM/clang code is so much nicer compared to working on/with the GCC code is because it is written in C++.
- acqq 16y agoYou're wrong. I've actually had to maintain the big C++ projects. That have Zillion of classes, fully different, but each one has more Read(), Write() functions. Some are virtual, some are not. Some have two parameters, some have three, some four. And they even do fully different stuff! Which Read() will be called depends on anything and everything. I claim you just can't figure out what some piece of code does in any other way than by actually single-stepping through the debug build. Any time the debug build pieces of code don't reflect the source, you're fully lost. Note that Linus usage scenario is "read the chunk of code outside of the whole source base" and you argumenting "if I use some hypotetical very clever tool the tool would maybe able to show me what some line in the chunk of code actually does." I've actually made some "very clever tools" since some twenty years ago. And I wouldn't want to have to use them on the really big projects.
- albertzeyer 16y agoWhat exactly is your point? You have the same problem if you use virtual function tables in C.
- kqr2 16y agoOriginal Linus rant on C++: http://lwn.net/Articles/249460/ http://lwn.net/Articles/249460/
- xpaulbettsx 16y agoLet's put it this way without any subjectivity: every production kernel that you folks use every day is written in C. NT is, Solaris is, Darwin is, and Linux is. Not one production-level kernel that is in wide use as a general-purpose operating system uses C++. I don't believe that to be a coincidence. (Nitpicker's corner: Darwin's device tree subsystem is written in Embedded C++, an extremely cut-down version of C++ that's more like "C with classes" than C++).
- shin_lao 16y agoThat's perhaps because all these kernels were written before C++ exists? The first C++ standard is from 1998, and stable STL/C++ support is even more recent. FYI : in NT many device drivers are written in C++
- shin_lao 16y agoThere are so many large scale C++ projects that prove Linus wrong every day. One of them, you probably use it every day. hint: it's a search engine. Whatever language you use, you need rigor and diligence. You need to manage the project and follow up on developers. You need to agree on a subset of the language, that will become your local dialect. I'm pretty sure that Linus doesn't accept "any C source code". C++ has got more features than C. That's neither intrinsically good or bad. I could argue about the merits of templates and what they enable you to do, and someone would tell me "it's hard to understand". Well, any language you don't know is "hard to understand". C++ is not "C with classes" anymore. It's something else. It's a different language. In the end what really matters is the quality of the developers and the quality of your process. The language is just how you implement your concepts.
- kensan 16y agoI would inject into your list of what really matters something Linus said: communication. Having each member of the team (1000 contributors to the kernel by Linus's estimation) in a different corner of the world is a huge consideration.
- eps 16y agoMain problem with C++ is non-technical. Based on some experience interviewing a dozen people a week for several months, C++ programmers tend to routinely overestimate their proficiency with the language, while C programers tend to have the opposite self-assessment. To put it differently - on average C++ devs are cocky, eveyone is a guru and C devs are basically modest.
- shin_lao 16y agoI agree with you. I often interview people who consider themselves "C++ expert" but struggle to use the STL's algorithms correctly.
- dan00 16y agoIt's right, that in theory I can't know what a C++ function call means. But that's also the case for C. In C I can assign a function pointer to a variable. When the function is called through the variable, than I don't know which function is called. Almost never the language is the problem, but their usage. There's always context, and the quantity depends mostly on the complexity of the software. And regardless which language you use, you have to define a convention for the usage of the language, also in C.
- shoover 16y agoInteresting point about function pointers. Maybe Linus is saying (in many more words) to use virtual dispatch only in appropriate places but not as a basis for an entire language? He would be in disagreement with every language designer who has added some kind of first class dispatch or pluggable modules. Not that such disagreement would be surprising, but that seems to be what he's saying. He suggested looking to other languages for GC and concurrency support, but in that thread I didn't see any desire for dispatch or modularity beyond what C offers.
- pmjordan 16y agoIt makes a lot of sense if you think about it as optimising code readability for the case of seeing it through the lens of diff -pu -c 3 which is basically what Linus does all day. This also implies that the argument has little meaning in the context of projects that aren't comparable in scale (both code size and contributor pool size).
- henry_flower 16y agoIs that Linus post originally comes from some mail list? What is the name of the list? (google gives me only links to realworldtech, which is weird)
- Symmetry 16y agoThe post is from the forums attached to the realworldtech website.
- known 16y agoIs there anything in C++ that I couldn't do in C from Application pov?
- matthavener 16y agoCould Linux explain spinlock.h then? Depending on which type you give to the PICK_OP macro, it performs a different operation. Its basically a C template. Seems a bit weird to complain about type context specific code and then use it in one of the most important parts of the kernel.. Here's the code: #define TYPE_EQUAL(lock, type) \ __builtin_types_compatible_p(typeof(lock), type ) #define PICK_OP(op, lock) \ do { \ if (TYPE_EQUAL((lock), raw_spinlock_t)) \ __spin##op((raw_spinlock_t )(lock)); \ else if (TYPE_EQUAL(lock, spinlock_t)) \ _spin##op((spinlock_t *)(lock)); \ else __bad_spinlock_type(); \ } while (0)
- yock 16y agoI'm immediately skeptical of people who think modularity, inheretance, and polymorphism are a bad thing. Linus never comes out and says as much, but by indicating that he doesn't want to jump around to learn how a bit of code works he's implying it by desiring as few dependencies within code as possible. I certainly apprecate Linus' genius and the revolution he brought to computing, but we live in a different world than when he first took up C programming. Computers are far more capable than they were decades ago and we've taken advantage of that by making code much more flexible than in years past. The result is far more code reuse than early OO programmers ever thought possible. Could this possibly be the worlds first programmer-generation gap?
- Daishiman 16y agoWho said C isn't modular? You're confusing language features with programming paradigms. C can and is modular and flexible. Objects are not just a language construct A struct with corresponding functions is just as much of an object. And he didn't claim those were bad things. He claimed that the context dependency, the massive size of the language, the different implementations, etc., contribute to an environment that's not good for kernel development. On that count, I must agree.
- angelbob 16y agoI absolutely could not be the world's first programmer generation gap, because we have had so many before :-)
- johnastuntz 16y agoLinus rules! That's right, C ain't for everything
- Shorel 16y agoHe falls in the same mistake of many people: thinking that because there's operator overloading in the language, you have to use it. The same for templates. Most successful C++ projects never use some features. Some even use C macros instead of templates, like wxWidgets. It both works and compiles fast.