C++ In The Linux kernel
An anonymous reader submits "A researcher at Reykjavik University Network Laboratory (netlab.ru.is) has just released a Linux patch allowing for complete kernel-level run-time support for C++ in the Linux kernel, including exceptions, dynamic type checking and global objects (with constructors and destructors) The implementation is based on the C++ ABI in GNU g++, but contains various kernel level optimizations, that reduces the cost of throwing exceptions by an order of magnitude, thus making C++ exceptions viable in several scenarios. Furthermore, the Linux module loader is extended to handle weak symbols in C++, so that dynamic type checking is reduced to a pointer comparison, in contrast to string comparison."
how long until c# is supported?
So what will we say the kernel is written in . . C? C+? CKernelRun?
Your hair look like poop, Bob! - Wanker.
Good now I can fire up my good old visual basic and hack the kernal with COM.
I'm sure the kernel developers will LOVE the idea of putting C++ in the kernel.
It's about fucking time. Now maybe we're on the path to a bullet for killing those shallow arguments about C++ somehow being majorly slower than C, as opposed to people just not knowing the costs of C++ features.
StoneCypher is Full of BS
Java on other hand ...
:)
Or better yet - Brainf*ck, my personal favourite
3.243F6A8885A308D313
That's really awesome news, but I just can't imagine it being accepted in the mainline branch. Many figureheads in the linux kernel group are anti-C++ enough to probably veto this effort. (If "anti" is too strong, then at least I'll safely claim they're not "pro C++".)
It'd sure be nice though...
RMS is probably turning over in his grave... oH! wait he's not dead!
Zoeith
Say what you will about C++ being slower and more bloated than C, but I think this is a huge leap forward. I doubt Linus will accept it anytime soon as an official patch, though. If they have succeeded in making exceptions quick, I think C++ has a real place in the kernel. C++ offers the ability to have better type safety and more modular apis and interfaces to the kernel. For example being able to develop a new device driver inheriting from a nice base class is a good idea.
Anyway, this is a neat hack and I look forward to seeing what comes of it.
In fact, in Linux we did try C++ once already, back in 1992.
It sucks. Trust me - writing kernel code in C++ is a BLOODY STUPID IDEA.
The fact is, C++ compilers are not trustworthy. They were even worse in 1992, but some fundamental facts haven't changed:
* the whole C++ exception handling thing is fundamentally broken. It's _especially_ broken for kernels.
* any compiler or language that likes to hide things like memory allocations behind your back just isn't a good choice for a kernel.
* you can write object-oriented code (useful for filesystems etc) in C, _without_ the crap that is C++.
In general, I'd say that anybody who designs his kernel modules for C++ is either
* (a) looking for problems
* (b) a C++ bigot that can't see what he is writing is really just C anyway
* (c) was given an assignment in CS class to do so.
Feel free to make up (d).
what an incredibly awesome idea!!!
... my hats definitely off to this academic you have definitely spent your time wisely!!!!
... a real language will do us all good ...
...
i can't wait to try and debug virtual functions, copy constructors, and polymorphism over JTAG or BDM!!!!
man thats gonna be fun
i always found C causes to much clutter in the linux kernel
keep an eye for this in 3.0
Jim
I'm not sure if many people remember, but there was a short time when the kernel source was compiled with g++, even though the source was plain C.
IIRC (memeory very hazy, though), it lasted about a month in 1992 or 1993, and it had something to do with type-safe linking(?).
(S(SKK)(SKK))(S(SKK)(SKK))
Support, within the kernel, for IE^H^HMozilla! It'll be perfectly safe! Trust us!
Mod down people who tell people how to mod in their sigs
Kernel aside, I wonder if G++ developers out there have any comments on these guys' exception-handling changes?
Would they be applicable to the user-space runtime?
Matt
Any kernel project that uses C++ is most likely doomed to be an experimental project and will most likely never be included in the kernel. IMO, there's good reason for that, too. The added complexity just doesn't outweigh the benefits of using C++ over C.
In fact, there was a good post on kerneltrap not to long ago about C++ inside the linux kernel:
http://kerneltrap.org/node/view/2067
Worth a read if you've got a few minutes to burn.
I've only written one linux driver, so I'm no expert, but I can think of situations where exceptions can be helpful for device drivers.
Take, for example, a game controller or other hardware device that can become unplugged at any moment. It's useful to have an elegant way of handling this uncommon occurrence.
Exceptions are a useful way to separate uncommon sanity checks from the rest of your code, so you're not forced to use ugly nested conditionals.
My VB kernel works just fine for me.
C++ was designed to be the language of choice for modern operating systems, meant to replace C. This is main reason why every decision was made with efficiency in mind (no automatic virtual functions, no garbage collection, and, oh yes!, the infamous: pointers and goto). And of course C++ is fast. Maybe it loses by hair's breadth with C but surely wins with Java by great margin. And don't tell me about JIT, do some homework.
I think trying to incorporate C++ into Linux kernel is a good decision, giving more vitality to Linux and allowing it to differentiate better from the traditional UNIX systems - but that's only my 0.02 Euro.
You can defy gravity... for a short time
Nope. It's a condition that the throwing code couldn't handle. Someone else can handle it.
Classic example: a method calls another that calls another that calls openfile() for a temp file, which fails. the lower two methods don't care, and the toplevel one can give the user a proper error message and clean up.
People wonder why software is so hard to test, does so poorly on error handling, yet complain whenever we add mechanisms to languages to help.
Care about electronic freedom? Consider donating to the EFF!
Oh dear. Another person who thinks that exceptions should never be thrown.
If exceptions were never meant to be thrown, they wouldn't be in the language. Exceptions are an abstraction for dealing with exceptional conditions -- conditions that do not normally occur, but can occur. At the expense of some additional complexity, they make error checking a little simpler and less bug-prone. When (not if -- assuming you are a believer in Murphy's law) those exceptional conditions occur, your program better be able to handle them correctly.
You are right that some people do use exceptions when not appropriate. Exceptions are (generally) not appropriate for exiting loops, for example. But they are more than appropriate for out of memory conditions, out of disk space conditions, etc.
The reason they are not viable performance-wise is not because they are too expensive to throw; it is because they are too expensive when they are never thrown at all. There's generally a 5-10% performance hit just from having code that might possibly throw an exception, depending on your compiler's implementation. The numbers on the netlab page are for throwing exceptions, unfortunately; I would be interested in seeing if they got a performance benefit when exceptions are not thrown. Guess I'll have to dig to find a copy of the paper.
Anyone who claims with a straight face in 2004 that "C++ compilers are untrustworthy" is trolling. Sorry, rabid penguin lovers.
I love it when language bigots forestall any reasonable discussion by preemptively accusing anyone who disagrees with them of being a language bigot. Slashdot, of course, believe that Linus can do no wrong, so none of it ever applies to him...
After having conversations with him myself, I can state my honest belief that Linus doesn't understand how to use C++, and will simply assert that "it's just C anyway" no matter how many times he's proven wrong. He's a smart guy, but he's got his blinders on in some respects.
You cannot apply a technological solution to a sociological problem. (Edwards' Law)
Thats because you're used to C++. I know that code I produce in C is by far more sophisticated, and of a much greater quality than what I could produce in C++ in a similar time frame (unless I used the C subset of C++, which basicly means I was writing C).
Now if you were to start a new kernel entirely in C++, that'd be fine. The use here would be to mix the two *shudder*. No thanks. You then have a problem where the C++ people can't understand the C code, and the C people don't understand the C++ code. Its a maintenance nightmare. Just wait til the first patch that requires changing C and C++ parts. It'll be ugly.
Its much better to pick 1 language for a project and stick with it, or do a total rewrite. Mixing the two will just cause problems. Luckily, this patch has near 0 chance of being taken into the kernel.
I still have more fans than freaks. WTF is wrong with you people?
Now I'm a big fan of C++ and all, being both my language of choice and my favoured (or at least, least detested) language. However, there is the matter of using the right tool for the right job. When I need a quick, disposable tool, I don't fire up a new C++ file and work it into my project. I slap together something in ruby, and use that. Now, C++ in the Linux kernel?
The value of an OO language in larger projects is enormous. Basically there are simply too many things that could go wrong at any point, and the overhead associated with C++ (memory use, exception setup, excess copying, dynamic checking) is a small price to pay for the additional benefits it provides. As you get closer to the metal though, and you have to watch what you are doing more closely. You want to know exactly when memory is being allocated, when something may go wrong, and only want to set up to catch exceptional circumstances if you know they may occur. Resources in kernel-land are expensive. C allows this kind of control, C++ does not.
My former boss would love to see me defending C over C++ like this. The irony.
Having said that, the capability to run C++ code in the kernel would certainly be nice, provided it didn't impact the existing code. I'm not sure how this one could be pulled off though. There'd be too much code that would need to be made aware of exceptions, destructors, so forth.
Sorry, but I think you're missing the point of exceptions. They are supposed to decouple generating the error from reacting to it, because in practice that's often useful.
Exceptions are a systematic way to return control multiple layers up the code, without cluttering the code in between passing information it doesn't need to know or care about. They are best used where the code that directly causes the error can't handle it because it doesn't know how, and the code that handles it doesn't care where it came from, because the code that was trying to run aborted anyway.
You could write at least a good length article on what exceptions are and aren't good for, but in short, if you ever throw exceptions exclusively at one level and catch them exclusively at the next level up, there's a good chance you're using the wrong tool for the wrong job.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
FWIW, I believe modern compilers now approach the zero-overhead ideal for exceptions when they aren't thrown, and have done for a little time now. Several people directly involved have posted to this effect on the major C++ newsgroups in the past.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
Linux made his view on C++ in the kernel a while ago here
You can senselessly dump all your error handling code in the middle of nowhere using return-value error codes, too, if you really want to.
These guys didn't do this with hopes of it being accepted into mainline, they did it to use with their pronto project (some sort of dynamic multicasting project, using the Linux kernel).
:-)
;-)
Personally, I think mixing C++ into the kernel is not a good idea, generally, in my experience certain aspects of C++ are messy to debug, and if you're gonna skip using them, then perhaps you should've stuck to C.
Also these guys used to distribute their pronto project in one tarball, a modified version of the Linux kernel, and the website for downloading it made you have to accept *their* license. When the issue of whether this was possibly in violation of the GPL, and if they should rather distribute a clean patch, came up on the local GLUG mailing list (www.rglug.org) their response was rather shocking, they absolutely refused to acknowledge that they should perhaps distribute their code in another way, and even reverted to speculations about the legitimacy and enforcability of the GPL. To their defense, the original 'article' on the matter was very inflammatory and made some rather derogatory remarks, and IIRC they changed their website some time later.
Multicasting is a cool technology, and dynamic multicasting routers such as RU is researching and developing with the Pronto project, may well be the key to using the internet as a single infrastructure for 95% of our content-delivery and communication needs (digital TV through the internet, without exponentially increasing bandwidth load, etc), so I hope RU keep on, and their work be fruitful
Also, to everyone who refers to the creator of Linux, as 'Linux'... his name is 'Linus', get it through your heads, this is slashdot.org not mouthbreathers.org
Embedded dev is now often C++ based.
Too bad too. I am developing FAA Level A avionics software using C++, I am sorry to say. What a debocle. For starters, the compilers for non-gcc supported platforms uniformly suck. Typical compilers for DSP's lag the C++ standard by 10 years, and crash frequently. And my project is proof that if a language feature exists it will be used, no matter how pointless. For example:
or
Gross. Please keep C++ out of the Linux kernel!
an ill wind that blows no good
Clean, but not clean enough. For true conceptual purity, you need lexical closures, call-by-name, monads, lambdas, cooperative microthreads (though of course these could be simulated by call/cc), message passing, introspection and serialization, nongenerative record types, one-shot and partial continuations, maybe a little prototype-based OOP for flavor, and of course if you add prototype-based OOP, you'll need generics that are specializable by object rather than class (as well as consider the case of whether a method specialized for a particular prototype object still applies to its descendents), not to mention considering how that would affect the implementation of a meta-object protocol and multiple inheritance.
Once you've done all this, Linux will truly be ready for the desktop. (Assuming you axiomatize your language definition first, to get rid of unnecessary features like for loops).
> // C++, is this really better?
> Register_set regset(base_address);
> regset.write(SOMEREG_OFFSET , Register_set::BIT_A | Register_set::BIT_B);
Only a complete novice would write code like this. Your code setting *SOMEREG_ptr = BIT_A | BIT_B will work just fine in C++ too. In fact, you could transparently support multiple types of registers by overloading operator= of SOMEREG_ptr, which could be a polymorphic class. And if you think that is going to bloat your code, you obviously have never looked at the output of a good compiler like gcc. A good C++ design is FAR more readable than any C hack you can come up with.
> Typical compilers for DSP's lag the C++ standard by 10 years
That is the problem of your compiler, not the language. Stop bashing C++ when you should be blaming your vendor for not being able to write a decent compiler, or even port gcc to their platform.
The whole point of exceptions is that you don't care. If you care about each specific read, you wrap each read in it's own block (the same as error conditions, except that you'd use an if block).
Whats the state of all your objects?
This is why object-oriented C++ is so wonderful and Java is so bad - your objects are automagically in the correct state because you allocate and clean up resources in thier destructors. If an object is in scope, it's in a clean state. If it's not in scope, it's not. You can write some really concise, clean, reliable code using this concept - it's where the true power of objects comes into play. In C, you have to manually check EVERY call and clean up EVERY resource - it's very susceptible to programmer error, especially in deeply nested call chains with gotos and whatnot all over the place (like the Linux kernel, for example). In Java, which doesn't have destructors, it's even worse because you've got exceptions with no automatic cleanup, which means you've got to have all sorts of ugly nested try/catch/finally and state management.
Exceptions are a nice way of dealing with problems, especially nested calls. But combined with destructors, they're a magnificent way of keeping error handling safe.
People use goto in C because they want a nice exit point in the case of failure. People use exceptions for exactly the same reason - it simplifies error handling. It's true that it's physically seperate from the code, but on the other hand it's within the same block so you've got a visual/indendation indication at least. If you think exceptions are a maintainers nightmare, then you've never tried to fix an error in a function with 40 different exit points, with almost identical cleanup code at every point. A C programmer would use a goto so that there's not so much duplicate code and it's easier to maintain. A C++ programmer would use exceptions and automatic objects to do exactly the same thing, in roughly the same lines of code, with with even less (quite possible 0) duplicate code and greater modularity.
When I say "thread" above I'm not just throwing around an ad hoc term -- you can use this to provide the basis for parallel execution in an OS or language.
There is an entire school of thought built around this idea called logic programming and it is based on the most widely used foundation for mathematics -- the predicate calculus.
I don't know why people spend so much time and energy optimizing things that are less powerful.
As for object oriented programming, As I've said before:
Almost all the Object Oriented stuff people layer on predicates are, at best, an ad hoc, and poor, means of optimizing execution speed.
Let me explain.
One of the principles of polymorphism is that the same method has the same abstract meaning regardless of the kind of object. A predicate considered as a method subsumes such polymorphism by simply trying the various possible implementations of the method and committing to only those that succeed. If more than one succeeds then so be it -- that's the whole idea of relations as opposed to functions.
So, one reason you want all this OO stuff is the inheritance hierarchies keep you from going through all possible interpretations of a given method when the vast majority of them will fail for a given object.
Another, related, problem is that inheritance provides defaults without requiring a lot of thinking on the part of the computer. What I mean by "thinking" here is the sort of thing that is done by statistical imputation of missing data via algorithms like expectation maximization (EM) [clusty.com] or multi-relational data mining via inductive logic programming .
So, the other reason you want all this OO stuff is so you can avoid mining a background database to provide reasonable defaults for various aspects of the data.
Some might be concerned that over-riding isn't absolute in such a system -- that you don't absolutely block, say, more generic methods when you have more specific ones present, and they're right. You don't block those methods -- you lower their priority by lowering the probability of those implementations via the statistical methods of imputation and/or induction. In a microthreading environment they most likely won't get any resources allocated to them before other higher priority implementations have succeeded. In a single threaded/depth-first environment they will be down the list of desired alternatives -- but they won't be discarded until something equivalent to a prolog cut operation kills them off.
However, and this is the important point, the work that has been expended toward OO facilities has vastly outstripped the effort that which has been put toward more parsimonious ways of optimizing predicate systems.
One of the better predicate calculus systems out there -- more promising due to its use of tabling to avoid infinite regress on head-recursive definitions and its optimization of queries using some fairly general theorems of predicate calculus -- is XSB . It has an interface to odbc and a direct interface to Oracle, but it would be better if it had something like a
Seastead this.
Shapiro is the guy working on a research Operating System project (The EROS system).
EROS was originally implemented in C++, but then
it was reimplemented in C.
First, you're not dumb; you just don't know much about the issue. Which is good: it means you know a lot more than a lot of the people who have been responding so far.
Essentially, C++ offers support for many, many different types of programming. Just like there are some tasks for which object-orientation is better than procedural, there are some projects for which generics are superior, for which functional programming is superior, etc., etc.
C++ is not an object-oriented language and was never intended to be (as reading Stroustrup will tell you); C++ was meant to support a broad variety of programming styles, of which object-oriented programming is just one.
So what do we gain by allowing the kernel to use C++? Mostly, we allow kernel programmers flexibility to solve problems in different ways. However, the trick to this is that while we're giving the programmers additional tools with which to do their jobs, we're giving them more complex tools which sometimes fail in extremely bad ways.
Exceptions are a good example. Up until very recently, code that used exceptions was about 5% slower than code that was exception-free. This five percent penalty was unavoidable overhead. Now, some people got bit by this five percent hit (usually people working in realtime fields) and came to the conclusion of "oh, C++ sucks for RTOS because exceptions give a five percent hit".
The reason why they came to that conclusion is easy to understand: it's easier to blame their tool than their knowledge of the tool. It's easy to say "oh, C++ sucks"; it's harder on the ego to say "well, I didn't know that about C++, and it bit me in the ass."
Many--and maybe most--people who condemn C++ have not used it recently. Linus, for instance, condemns C++ based on his experiences with it from 1992, six years before the C++ language had been standardized and ten years before GNU got a decent C++ compiler.
C++ is a very complex language, as anyone, even C++ aficionados, will tell you. On the other hand, in the hands of someone who's made the (significant) investment to become a skilled C++ programmer, C++ is capable of breathtaking power and elegance.
The conflict is essentially this: one side believes "if we add C++ support to the kernel, we'll have lots of incompetent C++ people doing all manner of incompetent C++ things which are really stupid and killing performance" and the other believes "with C++ support to the kernel, we give programmers different ways to solve approach problems, and I'm not going to deny all programmers the benefit of C++ just because many programmers can't use it effectively."
I sincerely think that adding C++ support to the kernel is a good idea, subject to some strict requirements. For instance, have a C++ Czar for the kernel, someone Linus trusts to have wisdom and understanding of C++; and make sure that all C++ checkins to the kernel go through the C++ Czar to ensure that C++ is being used wisely, and not as an impediment to understanding.
Ged rid of all these crappy drivers and related crap out of the kernel source tree, and just provide the basics. They should start a new sister project for maintaining drivers, and split them up too for goodness sake. Why should I have to diff the whole stinking tree, if i've made a few changes to a networking components? or added a soundcard driver?
BEOS was onto a good thing using the microkernel, completely seperate subsections for drivers, and the ability to control teams of processes - these would all be very useful in a mainstream O/S.
C++ output may be a bit larger, but isn't all that bad, objects are very easy to visualise, and the source usually ends up smaller. Kernel Modules with a better designed interface would be an good start. And if C++ could help out here, why not?
It's about time the kernel guys opened up to a some fresh ideas. Sure, linux is already an awesome O/S, but you can't fight an the evil dragon wearing nothing but asbestos undies...
As long as they keep STL out of the kernel I will be happy. (imho templates make code look butt ugly and a behemoth to maintain)
I thought the BeOS was written all in C++ and it was darn fast. Or perhaps just the public API was C++ and the actual stuff underneath was C? I dunno. I liked the BeOS. Hmm that RC5 cd is around here someplace...
Exceptions in the kernel are inherently a bad idea. An uncaught exception is a kernel panic. By contrast, an unknown error return is still an error, and usually the right thing happens. The risk of allowing exceptions in the kernel far outweighs any possible benefit. That's why nearly every kernel that has ever used C++ at any level has explicitly excluded exceptions. (That and the very nature of exceptions inherently results in worse performance than using error returns. In the kernel, performance is far more important than facilitating programmer laziness. :-)
It would be wise for the Linux community to learn from other OSes that have tried to do kernel exceptions. Even the Windows kernel developers rejected them as a bad idea. Don't do it. Don't accept any patch that allows it.
Check out my sci-fi/humor trilogy at PatriotsBooks.
Although sometimes it is good to throw in a little abstraction. Being able to visualise some things on a different level really does help a programmer wrap their head around difficult issues that can't easily be solved going the hard yards..
For example, learning forth as a kid did wonders for me being able to get a very solid grasp on recursion. True, it's not something you use everyday, but it's a different way to think, and some problems can only be solved (efficiently) that way.
(My point is...) Having a few different programming models at your disposal is not such a bad thing. Yes, along with C++ comes a little bloat, but it also includes C in the bargain. It'd be nice having a little choice for those who want it.
My language of choice these days is a hybrid of C and C++ (well, more lazy C++) - sure it means I have to link in an extra library, but I can break out with a different model when I see a real need for it.
It is a little different at the kernel level, but their really isn't much stopping that extra bloat being included when a module is loaded.
> So why can't openfile() simply return NULL?
> Obviously an unsuccessful operation.
Well, you want to communicate back to the higher level code *why* the call failed.
Oh, wait, no problem!
Well set a global variable called errno.
Oh yes, and scratch our heads for a seeming eternity while we figure out exactly how to virtualize different errnos for each thread.
And hope to hell that no failing system calls get called between when we failed and when the user checks errno.
Rock on!
Do daemons dream of electric sleep()?
Even the Windows kernel developers rejected them as a bad idea.
MS Developer #1: I was thinking we could put exceptions in the kernel.
MS Developer #2: Are you insane? Why on earth would you want to do that? I don't think I've heard a stupider suggestion for a kernel addition.
MS Developer #1: Really? Well uhh... how about we put an Internet browser in the kernel?
MS Developer #2: FREAKIN BRILLIANT, let me call Bill.
- sm
Having a linux kernel running as a layer on top of a JVM is kinda useless since it's designed to run some sort of native binaries. So the question becomes: which target architecture do you then emulate in the JVM to accomodate the user space programs, or do you force all userland apps to be java bytecode as well? Then what's the point? Just use straight java on the JVM.
Really, more useful would be a full-fledged java-based x86 or whatever simulator with emulated hardware that a kernel would target. Then any standard propietary binaries could run in that, and even be migrated across an java cluster.
THIS THING CAN TURN ON A DIME, MACROSSZERO STYLE ALSO FUCK BETA, ~NYORON
Whats wrong with objective-c. I would consider that to be a much more viable option for adding object support into the linux kernel because thats basically what we are talking about. Without objects C++ offers no real benefit over C and in fact with the absence of objects is a detrement. Objective-C on the other hand is pure C with some nifty object support stapled on. Way better and in my opinion much more likely to be accepted by them kernel folks.