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?
for us non-developers, this means what?
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
n/t
oh dear, again someone who doesnt; understand that exceptiosn are designed never to be thrown. If they were everyday occurrences, then they wouldn't be, well, exceptional.
Unlike some languages who use exceptions for events that you expect (like End-of-file) and poor programmers who think that because they're there, they must be used all the time, for everything, exceptions are a defensive programming measure to ensure that the things that should never, ever happen, are handled gracefully if they do.
Java on other hand ...
:)
Or better yet - Brainf*ck, my personal favourite
3.243F6A8885A308D313
This can only be viewed as a good thing.
I know that code I produce in C++ is by far more sophisticated, and of a much greater quality standard than what I could produce in C in a similar time frame.
I hope that this will be the beginning of some new more sophisticated features for Linux!
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...
When can I submit my Perl patches to the kernal? I am waiting for that.
C++ in the Linux Kernel
We have implemented a complete kernel level run-time support for C++ in the Linux kernel. In particular our run-time support enables the full use of C++ exceptions in the Linux kernel, but notably also includes support for global constructors and destructors, and dynamic type checking. Our kernel level support is based on open source commodity components, specifically the GNU gcc/g++ compiler and its exception implementation, the C++ ABI version independent standard interface.
C++ runtime support for 2.6.6 (Last update 27 october 2004)
C++ runtime support for 2.6.9 (Last update 27 october 2004)
Using the C++ runtime support for Linux
Installing the C++ runtime support for Linux
The code is installed by applying a patch to the Linux kernel and enables the full use of C++ using the GNU g++ compiler. Programmers that have used C++ in Linux kernel modules have primarily been using classes and virtual functions, but not global constructors. dynamic type checking and exceptions. Using even this small part of C++ requires each programmer to write some supporting routines. Using the rest of C++ includes porting the C++ ABI that accompanies GNU g++ to the Linux kernel, and to enable global constructors and destructors.
The implementation of the C++ ABI is based on the implementation provided with the source of the GNU g++ compiler. We modified it to run in kernel space, and performed optimizations that reduces the cost of exceptions and dynamic cast considerably. Our paper contains thorough explanations of these optimizations. The cost of throwing an exception one level on a 990 MHz Intel Pentium is around 12-13 micro seconds in the plain GNU g++ implementation, which we reduced to 2.1 micro seconds by modifying the runtime library, including unwinding the stack in one phase, and caching information on exception paths. In contrast the cost of a trivial printk operation -- printk("Error\n") -- is 18 micro seconds.
In addition, we modified the linux kernel module loader to handle C++ weak symbols correctly. GNU g++ associates with each class a type information object that encodes the type of the class as a mangled string and puts a pointer to this object in the virtual table for the class. GNU g++ uses weak symbols to reduce the dynamic type checking to a pointer comparison, thus avoiding the more expensive string comparison. Each time a class, containing virtual functions, is used in a source file, GNU g++ generates the virtual table, type information object and type name string as weak symbols and the user space linker ensures that there is only one copy of this object, which renders the simple pointer comparison sufficient. However, the kernel module loader, which in the 2.6 versions of the kernel is exclusively in kernel space, does not handle these weak symbols correctly and always relocates references to weak symbols to the weak definition within each object file that is being loaded. Therefore multiple type information objects may exist for the same class and pointer comparison becomes insufficient when doing dynamic type check across kernel modules. To avoid this overhead we have modified the kernel module loader to handle these weak symbols; the first time a weak symbol is encountered it is added to the symbol map, and on subsequent encounters the relocation is done to the first symbol.
Paper:
Exceptional Kernel: Using C++ exceptions in the Linux kernel
Halldor Isak Gylfason, Gisli Hjalmtysson
Submitted for publication October 2004 abstract
Please direct bug reports, questions and comments to {halldorisak at ru dot is}
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.
Linux doesn't want any C++, so as long as he's at the top, it likely won't get far. And I think that's good, given the state of C++ in gcc (hint: slow and memory-intensive compiles, generating subobtimal code).
But I'll shut up. I've pretty much turned my back on C and C++ anyway.
Please correct me if I got my facts wrong.
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
using the kernel now? :)
;)
Joking aside, this is cool. Runtime compiling makes conceptual sense in an open source operating system running mainly open source software... though it will surely add to load times. It adds to the openess of open source by keeping the source editable straight up untill run-time and, so, encourages keeping source code and editing source code... being that it is immedietly executable, given it was coded correctly of course
Please help! I'm stuck inside my virtual reality headset!
Sounds like an exercise in obfuscation. How will SCO handle this?
Zhrodague.net - I do projects and stuff too.
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
Just this afternoon I pondered if Linux supported C++ like this. With Slashdot I don't have to go out of my way and do things like being social to get things answered anymore. Thanks, Slashdot, for ensuring my nerdyness!
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.
but don't use runtime type checking in the kernel please.
or exceptions.
-pyrrho
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.
Like they handle everything else.
* A nice handshake
* Grease up the 10 feet pole
* Insert it in
Worse than C++.
Objective-C is too dynamic, and all objects are heap objects.
Linus is rolling in his grave.
Every day newer appliances are thrown in the market without Linux drivers; a C++ kernel won't help much in avoiding this. *Please* if you have enough resources/knowledge go test some hardware and help developing drivers for unsupported stuff.
In other words, put the efforts where they're most needed.
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
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)
The article says that they managed to support C++ in the kernel. Well, that's sweet as an accomplishment. But what are the benefits? many parts of the kernel are already object-oriented, in the form of manually written vtable structs and object structs that have pointers to those vtables. I just don't see a reason for C++ in the kernel. Maybe someone that knows more on this can enlighten us.
While the NT kernel itself is written in C, and Microsoft doesn't officially support C++ for drivers, many people have figured out how to write Windows drivers in C++. It's about time Linux caught up!
</troll>
just don't try it on a 486 or for that matter a P1 or P2, unless you have gobs of ram and time to burn. Having smp with P1s or 2s might help. But how many cheapo multi-processors are still around? C might be out of date, but atleast it is quick.
Or at least drive him (more?) insane!
The good news is that we have a new renewable power source. What you do is wrap Linux in wires and place him in a magnetic casket. Putting C++ in the kernel will cause him to roll fast enough to generate enough electricity to power North America.
Haven't they read "Exceptional C++"? C++ is a fucking disaster. It kind of constantly conspires against you to shoot you in the foot in some kind of massive manner where you'd least expect. Sure, non-exception enabled code is ugly (check the return values all the time, etc), but any non-trivial exception-enabled code is nearly impossible to write if the requirement is that it works correctly in all situations (which is what the requirement is for the kernel).
Don't get me wrong, C++ is an OK language, but I'd think twice before using its exceptions.
thus making C++ exceptions viable in several scenarios
By experience, C++ exceptions are the worse way of handling errors and leads to too many warp jumps that are difficult to track, trace and debug.
C++ in a kernel is fine with me. But throwing exceptions in there is asking for trouble.
This guy has seems quite correct.
/b
|f(x)dx = F(b) - F(a)
Haha! Now I'm a troll for dissing Linus!
No, you're a troll for playing the victim before you get modded into oblivion.
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.
If we're going to add exceptions to the kernel, lets go all the way and add "call-with-current-continuation." Imagine how much cleaner the resulting code would be!
would side with Israel, they can do no wrong in your fundamentalist mind, have a nice brainwashed life loser, it's the only one you get ;)
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.
C++ could help a lot making kernel development faster, making it easier to use more efficient data structures, and making it easier to avoid resource leaks, buffer overflows, and other problems. Whether or not this leads to any inefficiencies or code bloat in the kernel is up to the kernel developers; C++ has many faults and it fails to fix many of C's problems, but it does deliver on its main promise: you pay only for what you use.
But in order to make C++ work in the kernel, the kernel developers need to stand behind it, set clear coding guidelines, and be committed to it. I don't see that yet.
Linux made his view on C++ in the kernel a while ago here
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
The simple reason for that is that otherwise the kernel would be unpredictable. Let's say the error logging function used the string class (which likes to allocate memory behind your back). If the memory allocation function fails and tries to print an error message... you got yourself a kernel crash. This is why the kernel is significantly more difficult to program than, say, a word processor.
Put the strawman away. You don't absolutely have to use all the features C++ gives you if they aren't right for you. Don't use exceptions or run-time typing in an environment where you don't need it, or don't know if it'll work. Personally I never use either because I strongly disagree with the code they generate. If you don't understand that skilled usage of C++ generates exactly the same code that the equivalent C would (except the C++ took less time to type and checked your syntax better), you don't understand the point of C++ whatsoever. It's just a glorified type checking macro expander. And there's no reason to use plain C when you've got that at your disposal.
Now have a look at examples of kernels written in C++. One easy example: Red Hat eCos. Just saying that C++ doesn't do kernels well doesn't remove the fact that people do use it in kernels, it works very well, and there are many examples out there.
And, to add one more thing, nobody around here appears to have bothered to read what that fucking patch does anyway.
It doesn't add C++ support to the kernel, you blithering slashbots.
It adds native kernel support to C++ in userspace.
Doh!
Beat me for my sub-geek intellectual prowess :(
I'm Rick James with mod points biatch!
C++ is an extension of C... a continuation of it's ideals to see the machine as the machine sees itself, to allow the programmer latitude with the machine while giving ways for the programmer to protect itself from common problems.
C++ is not distinct from C because it's evolution has been driven by adhering to the systems oriented philosophy of C and also by a very real effort to keep C++ "compatible" with C.
Obviously, to take advantage of C++'s improvments, you have to learn and use them.
-pyrrho
C++ supports // comments! how can you pass that up? out of interest, what where the various versions of Windows written in? The kernel is pretty hardcore, and as much as C++ is fun and mature i don't see the need to taint that image of proper tried and tested built like a brick *nix reputation, really the kernel should be written in assembly (since its _ment_ to be for the x86) but c isn't too far off.
This comment does not represent the views or opinions of the user.
Exactly. This is a Good Thing.
You cannot apply a technological solution to a sociological problem. (Edwards' Law)
This is a sacrilegy
It doesn't add C++ support to the kernel, you blithering slashbots.
Really... well, to quote the article:
In particular our run-time support enables the full use of C++ exceptions in the Linux kernel
Programmers that have used C++ in Linux kernel modules
Exceptional Kernel: Using C++ exceptions in the Linux kernel
So, you were saying?
it would be interesting to read a paper that discusses C++ compilers and their trustworthiness.
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
... your 0.02 CENT?
I am very small, utmostly microscopic.
anyone care to explain in reasonable level terms what having runtime level C++ support in the linus kernel actually means?
Whats the issue ?
nick...
Electronic Music Made Using Linux http://soundcloud.com/polyp
and he'll start throwing exceptions all around the place like crazy...
...is prone to abstruse and glittering generalities.
One must only be *consistent* in one's use of exceptions. I (occasionally) write exception heavy code. That doesn't lead to the proposition that exceptions only exist to defend against things that should "never, ever happen."
Exceptions exist to remove redundant (and so error-prone) checks. If a tree branch is twenty-steps deep, and each step must check the return code on the branch for the error case and handle it and then propigate it back towards its caller, then you nave nineteen redundant code actions and so nineteen opportunities for someone to make a (compundable) mistake in handling the error.
The C++ exception mechanisim provides a means for the compiler to generate all the code to Do The Right Thing(tm) automatically and without _unnecessary_ programmer interaction.
The short version is that if all you classes (objects) do proper semantic cleanup on destruction, and all your call frames are exception safe in their handling of intermediate state, then stack-unwinding *is* proper semantic cleanup. When something more than cleanup is needed, there, and only there, is where you catch the exceptions. This leads to only having to write the error _handling_ code once, in the proper and meaningful context.
The fact that C++ exceptions throw fully-fleshed objects means that the exception itself can communicate more than its mere existence, which makes it even more useful. (I will skip the digression here, but I have used excpetions to "return" references to offending objects into contexts where they can be dealt with, with great success, and without having to burden call semantics for intervening frames. It's an incredibly powerful and readable technique.)
The fact that _many_ programmers "are bad" and don't otherwise maintian "semantic invariants" in their objects; allocate "bare" pointers; and catch exceptions by value instead of reference leads to a lot of people writing marginal exception-based code that is *terrible* and unsustainable. But that is bad art, not bad facility. I have seen similarly disasterous choices in every language I have ever been exposed too. (It's a poor craftsman who blames his tools. 8-)
So what?
A lot of people injure themselves using nail-guns each year, which is not a argument against construction equipment, it's just an argument against incompetence.
The sole point of contention is whether the "error" must be an _ERROR_ or if it is sufficent for the "error" to "just" be a "sufficently exceptional condition" to merrit a non-local return.
At least it's not setjump/longjump... 8-)
Personally, I anchor the root of my exception class hierarchy on Exception ==> Fault and Exception ==> Error, with classical errors branched off of "Error" and semantic errors based off of "Fault". I then crash-proof by catching any Excpetion by reference in the last recoverable frame before semantic collapse. (This protects against "unexpected" and other stupid mistakes to which even I, in my infinite wisdom, are subject. 8-)
For instance consider Fault ==> LockFault. I throw a LockFault whenever you/I mess up a lock (unlock a lock you don't hold or "try" a lock and fail to get it). These semantic errors are "common enough" but still deserving of exception status. The LockFault lets me "back off" from deadlocks automatically because I A) hold locks via objects so the destructors release locks during stack unwinding and B) I can catch lock faults in a context where a retry makes sense instead of passing-out state itteratively. This then leaves me "ready to act" in a semnatic frame where a retry can be logically attempted (as opposed to mechanically attempted) in a rational and reasonable manner.
Further, these locking layers are managing real (unpulgable) devices and real (droppable) network connections. The braided exceptions path is, at first, complex, but after a very-short period of annalysis makes sense, as all three semantic fa
Innocent people shouldn't be forced to pay for inferior software development.
--"Code Complete" Microsoft Press
My pet peve: the gaping hole in the standard regarding the use of virtual functions from constructors and destructors and routines that serve them.
If a member object's constructor, or a routine it calls, somehow gets hold of a pointer to the containing object and calls a virtual function, IMHO it should be performing a legal operation and should get the BASE CLASS version of the function. Ditto in the destructor. (At this stage of construction the base class is fully functional, while the derived class is not yet initialized making attempts to call its version of the function massively broken.) Ditto during destruction. The derived class version should be the one you get beginning with the first line of the body code of the constructor and ending with the last line of the body code of the destructor. (The object transitions during those sections of code, which can be coded carefully to only use virtual member functions whose support is initialized.)
Everywhere else C++ uses extreme care to get the "right" level of virtual function. (This is unlike Objective C and Smalltalk, which "get it wrong" big time by calling derived class (subclass) versions in base class (superclass) construction code, breaking the already-debugged code.) But here the standards - and the implementors - missed an imporatant point.
With an opportunity for both construction and destruction code to get it "right" (call the base class version) or" wrong" separately you have four binary combinations - of which one is "right" and three "wrong". In the early days (pre-standard), cfront got it "wrong" one way, gcc another way, and three commercial compilers for PCs the third way. (So the standard would have imposed equal pain by prescribing the "right" way, leaving them all "broken".) But the first ANSII standard explicitly left it undefined, while the second one not only affirmed that but explicitly warned against calling virtual functions from constructors and destructors.
(I did bring this up with the committee both times, but was unable to sway them, even to make it a recommendation or to provide a "pedantic construction/destruction order" switch.)
Getting it "right" would have had considerable benefits. There's a lot of useful things (which I won't go into here) that become easy if it's "right" and breaks badly - or requires combersome workarounds - if it's "wrong". And getting it "wrong" also leads to subtle bugs and interactions even if you're NOT trying to do something fancy.
(Because it was "wrong" in all the compilers and not forced by the standard, a large programming project I was working on back then was forced into workarounds that gutted the opportunities to build complex objects using member objects, replacing them with smalltalk-style heap-allocated objects strung together by pointers (with enormous overhead as a reault) and creating an initialization function hierarchy parallel to the construction hierarchy to get things properly spun up.
In the kernel the code must be solid and really should be tight and do things the obvious and simple way. So a feature-gutting, bug-attracting, spec ambiguity like this is a nightmare.
Thus for me:
* (d) There's a big fat hole in the standard.
Is a killer.
Bantam Dominique roosters crow a four-note song. Once you've heard it as "Happy BIRTHday" you can't NOT hear it that way
People should instead jump to JAVA, and write te whole of it in Java!!!
and waiting for Linus to flame them into oblivion...
Red Leader Standing By!
From the patch: +/* Define to 1 if installation paths should be looked up in Windows32 + Registry. Ignored on non windows32 hosts. */ +/* #undef ENABLE_WIN32_REGISTRY */
Linus is rolling in his grave.
No matter how low your opinion of Portland, moving there is NOT as bad as dying.
Bantam Dominique roosters crow a four-note song. Once you've heard it as "Happy BIRTHday" you can't NOT hear it that way
The fact is, C++ compilers are not trustworthy.
Neither are C programmers. But unlike C programmers, who keep making the same mistakes generation after generation, C++ compilers are actually getting better with time.
any compiler or language that likes to hide things like memory allocations behind your back just isn't a good choice for a kernel.
But C++ doesn't hide memory allocation behind anybody's back. You get to decide exactly where memory allocation happens and where it doesn't.
* you can write object-oriented code (useful for filesystems etc) in C, _without_ the crap that is C++.
Yes, because it is so much "better" to let every programmer make up their own crap rather than to have an efficient, compiler supported standard for dispatch tables.
Haiku (formerly OpenBeOS) has had parts of the kernel in C++ since the beginning.
/ cu rrent/src/add-ons/kernel/file_systems/bfs/
Most notably the reimplementation of the Be File System. (Now OpenBFS)
http://cvs.sourceforge.net/viewcvs.py/open-beos
The filesystem is not slow at all. Actually the Haiku-people did some speed comparisons with Be's BFS and OpenBFS won.
Other parts of the kernel is C++ as well. The device manager, an experimental vm..
I've never really understood this anti-c++ in kernel thing.
"Embedded dev is now often C++ based."
Your comment is at best misleading, and at worst flat out wrong.
I have no idea what type of embedded development you do, but I strongly
suspect it's at the application level - not the kernel.
In the Linux/UNIX/BSD area (which these days comprises most of the
embedded development out there), embedded development is mostly C based,
with C++ applications thrown in, maybe.
If you do a count of the code size, including the standard Linux utilities,
and libraries, you end up with most of the code still being C. I grant that
you could come up with a bloated C++ application which out does this. But if
you've got such a beast, it's usually due to code bloat.
> // 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.
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.
The fact is that the Linux kernel is not just C, it also has parts where it uses assembler because they don't trust even the C compiler for that part of the code.
The fact is that in the kernel much of the low level code cares about the exact physical layout of memory, and if it were mostly C++ you would need more parts in assembly which must be ported to each archatecture.
Yes, C can be used in a higher level, but you are calling functions that deal with the low level from there is a very much OO way.
Also, when you see people benchmarking how many cycles a processor actually takes to perform a snip of code and analyzing the assembly of the C program, I sincerely doubt that they would not be able to do the same for C++.
There: Something at a specific location.
Their: Owned by someone.
Please make sure your english compiles.
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.
That's an OS used in deeply embedded environments called "cell phones". There's a real-time version.
Or is that all userspace code, not kernel code? Looked to me like both use C++.
People pushing C++, Java or other OOP languages for kernel level development just don't understand kernel development. One simply does not need all the baggage that they bring.
The most efficient solution is what the Linux kernel is already moving toward; and, I might add, what Solaris has incorporated for years. Namely, developing things in terms of objects, when it is useful. You CAN do OOP in C already, you just need to know what you are doing.
The question is whether all the extra baggage that C++ brings to the table is useful. IMHO, as a long-time kernel developer, no, not at this time. However, some of the techniques used by the OOP people DO have benefits, and more kernel people should recognize this.
From what I have seen going on with the latest kernel development, this is indeed recognized, and things are moving in that direction. In an efficient manner, I might add. And certainly in C.
If the drawbacks and bloat of C++ outweighed its benefits, then I could see it being used. But I don't see this happening in the near future. It will always be more efficient to do things in C; and adopt OOP techniques will be adopted when it is desireable. That approach impresses as much more efficient, well balanced, and desireable for kernel development.
..Maybe not necessarily in the kernel area, since a kernel has pretty few tasks normally, but in general. This is why I strongly disagree with http://www.gnu.org/prep/standards/html_node/Source -Language.html. The whole point of open-source software is that developers around the world can contribute to to projects they deem important out of good-will in their spare time, or at least extend them in a useful way for their own personal use. If a project is written in C (or even C++), a would-be contributor has to learn somebody else's coding style and try to understand a large, monolithic piece of software before making any contribution. This is a huge turnoff for someone who has a job to work at to make a living (especially a job that involves programming) or to a student who has classes. Sure, there are people who work on OSS for their regular work or zealots who don't mind programming all day, but you're missing out on a whole lot of potential by advocating an antiquated, low-level tool in an area where rapid, error-free and extensible development is most important.
Imagine most Linux apps were coded in .NET. *falls back at the the roar of millions of slashdotters bawling* Ok, imagine *you* had created .NET as the official recommended environment for Linux application development. Extending functionality for an application would then be almost trivial, provided the developer used proper OO design. Heck, you wouldn't even have to recompile, because of loading at runtime. You'd also have stronger guarantees about what the application is allowed to do (no memory leaks, you can even run untrusted code in a sandbox). And debugging would be much simpler with a VM environment and an exception stack trace than it is with "the app crashes 50% of the time when I finish downloading a new theme". Not to mention that you'd be able to use your own favorite language yet interact with any older code you need to deal with, or write plugins in yout language instead of having to learn everyone's variant of Scheme.
If you want an example of this, check out Eclipse. It lets you easily create plugins that latch onto well-defined "extension points" in each subsystem or existing plugin. Thus people have integrated support for many other programming languages and all kinds of extra features for the Java tools. Installing a plugin only involves copying its directory or zip to eclipse/plugins (for that matter, installing Eclipse itself only involves unzipping it). The built in plugin development tools let you create a new instance of the workbench with your new plugin in 1 click, and you can then debug, etc because everything is just running in a separate JVM that Eclipse has full control over.
IMO, lack of a consistent, easily extendable framework is one of the biggest weaknesses of open source (especially Linux) right now. If Microsoft makes writing a plugin that does something cool for its office app, web browser, development environment or whatever easier than you do, and all I really want is to get the program I use most often to do something I really need, I won't hesitate about writing it for the Microsoft program instead of yours. And with .NET and Longhorn, Microsoft is moving towards just that.
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)
Now, I'm a C++ fan. I'm a huge C++ fan. It's my language of choice. However, Linus is correct, "C++ is just C anyways". Go take a good long hard look at cfront (not sure if that's still current). C++ was literally convertable to C. Still is to this day to the best of my knowledge. There is absolutely no construct in C++ you can make that I can't do in C. It might not be a simple, it might not be as easy, but it can be done. Virtual tables, are nothing but fancy tables of function pointers. Templates are nothing but a simplification for writting the same code over and over. References are hidden pointers that can't be NULL (unless you trick the compiler). Exceptions, ahh, now that's harder, but even their it's nothing but a setjmp, longjmp type problem. I'm not saying they are nearly as easy or useful to write, but it is in fact true. Even constructors and destructors are nothing but code that must run. If you are careful, you can arrange for that in C. Yes it's harder, but it's not impossible.
Name a construct that has a useful application in the kernel that is in C++ that can't be easily duplicate in C with the use of arrays of function pointers and macros?
Remember useful. Anytime Linus wants to hide the implementation details, he does, he just uses an opaque type. He doesn't have to worry about references or non-references (especially not the NULL pointer checks that happen on every access of a reference with g++ 2.96 (not sure about later versions), that you have to disable to speed up the code). There are lots of hidden things going on in C++. They are grand and glorious most of the time.
The most useful constructs of C++ is the STL IMHO, and those are completely not allowed in a kernel. Too many memory allocations that happen transparently. Too many nasty bits where you can't access them in some specific context (interrupt context jumps to mind). You'd have to rewrite them yourself, and they already have an implementation of lists in the kernel that are C style templates.
C++ is syntactical sugar that makes it easier to enforce certain things. That's it. It's a better C. However, the number of people who can do it, and do it well are few and far between. A good tool (like the one Linus has been working on), that checks to see if you are following a specific set of rules, would be much more useful then attempting to graft C++ into the existing kernel. We'd be much better off to write tools that ensure you are using the API they way you are supposed to, rather then attempting to write the API so that C++ can check it. C++ has no concept of "interrupt context", it has no concept of "preemptible code", it has no concept of per-CPU data structures. Those are the things that need to be checked in a kernel. Not if you are accidently accessing a data memeber you shouldn't be.
A lot of the things that have been added to C++ aren't going to make it better for writting an OS then C is. You can write some wonderful interfaces useing just straight C. It's more complex the most part. If nothing else, I wish that the Linux kernel would use C++ just to get namespaces, but that's just me. C++ does have times when it can take templated code and optimize it better then C can due to it's more advance understanding of type , const'ness and inlineness. However, remember that kernel hackers would just write a custom version and use it when it's a measured speed problem.
Kirby
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...
Even g++ can give the zero-overhead ideal for exceptions. It's heavily dependant on the platform and the platform-specific ABI.
Linux on x86 ain't one of those platforms.
You cannot apply a technological solution to a sociological problem. (Edwards' Law)
Which are now 4 years old. They're dead. They're unsupported unless you pay hefty dollars. They're known to be non-complaint with any C++ standard, ever. They never were.
So is C. So is anything above assembly. Door's that way, troll.
You cannot apply a technological solution to a sociological problem. (Edwards' Law)
This seems to be turing into an all out war! Im a CS student in college and we're learning Java now, but in my CS class in High School, it was C++. I never became advanced enough to really compair C++ to anything, espically C. Could someone recomend a book or online article that fairly debates C vs C++, perhaps in terms a n00b level programmer could understand?
/, moderators continue to amaze.
You missed the word "particular", Einstein. Meditate on it.
GOOD LANGUAGE? C++ is just a pile of crap bootstrapped on to C. Obj-C, Smalltalk, Perl/Ruby (With perlcc. I hope that we might get a rubycc soon) or maybe even JAVA (compiled into binary, not bytecode) would be good. Now, I don't like Java's syntax that much, but its better than CCrapCrap.
To support Obj-C all they'd have to do is include the Obj-C runtime. No problem.
that what you thought was exception safe is in fact not exception safe. I've seen our local C++ "god" spend entire week hunting down a signle bug which only manifested itself after a few days of intensive load test. The code was multithreaded and it had to be thread safe as well. Turns out, even the guy who has been using C++ for 10+ years now could not write multithreaded exception safe code. He could not find the bug by just looking at the code, either. He ended up working on a memory dump and calling in other experts from around the company to figure out what was going on. They spent five days to find out that exceptions didn't quite work the way they expected them to and because of this there was an extra decrement on a variable in RW lock which deadlocked the waiting threads.
Sod that. I want UT2004 in the kernel.
It's all about the framerate, baby.
perfect example of why c++ doesnt belong in a kernel. with proof by someone who wrote a kernel in c++.
Well, not _entirely_ true. I mean, obviously, you can program C++ without doing mallocs. The question is, if you restrict yourself in that way, do you give up a major feature of the language? The answer is Yes -- you lose polymorphism, in effect. In order to use objects polymorphically, you must pass pointers to them. The pointers can be upcast/downcast. If you don't pass a pointer, then your object is stripped.
Admittedly, it is possible to pass around pointers to stack-based objects. But in my experience, you don't end up with safe code. What you want is reference-counted objects. Such objects must be allocated on a heap.
I only bring this up because, over the course of several years' C++ programming, I've gradually eliminated almost all heap-based (well, explicitly heap-based) activity. I can do _almost_ everything with stack objects and STL containers. However, whenever I need to make use of polymorphism, I find that I need a reference-counted heap object.
I don't care what you think about structured programming.. this is the ONE good use for gotos.
There is absolutely no construct in C++ you can make that I can't do in C. It might not be a simple, it might not be as easy, but it can be done.
That's because both languages are Turing-complete, idiot. You can convert any construct in Scheme or Prolog or Brainf*ck to C, as well.
Anyone who claims with a straight face in 2004 that "C++ compilers are untrustworthy" is trolling. Sorry, rabid penguin lovers.
The fink project has recently traced crashing problems to gcc 3.3 generating incorrect output from C++ code.
As of about mid-2004.
My God, it's Full of Source!
OUTSIDE_IP=$(dig +short my.ip @outsideip.net)
Find free books.
I'm tainted - in the days of punched cards, // in the first two columns signified a job control (JCL) statement to IBM mainframes, and you NEVER wanted to write a program that relied on those characters in those columns EVER. Just seeing it adopted in C++ (and gcc) gives me the willies. The only worse combination was /* (oops, isn't that a comment in C?).
While Linux started out as x86 only (and is obviously mostly used there), it actually runs on lots of architectures, which I think is a GOOD thing if you can manage it, and which defeats the argument that it should be written in assembler.
Why dont they just make it all in assembly? Would be alot faster...ohhyeah.
Current Operating System kernels created by Linus: 1
Current Operating System kernels created by devphil: 0
priceless...
Depends on whether you consider kernel modules "in the kernel". It allows kernel modules to be written in C++ (they give 2 sample modules) which before apparently was required lots of extra redundant support code. Nobody is forcing kernel (proper) developers to use C++.
It's 10 PM. Do you know if you're un-American?
Neither the kernel proper nor kernel modules are commonly called "userspace".
Yes, on re-read I even have errors in the title. Sigh. I furvently wish this site had the nice "check spelling" button like on the bottom of the gmail compose page.
I just cannot seem to keep my dyslexia from misfireing all over anythin I type when I am this pressed for time.
(Slashdot is not work-hours compatable unless I am really fast... 8-)
Innocent people shouldn't be forced to pay for inferior software development.
--"Code Complete" Microsoft Press
until the kernel supports java.
In theory, an exception is just a more expedient return statement -- it lets you immediately branch to the handler. In some sense, they're a bit like using setjmp/longjmp, labeled branches (a feature not found in C/C++), or continuations (another feature not found in C/C++). But it also means that there is absolutely no benefit provided if you only use it as an alternate means of returning to the caller.
Exception handler addresses can be pushed onto the processor stack just like the return instruction pointer (or they can be pushed onto a separate exception stack). Any function that needs to do exception 'cleanup work' can push its own exception address instead of its caller's.If you're passing an exception through multiple functions, raising an exception can bypass significant number of comparisons and jumps. It also reduces clutter in the intermediate functions that don't have to bother testing for an error condition and passing back a return value.
However, in C++ you run into the situation where 1) nearly EVERY function has an implicit exception handler to calls all the destructors for the stack variables, and 2) optional exception handlers require expensive runtime typechecking comparisons to see which handler gets to run. The former means you don't end up saving much with C++ catch-all exceptions (i.e. "(...)"), and the latter means you actually end up losing performance with type-specific exception handlers! The article mentions using pointer comparisons here to help reduce this performance hit.
Basically you use C++ exceptions for convenience/safety, not performance. They're particularly useful when you're calling 'unknown' code like virtual functions/function pointers (in other words: drivers), and that's why there's interest in using them in the kernel.
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
..you mean the linux kernel isn't written in Visual Basic?
As far as my priorities on implementing an OS based on the predicate calculus criteria I set forth -- I'll "get back to you" after I've handled a lot of very much more important issues. I'm 50 years of age with a lot of responsibilities. If I give advice and refuse to take it from some anonymous coward who thinks he's qualified to diagnose sanity and judge the merit of scientific arguments that are too threatening to his world view to consider them without reacting against their source, then so be it.
If I do happen to break free of more pressing matters and can afford the time to spend doing this sort of system, you should not, in your anonymous narcisism, convince yourself that your "advice" contributed to the completion.
Seastead this.
The kernel developers have found a number of bugs in GCC over the years. Do you think it's unreasonable to say that G++ is likely to be more buggy than GCC?
Not true. (the bit about untrustworthiness of cpp compilers)
C++ has quite a few areas of the language that actually exhibit _undefined_behavior_. Sure, on any one implementation it may be predictable, but there are still quite a few things that you could ask Stroustrup about and he'd say "well, just stay away from that, eh..."
Have they fixed SATA support in 2.6.x so that i can use DMA on my drives yet? Thats the only reason i'm using 2.4 vs 2.6. 150megs per sec vs 10megs per sec. Makes a big difference...
If the Kernel is C++, this means the API calls can ALSO be C++ (with some restrictions, of course). This could mean no more kernel-recompiling for loading modules, no more .so recompiling and ending the .os dependancy hell...
What we're talking about is using a whole new computing paradigm in the very core of an operating system. (it may be not new for apps, but for the kernel... just think about it).
As an OOP'er, I'm frankly excited by the idea.
And no, we're not talking about interpreted runtime languages like C# or java. We're talking about the REAL thing.
C++ means that the code will be easier to maintain, changes will be easier to track, and who knows. Perhaps a boost in the development that might JUST be what Linux needs to defeat Winblows as the next Desktop OS.
There is no construct in C++ that you can't do in Visual Basic, or a shell script, or any other Turing-complete language either. That's not the point. C++ isn't there to make writing complicated things possible, it's there to make writing complicated things easier. The easier and more fool-proof a given piece of functionality is, the more work you can get done in a day, and the more code you can write and debug in a year. That is the advantage of C++ over C.
C++ has no concept of "interrupt context", it has no concept of "preemptible
code", it has no concept of per-CPU data structures.
Neither, to my knowledge, does C. Those are both policies that must be followed manually by the programmer -- neither a C++ nor a C compiler will do the work for you there.
I don't care if it's 90,000 hectares. That lake was not my doing.
Don't consider devphil a kernel developer - more like an apologist (first ammendment anyone?). What we're discussing is the worth of the PATCH, not of people who defend it (that would be an ad-hominem attack - similar to the FUD spread by SCO and Microsoft).
So please rephrase your statement.
Current OS kernels created by Linus: 1
Current OS kernel patches created by Gylfason et. al: 1.
That makes it even. Also remember that Linus just gave BIRTH to the Kernel. Hundreds of other programmers nurtured it and made it what it is now (can the Mozilla project, for example, be said to have been made by only one man?)
So please stop idolatring Linus and saying that his word is inspired by God or something. Remember that when he designed Linux, he was trying to improve an existing OS. Who says that nobody can improve his work? Let them try, if it succeeds, it'll be "A better Linux than Linux", just as Linux was "A better Minix than Minix".
I'm sure that Linus' ideas were revolutionary at his time - but what if he fell short in his design? (GASP! Blasphemy!) Who knows what ideas might have been a huge success had they been implemented in Linux in the first place? (Idea for a poll: If you could go back in time and change something in Linux, what would it be?)
So, at least give the guys from Reykjavík the benefit of the doubt.
(Unless of course you want to patent Linux and forbid all innovations on it)
Most linked lists have been abstracted. In an ugly manner versus the C++ way, but they also take up a heck of a lot less space then the C++ way using a naive implementation (with partial template specialization, you might be able to not use up any extra memory, but I believe the kernel doens't keep pointers to nodes in the lists, they keep the nodes in the list with the void *next being the first element of the structure).
Iterating over the lists is abstracted.
Virtual functions are an essential construct to the linux kernel (see the VFS).
Namespaces would be very, very nice to have in the kernel, but the kernel handles that by prefixes, and by linking everything in a subsystem into one .o and having specific entry points into that .o and then forget the rest of the symbols to avoid symbol collision between subsystems.
Classes aren't strictly necessary. As a general rule, by using opaque types, the Linux kernel gets the same types of encapsulation that the C++ class constructs do via this.
What is needed to improve the Linux kernel, is a language that can allow you to express rules that it needs. Like interrupt context, accessing a per CPU data structure, like recongnizing the locks being misued. Like realizing that you are not using the PCI accessing routines when you should be.
C++ doesn't do any of those things, and thus in my opinion is not an enhancement in any way to implementing it in C. There are several places where C++ does obscure things (read the standard sometime about resolving overloaded functions and types, even the standard writers aren't sure the rules aren't ambigious or handle all cases sanely). Default copy constructors, operator=, operator==, and the sheer number of places where an exception can be throw (read Exceptional C++ sometime), can all cause problems. Most of the really good stuff in C++ like the STL wouldn't be usable, as they don't fit the design requirements for datastructures in the Linux kernel (see all the standard libc stuff that is re-implemented in the kernel).
The tools that Linus is working on (which I've always wanted to write, both for the Linux kernel, and for projects at work), are the types of tools you need. Generate a call graph. Do static flow analysis and see if any rules are violated (did you call something which could call "schedule" where is unsafe). Did you call something that requires you hold a lock, while you don't hold the lock. Those are the types of tools and the functionality that will make the kernel better. More crappy type-checking, templates, and RTTI won't do any good. Generating tools which do the code flow analysis is much, much easier in C then it is in C/C++ code. Those will help generate better higher quality source in a much more measurable way then just allowing C++ to be used in a large body of software that it wasn't designed to be used in.
Kirby
You can do stupid juvenile garble in C too, like rewrite the reserved words with #define macros. You don't because it's dumb and because Linus would laugh his ass off and tell you to throw it away, go read "C for dummies" and try again.
Nobody's forcing you to use C++ features where they would be a bad idea.
Probably because you initially made a broader statement about C++ and C without regard to usability in the kernel. I could quote if for you if you don't want to look back in the thread. The tactic you are demonstrating is frequently known as "moving the goal posts".
Your knowledge of C++ seems passable, but your failure to mention RAII and destructors, and your apparent opinion that exceptions can be thrown willy nilly (with out regard to standard library usage, without regard to allocator usage, etc), makes me wonder if you've thought about everything. My knowledge of the kernel is poor, however, so I'll admit that you might be right that there is no place for C++ in kernels or kernel modules. But, hell, anyone that says "c can do anything c++ can do" as a serious attempt to disparage C++ probably isn't qualified to discuss it.
Also, barring some non-standard C-isms the kernel is probably using, and barring any of the rare non-compatible corner cases, you could take the kernel and compile it today as if it were C++. Then, if there was just one feature that made your life easier, and presuming you had the disipline not to employ paradigms and use C++ features that were detrimental (seems safe) to your requirements, you'd have a win. YMMV
XML causes global warming.
Oh the new patch might support C++ (and Andrew Morton might not mind it), but Linus Torvalds *HATES* C++ for kernel work. Why? Ever see a destructor function unravel a system part of a context switch? Destructor functions tend to run independently of strict programmer control. It's often touted as a feature of the language. With operating systems though, you need strict control. You even need to use GOTO in places where the (c) programming language fails to meet needed the needs of necessary data structures needed in an operating system kernel. C just happens to be the best programming language currently available for operating system design. It's why Microsoft uses it, Sun uses it, IBM uses it, HP uses it, and just about everyone else. Don't expect operating systems to be written in Java any time soon.
Okay, here's one: Built-in constructors and destructors. You can simulate them in C using constructor- and destructor-like functions, but you'll always have to remember to call those functions at the right time, and if you don't, you'll have a bug in your program. With C++ you don't have to worry about that, they are automatically called for you at the proper time.
As an example, here is a pseudo-code snippet that I don't think you will be able to express directly in C:
ObjectRef AllocateNewObject()
{
ObjectRef objRef(new Object);
return objRef;
}
Note that this function uses a nice reference-counting template class to make it practically impossible for the heap-allocated Object to be leaked, because the Object will be automatically deleted by the destructor of the last ObjectRef that points to it. ObjectRefs can be passed around and copied just like any other value type, with no need to worry about leakage.
You can do reference counting in C, but you'll have to scatter manual IncRefCount(object) and DecRefCount(object) function calls throughout your code, and chances are pretty good that you'll eventually forget one someplace and end up leaking memory anyway. Because of C++'s constructors, destructors, and templating, I haven't had a problem with memory leaks in years. I automatically get the correct behaviour every time.
I don't care if it's 90,000 hectares. That lake was not my doing.
For examle, this is "undefined behavior" in both C and C++:
int arr[4];
int i = 0;
arr[i++] = i;
In summary, the existence of "undefined behavior" in the C++ and C standards in no way make the compilers implementing the standards "untrustworthy".
XML causes global warming.
Object-oriented programming is just part of the evil Zionist master plan!
'D' is actually a wonderful language, which would have been the next successor to 'C', had Stroustrup not screwed things up.
'D' is an object-oriented language that takes the best parts of C and C++ and throws away the worst.h
http://www.digitalmars.com/d/
and I'll be a happy camper. Maybe even a happy programmer, too.
(I suppose I'll have to do that myself someday, just to find out.)
.....don't fix it.
Yes, "undefined behavior" means, "this is not a feature of the language; DO NOT EVER DO THIS, EVER!". That is, it's a syntactically valid construct with no semantics attached to it. Since there is no semantic value in the statement, you should never use it. Just for the record, C has undefined behavior as well. Try the defined behavior of "int *px = 0; int x = *px;" for starters.
to gaming in the kernel...
Oh FFS. Who moderated this interesting.
You can write bad code in ANY LANGUAGE.
Read the previous sentence again, to fully understand it. You can write bad code in ANY LANGUAGE.
The rest of your post made no sense. Sorry. You've never even used C++.
ftp://ftp.rocksoft.com/papers/crc_v3.txts everything about crc code.
explain
Apparently being unreadable to anyone but a math expert is in the very nature of the problem.
Well, I agree with you. But what is the point? I mean C++ is _a low level language_ unlike Java, and will perhaps replace Fortran in coming future as the tool for (*cough*) hardcore numerics, feat you cannot expect from both Java and C#. Take a look here.
I would like answer your parent post at the same time. C++ is not an OO language. Currently emphasis is put on templates. Even programming patterns in C++ are not expressed in terms of classes, but rather in terms of templates. Please, comparing Java and the lot to C++ is like comparing apples to oranges.
You can defy gravity... for a short time
C++ can do things that would be very hard to do in C, using C++ without using most of the things in conjunction is just silly. C++ unravels once you say, well, you can't use exceptions, destructors and RAII become less useful (they are syntactically cleaner, but no less assured then below code). If you stop using templates, then operator overload and overloaded functions are just syntatic sugar too.
The first two things most people say you can't use in the kernel, are guess what? Templates and exceptions. Templates, because the sneakily lead to bloat (using more memory then you realize, I know that between that and inlining functions can lead to some huge binaries relative to the work they are really doing), and exceptions for reasons listed below. I've always found that using RTTI is just a design flaw. Inheritence is pretty cool, but again anyone willing to take the time can accomplish single inheritence pretty easily by just pounding out the code. Multiple inheritence isn't too much harder, you just have to resolve the collisions by hand. Virtual inheritience is probably pretty difficult unless you start doing sick twisted things with unions.
Most of the C++ functionality is there and it's all interlocking. Like if you don't want exceptions, constructors and destructors are simple:
Works just fine in my C compiler. RAII can easily be implemented this way, just write a macro for each one that calls the functions you want called, make it take some more parameters if you want.
If you give up exceptions, that's all you need barring the usage of a "goto:". If you use goto you better darn well be aware of it (normally in Linux code, the goto is actually used as the error handler, you jump to the thing that releases all of the things you have allocated so far and exit).
There's a simple example of RAII, memory allocations could be the same.
I see exceptions as non-starter in the kernel for several reasons, adding a throw in any number of places can do a whole slew of nasty things if called in the wrong context, along with the fact that exceptions use up additional stack space with is at a premium in the kernel space (4k or 8k depending on the version, it's a serious overhead if you have lots and lots of threads so getting it to a single page was a goal for a long time).
Plus the kernel wasn't designed for the usage of exceptions, getting it from it's current state, to a state where using exceptions is stable probably not possible in the incremental fashion that Linus would require it to be (lots of small changes that take you slowly closer to being correct is the way to get things past Linus). Just adding exceptions to a normal program in sane fashion is hard, now think about adding it to something that is inheriently multithreaded and has multiple call stacks all of which might deal poorly with catching an exception they've not been programmed for.
Exceptions can't be added willy nilly. They would simplify things a great deal in some cases (but would require re-writting of a ton of core kernel code to conver it all over). The Linux kernel uses "goto:" as a general rule to simplify error handling inside of the function (all error handling goes at the end just before the last return statement, if you have an error, goto error_handler; then the error gets passed back up the call chain, un
I liked some of the ideas there, but it's not happening.
There is one problem though; end-users. As long as they are concerned, it doesn't matter what language the kernel is written in, only speed matters. So even if using C++ is only 0.1% slower than using C, but much nicer to use and maintain, then it's still a loss for the end-user.
Incorrect. If you get a CannotReadMoreException while running the code snippet the GP gave, you have no idea whether or not "string" has an appropriate semantic value -- Note that it was declared in another scope and may even have had other values assigned to it! You can mitigate this type of thing slightly by having appropriate destructors for the variables in question (and never using pointers directly!), but handling this is a lot more tricky than it seems at first. This is in fact one of the reason exceptions suck: they hide a lot of the context of which an operation failed. If you want to know which operation failed, you have to have try { } blocks around each operation and you have to introduce more scopes simply because of the way statement sequences work. This makes code incredibly ugly, which is why many people don't do it, leading to subtle bugs.
There are lots of things which simplify error handling in C++ (like destructors for automatic variables), but I have this sneaking feeling that strengthening the data types of C (or C++ for that matter) into having types like "Success $RESULT" and "Failure $SOMETHING" and forcing people to looking at return values might have a much greater effect and be more readable in the end...
HAND.
Making C-programmers write C++ is not the way to make stuff easier.
If you want to write C++, go ahead. But keep it out of the kernel, which is written an maintained by mostly C-prople.
G++ is part of GCC.
...as long as kernel hackers use the best bits of C++ (default parameters, OO paradigm, late declaration of local variables, const correctness), and leave out everything that could cause problems (virtual functions, inheritance (especially MI), exceptions).
But that's not going to happen. Give people the tools and they will use them (badly), so we'll end up with a flurry of rejected patches and signal/noise ratio will plummet.
Stick to C.
"If someone tells me that they are a C/C++ programmer, I'm going to assume they're a novice at both languages."
Thats an assanine statement to make. I've been a professional programmer for 11 years, most of that doing C AND C++. Yes thats using both languages or a mixture of the 2 depending on what project I've worked on. And I'm quite happy doing either high level OO template programming (C++) or low level boolean bit operations, memory management, function pointers etc (C). Most people I know who do C/C++ would have the same ability and most people I've interviewed myself I would expect the same off. If they can't handle malloc & free they're as useless to me as if they can't handle temaplates.
"in my head I know that the interview is probably already over."
Then I suspect you're probably responsible for your company not hiring a lot of good people since you obviously have an arrogant attitude and give the impression that only you can be master of both. If you worked for me I'd never let you near an interview room.
C++ is transparent - to anyone who understands the language.
;)
;)
Just like C is transparent to anyone who understands the language.
Neither language is transparent to those who do not understand. "Det er da ikke så svært at forstå, er det?" (see what I mean
Read:
C vs C++
written by yours truly.
The major points in that article in relation to C++ in the kernel will be
*) Rewriting good C to C++ will be bad C++ and that's not a change to the better
*) Few (good kernel-) developers understand C++ or are willing to learn
However, it is interesting to see that Linus is working so much with the SParse tool - which, really, is just a type checking tool allowing to check annotated C types more strictly than the C language itself allows. This is one of the major benefits you get from C++ (and you can get this benefit with *zero* overhead compared to C - the stricter type system does not force you to use features that have overhead). Instead of developing SParse and running type checking in two steps (first the C compiler, then checking with SParse), they could move to C++ and have it all (and then some) in one go.
But again; I don't think rewriting the kernel to C++ would be reasonable - however, if you start up a new kernel project today, you'd be insane not to go with C++.
My 0.02 Euro on that one
Object-oriented programming is an exceptionally bad idea which could only have originated in California. (Edsger Dijkstra)
C solves the same problems as C++. It makes different methods of solution easier.
In many problems, the best solution is a procedural function. In some, it is an OO design. I've written polymorphic functions (badly, admittedly) in Fortran 77 with VAX extensions %REF and %LOC. C++ makes it *easier* to do this.
One of the cardinal sins of the new C++ programmer is making *everything* an object. Makes the program impossible to debug.
Two things bug me, though, in combination:
Function Overloading is NOT recommended for the New/Delete functions. That is the ONE place I would see great benefit from overloading. You can write your own pooling mechanism, ad reference counts and so on by overloading the new and delete function. Why not?
You miss what is probably the biggest advantage of C++ (and possibly one of the most controversial).
Templates allow for some incredibly slick code, and vastly improve both programmer productivity and type safety.
nt
OK, I skipped C out completely and went straight to C++. So my knowledge of pure C is pretty shaky. One (overly long) question:
Say (for example) I have a program that needs to access, as flat files, data stored in several different formats, each requiring different access methods. I want to minimise the amount of code, obviously. So in C++, I write:
- a File class with the common code and interface (read_data,write_data,open etc)
- derived subclasses for each type of file that actually does the reading/writing(DatbaseFile, VFSFile etc.)
- a manager class that only knows about File classes, not the subclasses
- some factory class that returns an object of the correct File subclass
That way, I keep most of the file access code generic and all the filetype specific code is in one place.
My question is: what is the equivalent of this in C? AFAIK, you'd have to either use switch statements everywhere or some kind of function pointer system. Is there a better alternative? I assume there must be, and I just don't know enough C.
I really hope this gets somewhat modded up.
There IS an OS kernel that is written in pure java - and it actually makes sense!
It is developed at my university in Erlangen/Germany and called JX.
http://jxos.org/
At first I also thought "Bah, screw it". But more interesting is the DESIGN and the on-the-fly merging of domains, which I consider the most interesting _concept_ ever!
Please see their website for actual implementation designs and benchmarks.
Sorry, you are right. It was MVS that I saw. damn transpositino
I prefer the "u" in honour as it seems to be missing these days.
I think it's unreasonable -- and dishonest -- to say that <some tool I have no relevent experience with> is untrustworthy.
You cannot apply a technological solution to a sociological problem. (Edwards' Law)
So does C, and every other language derived from it. That changes nothing.
You cannot apply a technological solution to a sociological problem. (Edwards' Law)
OO paradigm yes, virtual functions no? Stick to C.
A question that occured to me while reading the article:
Why are C++ compilers normally using string comparison on type checking? The taken approach of pointer comparison seems to be the logic choice in the first place, so I wonder why this is often done the other way.
I remember something about linking and shared libraries, but an obvious problem doesn't come to mind...
I think this discussion is missing the point. The only true computer language is Lisp! C++ is teh sux0rz!!1!
My new
> This will compile to an indirect-branch (to figure out which class to use at run-time)
Not necessarily. If you implement your call as virtual and give your function a class pointer, then of course that is what will happen. In C you would have to do the same thing for similar functionality. But you do not have to do this. An non-virtual inline operator= will always produce a simple or and store, just like the original C code. The difference is that you have now abstracted the interface from implementation and can substitute another implementation without changing the original code. That is what C++ is all about and it is an enormous benefit if you ever need to modify your code.
> The point is that people like you delight in
> creating gadget interfaces, and avoid minimal,
> repetative, direct programming designs.
A good "gadget" interface will produce your "minimal, repetetive, and direct" code, but with less effort. More abstraction does not necessarily lead to more code. Consider the following:
class CDevice {
public:
CDevice (SOMEREG_ptr* pRegs) : m_pRegs(pRegs){}
inline void EnableFeatureX (void) { *m_pRegs = BIT_A | BIT_B; }
private:
SOMEREG_ptr m_pRegs;
};
CDevice dev (GetDeviceRegs());
dev.EnableFeatureX();
This code will compile to a copy to a local variable (the constructor), an OR and a memory store, just as your original code did. There is absolutely no extra overhead. But now you see exactly what the code wants to do. BIT_A and BIT_B do not necessarily mean much, and you would have to add comments all over the place. In C++ the code can be much more self-explanatory, which means that maintainers would not have to dig through documentation as much. And then consider what happens if you have to add |BIT_C to EnableFeatureX. If you wrote this in C (which normally does not support inline functions), you would have to change every occurence of setting BIT_A and BIT_B. In the C++ implementation you change it in one place and you are done.
It's interesting
OK, you are right, there seems to be really not much happening on both Blitz and Pooma homepages. And of course Fortran is oriented towards HPC, that's obvious, and is much easier than C++. What I wanted to say is, perhaps, that C++ _could potentially_ replace Fortran as the high performance computing language of choice, whereas Java still cannot and it does not seem that it will in near future. Therefore ,in my opinion, people comparing Java to C++ in terms of performance are comparing apples to oranges.
You can defy gravity... for a short time
s/function overloading/function overriding/
s/operator overloading/function overloading/
If you're refering to Linus, he does have experience with G++. I'd also point out that Linus does (deliberately) overstate arguments on LMKL. He may not have said that quote you're reacting to "with a straight face".
I happen to have been reading Stroustrup on the History of C++ recently, and he is the one that paints C++ this way.
so fuck you unread bigot.
did I mention fuck you?
C++ is an improved C, choke on it. read a book.
-pyrrho
I like the forumlation that it throws C in an OOP direction, except that the STL isn't oop, and strong typing isn't OOP, although it's realated.
Seriously, read History of C++ and you will understand the lengths gone to to make C++ C v2.0 compared with... Objective C, etc. etc. etc.
None of this means the C++ IS Cv2.0, it's not (that would be ANSI C), and maybe there are even better languages that could be C v3.0... but I won't hold my breath waiting for you to create it.
-pyrrho
Seriously. The fact that one can simply build and install a Linux kernel and _already_ have all the drivers required is IMO very important.
I really don't like the idea of having to go online and download drivers, and if the drivers were availible as another bundled download, really what would be the point?
Anyway, I don't really see how separating drivers from the kernel core could make sense given the Linux development policy on stable driver APIs (that is, there aren't any).
Stroustrup et al took great care to make sure the C++ be able to solve all the same problems as C, even to the degree that C code compiles pretty much unaltered (a couple exceptions, generally regarding typing issues).
C-style is ONE OF THE PARADIGMS available in C++, and if you use it, you get no "C++" overhead. That's by design. Please note all the other languages that DON'T take that approach. It wasn't an accident.
-pyrrho
meaning without the OOP stuff.
function polymorphism is one of the main advantages to writing C-style in C++. It's nice to share the name of the function but have versions that take different arguments.
-pyrrho
and why did these C++ features keep making it back into C?
The answers have been available in print for more than ten years.
sorry, that other guy got me worked up.
-pyrrho
"this is not a feature of the language; DO NOT EVER DO THIS, EVER!"
That's a gross overstatement. You don't write stuff like kernels without going UB.
#include <kernel.h> is undefined behaviour.
if (p<q) is undefined behaviour if p and q are pointers and don't point to the same "address space".
type-punning is usually an undefined behaviour.
casting a function pointer to a void pointer is undefined behaviour.
int __foo is undefined behaviour.
poking data at random memory addresses is undefined behaviour.
Even in system-dependent modules. UB is UB is UB.
I assume there is some terminological collision here.
"templates" in C++ refers to it's typesafe generic programming...
-pyrrho
you just lowered my blood pressure. :)
-pyrrho
it's true.
C++ is multiparadigmed.
You can use pointers. But you can also adopt a standard where you do not have to use pointers (generally you will manipulate pointers at lower levels, say in class libraries you make or purchase). You can't adopt a "pointerless paradigm" for an application project, and then go use pointers.
You can use printf style string building and stream style, but it's better to choose one and use it.
RTTI: yes... and if you grant that some projects really do need/want RTTI, then this is a conflict with the possible paradigm of relying only on compile time type checking.
You can have a paradigm where constructors cannot fail... i.e. you can set defaults and prepare your class, but you might avoid mallocing or attaching to streams, etc., in your constructor, instead putting that into an "init" type function. That's legit, it's also legit to do it in constructors (assuming you don't mind using exceptions to handle errors in the constructor), but doing both in one project is not a clear approach. Goto is available in C++... and you might use an old fashioned error handling system using goto:, exceptions are probably better, but the former is still legal C++ and if used for whatever reason, should not be mixed also with using exceptions sometimes, and goto at others.
All of this comes from the fact that C++ is designed to give options to the programmer. And many of these options are contradictory, if not literally incoherent when used together, use of them together shows a lack of design, show that there is no design, or at least that there is a mixed and therefore unclear standard at use in the code.
-pyrrho
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.
but what I said is still true. That sort of thing has been kept for a minimum.
It's legit to say "not minimum enough" and my OOPers would happilly say compatibility is "way too minumumly broken", but there is no doubt that there has been a very real attempt to keep it as minimal as possible.
-pyrrho
or maybe it was a different set of mistakes!
a continuation of it is ideal
it is evolution which has been drivien
-pyrrho
It is simply a matter of how eager the evaluation is, but the table can be generated prior to execution if the predicates are known at compile time. If you dislike how efficient the tabling mechanism is in, say, XSB prolog, then you always have the option of building an optimizer for a particular machine.
Seastead this.
Obviously, you are not going to be convinced until I go and actually write a C++ compiler. Of course, that is the only answer possible these days to any software problem. Linux has no desktop? Quit complaining and go write one! Linux has no games? Shut up and go write one! C++ compilers are impossible? Why don't you go and write one! Yes, proof by accomplishment really is incontrovertible, but it is sad that it is the only one left. Sure I can write a few good programs, and I am, but it will take many years for me to write everything, even if I were interested enough to try. What I wonder, is why am I the only one charged with this task? Why doesn't somebody else say "It can be done!" and do it? Where are the confident people who do instead of profess the impossibility of doing? Where will the world go if it is overrun by the latter?
If you were to say a computer's instruction set was not a mathematical object, you would hear objections from mathematicians like Alan Turing.
If you were to say a computer's circuitry was not a mathematical object, you would hear objections from mathematicians like George Boole.
Seastead this.
Encapsulation is useful indeed, but OO it doesn't make. Ada has encapsulation, but nobody calls it OO. "Virtual functions" is a fancy name for a table of function pointers. It's a useful method of managing your control flow, and one that is used in the kernel as well, nothing new here. An object with an integer type field is just as big as one with a pointer to vtbl, you chose one or the other.
Quine, in his essay "The Scope of Logic" says the identity predicate x=y is inherent in the very idea of predicates.
Given the predicate P(x1,x2,x3,...xN), a "Quine identity" P(A=B) is the conjunction:
For all x2,x3,...xN ( P( A ,x2,x3,...xN) iff P( B ,x2,x3...xN) & ,x3,...xN) iff P(x1, B ,x3...xN) & ...xN ( P(x1,x2, A ,...xN) iff P(x1,x2, B ...xN) &
...
For all x1, x3,...xN ( P(x1, A
For all x1,x2,
For all x1,x2,x3,... ( P(x1,x2,x3,... A ) iff P(x1,x2,x3... B )
Tom Etter (yes, the author of Racter) posits three predicates about which nothing is presumed except that they are Quine identities:
Row(x=y)
Column(x=y)
Value(x=y)
Mathematics is now expressible with no further primitives.
FOR INSTANCE:
See The Expressive Power of Equality for a proof that three identities are sufficient to express Zermelo-Fraenkl set theory.
Seastead this.
what you are suggesting is more along the lines of emulating the linux syscall API and scheduling model as a replacement set of APIs for java code (the ported linux userland programs).
That'd be really strange to behold, and the amount of work recoding everything in java would be enormous. Not to say you couldn't emulate it all from a non-developers' user's perspective, but the source code itself would be shockingly different.
THIS THING CAN TURN ON A DIME, MACROSSZERO STYLE ALSO FUCK BETA, ~NYORON
It does not follow, however, that r such that r(x=z) if and only if Epq(x,z).
has the existential quantifier before the 'r' in the original pdf, so I should have transcribed it as:
It does not follow, however, that there exists an r such that r(x=z) if and only if Epq(x,z).
Seastead this.
and you need to choose one for your project and stick with it.
if you do choose a C style paradigm (a paradigm easily available in C, that is)... why not add to that some of the Better C in C++? Like polymorphic functions, default arguments, generic functions, better static typing, all of which introduce no inefficiencies (at least no more than making efficiency mistakes in regular C does).
Even simple classes as structures with constructors and destructors are easy to use such that they don't introduce inefficient or "hidden" code.
-pyrrho
One problem with your analogy is that all those languages are (approximately) equally expressive, ie. sentences are not disproportionately more complex in one language over another when expressing the same ideas. However, if there was another easily spoken language which allowed you to condense the story without losing detail/content, wouldn't you use it?
This is just one fundamental difference between programming languages and natural languages.
HAND.