6 ms·
I find it interesting how virulently opposed Linus was to introducing C++ to the kernel in contrast to the embrace of Rust. It made me think that the idea of an
by nonbirithm 5y ago
I find it interesting how virulently opposed Linus was to introducing C++ to the kernel in contrast to the embrace of Rust. It made me think that the idea of another language in the kernel wasn't the issue in itself, but that C++ was a bad language and Rust wasn't, and also that there were tangible benefits to adopting Rust like memory safety that couldn't be had with C.
I do hope that Rust doesn't suffer from an explosion in complexity and compile times, though. Memory safety and overengineering shouldn't have to go hand in hand.
- hpaavola 5y ago"C++ is a horrible language. [...]" http://harmful.cat-v.org/software/c++/linus http://harmful.cat-v.org/software/c++/linus So yes, Linus does really like C++ :)
- phendrenad2 5y agoIf Linus dislikes something, you know it's either really bad, or really good.
- threatripper 5y agoC++ is like nuclear power. Very powerful but very dangerous if only used slightly wrong. It would have been a constant fight over which parts of C++ are off limits and which parts are good to use. In recent years the language has improved but it carries a lot of baggage. Also it's too close to C in some regards and invites C programmers who just don't know enough dark corners of C++ yet. To me C++ is a language of last resort. It can do everything you need but you should not touch it if there is any other option.
- Lev1a 5y ago> C++ is like nuclear power. Building from your metaphor, I would add: Python et al.: normal household batteries; everyone can use/operate them, not much power but can be used with little to no training and a screwup happening means you went looking for trouble Java et al.: electric batteries; substantially more power but has to stop relatively often (GC pauses), everyone can use the things running on them at least reasonably well [0] but one little thing can potentially cause a catastrophic chain reaction (one cell out of thousands => thermal runaway (eg. the infamous NullPointerException)) Rust, Go et al.: industrial backup generators or hydroelectric plants; substantially more power yet again but have a startup/setup time (learning a more complicated language/ecosystem), as reliable as can be realistically done but have to be spec'd right for the building/installation/etc. at hand (time vs. resources tradeoffs); screwups happening means you probably went looking for trouble (eg. in Rust: excessive cloning of data, building of circular references without weak references; not so sure about specific examples in Go but didn't want to lump it together with Java et al.) C, C++ et al.: "nuclear power [...] very powerful but dangerous if only used slightly wrong" like in your metaphor; should only really be used by experts but even they are not safe from introducing catastrophic failures with something seemingly harmless (seen as such at the time of writing the code); it gets safer over time but there is the huge inertia of existing installations running with huge time and resource costs associated with dismantling or even modernisations; footguns are everywhere and not always immediately recognisable especially since there recommendations about usage and safety concerns floating around which are sometimes years or decades out of date [0]: AFAICT a substantial part of the business software world runs on Java code cobbled together by not-necessarily-full-on-experts PS: My personal experiences/biases: - learned C++11 for a while, didn't like it, SEGFAULTs and associated debugging/fine-tooth-combing over the some-tens-or-hundreds-of-lines long code got really annoying really quickly - learned Java, Haskell and Prolog in Uni; Haskell was a nice intro to functional programming but nothing I would want to use even occasionally, Prolog was meh, Java was/is a convoluted, resource-hungry mess with huge amounts of boilerplate for every little thing and will IMHO always be associated with bad assignments in class(es) - Python3 I use every other week or so but not for "real programming (TM)", but instead for small (automation/download/crawler) scripts; I like it but for serious programming in a business environment - ie. something I personally would want to rely on for money - the duck-typing is just too unstable for my liking, even though I still like it for rapid prototyping of concepts coming into my head which I then later may or may not transfer into: - Rust... currently and personally my favorite language for "real programming (TM)" even though I struggled with the borrow checker for a long, long time (and still run into it on occasion); sometimes really long compile times but nice runtime performance in most cases even without special care and tuning while I still have the confidence that if it compiles it runs and any errors encountered at testing-/runtime are probably more due to logic errors than running into something like "oops, in this deep branch of cascading ifs I accidently didn't set some object's field or dict's value meaning at some later point the program blew up due to NoneError or something similar" - learned a bit of Go (before even finding out about Rust) but I just didn't like it, it just didn't "gel with me", don't even really remember the specific reason(s)
- kaba0 5y agoNot a very good analog there — most problems can be solved with any programming language, but there is a very very significant difference between batteries and power plants. Also, > but has to stop relatively often (GC pauses) is severely outdated and I don’t see how NPEs are something specific to Java.
- vips7L 5y ago> has to stop relatively often (GC pauses) Shorter pause times than Go. These are bad comparisons.
- jerf 5y agoLinus explained his reasons for not wanting C++ specifically in the kernel. I observe that very few people correctly understood his reasons, and every time it comes up I am reminded of that. The reasons, as far as I understand Rust, do not apply to Rust, hence the different reaction. Since I'm on mobile, here's a link to a previous explanation of mine: https://news.ycombinator.com/item?id=1422160 https://news.ycombinator.com/item?id=1422160 It is meant to be read in conjunction with the original post, addressing what I saw as the point most people were missing, not a complete restatement of his points.
- nneonneo 5y agoNot to nitpick, but wouldn’t some of the same arguments against virtual functions apply to function pointers in C? The kernel uses a lot of “obj->obj_ops->foo(obj, arg)” calls which are similarly dependent on the precise type of obj. In the case of these calls, the general assumption is that one can infer roughly what they _should_ be doing based on the type of obj. For example, if it was fd->fops->read(fd, buf, len) you would expect it to put some data in buf even if you had no idea what fd’s runtime type was. Your post also mentions operator overloading, which is a bit nastier since the calls aren’t explicit. But Rust also has operator overloading, so similar complaints would probably apply? In practice I’d expect the kernel to be fairly strict about limiting operator overloading (which would apply for both C++ hypothetically as well as Rust).
- jerf 5y agoIf you look at it from the assembler point of view, even function pointer structs in C have a bound on them. I can't directly speak to Rust's overloading support. If it's still one static type lookup he may be ok with it, plus you have the clarity around ownership of any intervening constructions. I'm sure the Rust Evangelism Strike Force (awesome 80s cartoon music intensifies) will be along presently to answer the question of how much assembler one can generate with an overloaded operator. C++ really does have a particular ability to stack a huge number of abstractions into one little line. Ultimately it's a continuum rather than a sharp line, but C++ is really far on one side.
- lenkite 5y ago"but that C++ was a bad language and Rust wasn't..." Google chose C++ 17 as the implementation language of the Zircon kernel for the fuchsia OS. https://fuchsia.dev/fuchsia-src/development/languages/c-cpp/cxx https://fuchsia.dev/fuchsia-src/development/languages/c-cpp/... PS: C++ compile times are actually shorter than rust compile times.
- magila 5y agoThat tells us nothing about C++ vs Rust because the decision to use C++ for Zircon would have been made back in 2016 or 2015. At that time Rust was too immature to warrant serious consideration for such a large project. More recently use of Rust in Fuchsia has been expanding, although the C++ kernel is obviously far enough along that they're not going to re-write it in Rust.
- oscargrouch 5y agoIts not just that. The experience of the teams also counts. For this kind of project its more important to have people with pratical experience in kernels, than experience in a particular language. These people will have a experience in languages they used before, so even if the decision was taken today, you wouldn't find enough people with experience in kernels AND Rust, but will have much more people with experience in kernels C and/or C++, so C++ would still be a good default in comparison to C. It would be pretty amateurish to get the kernel expert folks to learn Rust while implementing it, as it would probably mean that the end result in Rust would be worse than the end result in C++ as they were more comfortable and experienced in that language. It will take more time to form specialists in some key areas so that decision can be made with less side-effects.
- phaker 5y agoFirst, it _would_ make sense to use a narrow c-like subset of c++, but lots of people wanted to bring 'good practices' from c++ to the kernel. And many of these were _bad_, C++ was a different language back then and the culture of how you write C++ was different. There were times when it was fashionable to write OO spaghetti almost as bad as the stereotypes about java, or templates that worked except for some unforeseen footgun (then you could template libraries that worked correctly but figuring out how was a trip). And before all of that there was a decade when C++ compilers were just _full_ of bugs, and before that there was no standard and every compiler was different. The negative stereotypes about C++ come from all that. I think he had every reason to fear that e.g. he would have to fight someone who implemented control flow using an inheritance hierarchy because it's a pattern. And he could find himself in the minority. (Also I'd say there are still counterproductive fads, and it's still common to write C++ that's beautiful on the outside and completely inscrutable inside, or generally pay a huge price in code size and complexity for marginal gains elsewhere, or to depend on optimizations that don't trigger. Same in many other higher-level languages but somehow not in C.) Second, more important, i don't remember any talk of adapting C++ to bare metal programming, while there is an ongoing cooperation with rust folks already.
- plorkyeran 5y ago> Second, more important, i don't remember any talk of adapting C++ to bare metal programming, while there is an ongoing cooperation with rust folks already. C++ already is used in bare metal environments and in at least one production kernel (XNU) so there just isn't any adapting to do. The standard explicitly distinguishes between hosted and freestanding environments and defines what you should expect to have available.
- ncmncm 5y agoFurthermore, it would absolutely not "make sense to use a narrow C-like subset". That would exercise none of the power of the language to generate constructively-correct, high-level, yet optimal code. You would just have the same buggy code with slightly different syntax. That would be very dumb indeed; although, once you start building the native C code with the C++ compiler, it is easy to incrementally improve matters, keeping the system working continually throughout the process. As one does. That does not mean you would try to use virtual functions (much), or std::vector or std::shared_ptr (ever). Instead, you would use abstractions tailored precisely to the kernel environment, and arrange that wrong code would tend to not compile, so that when code compiles, it works. In C, you have to enforce all conventions by obeying instructions in comment blocks, and updating all uses every time the comment block changes. In C++, you can encode the rules directly into the type system and put that to work, not just checking correctness, but actually generating correctness. This is the same as one would do in Rust modules. Failing to make full use of Rust's type system would be a grave mistake that we need not fear will happen.