Date: Mon, 16 Feb 2009 16:56:02 +1100 From: Andrew Reilly <andrew-freebsd@areilly.bpc-users.org> To: Christoph Mallon <christoph.mallon@gmx.de> Cc: Marcel Moolenaar <xcllnt@mac.com>, Andriy Gapon <avg@icyb.net.ua>, Bruce Simpson <bms@incunabulum.net>, freebsd-current@freebsd.org Subject: Re: weeding out c++ keywords from sys/sys Message-ID: <20090216055602.GA70145@duncan.reilly.home> In-Reply-To: <49986ABB.5040207@gmx.de> References: <4995BB1B.7060201@icyb.net.ua> <20090213231513.GA20223@duncan.reilly.home> <4997F105.5020409@icyb.net.ua> <499811DF.6030905@incunabulum.net> <20090215151318.0d17bfb9@ernst.jennejohn.org> <499835BE.3000705@gmx.de> <8EF8771C-76D8-4556-96B2-B97B35573CBD@mac.com> <49986ABB.5040207@gmx.de>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, Feb 15, 2009 at 08:19:23PM +0100, Christoph Mallon wrote: > There is no fairy which magically makes code appear everywhere. All code > which gets generated is clearly defined by the programmer: You write > code for constructors and destructors. All inserted code is placed at > the boundaries of life ranges of objects. When an object is created its > constructor is called, when it is destroyed its destructor is called. > The compiler keeps track where exactly the life ranges of objects begin > and end and properly inserts the code there. The programmer determines > the life ranges of the objects either by new/delete, aggregating objects > in classes or creating local objects in function {} scope. The problem with C++ isn't really the functions that it provides, it's the functions that it doesn't. Personally, I'd like C++ a *lot* better if it required a garbage collecting runtime. The problem with the way it works at the moment is that object creation interacts with argument promotion and constructors (and C++'s ability to grab references inside the guts of objects, whch it inherited from C) in such a way that you can have temporary object creation inserted by the compiler in the middle of an expression, with no way to ensure that the resulting object is reaped at the right time. And that's because the compiler can't, in general, know what is the right thing to do: if the called function retains the reference in a long-lived structure then the temporary should be constructed on the heap, and explicitly freed somewhere else. If it isn't retained, then the temporary object should be collected as the expression scope is exited. Since there's no way for the compiler to make that call, you almost inevitably wind up with either memory leaks or you constrain yourself to operate with a restricted, not-quite-object-oriented style, which can't really be enforced by the compiler. I don't need to mention what a bad idea memory leaks are in kernel mode, right? > There is no way to have a resource leak here: No matter how the > constructor is left (regular return or exception), the lock is released > via the destructor of the LockHolder. Also if any of the constructors of > A, B or C throws an exception all objects created till this point are > properly destroyed by the destructors of the auto_ptr<>s (per language > specification in the reverse order of declaration in the class). > I consider this a improvement: The code is more concise and writing it > is less error prone. I'll admit that my working knowledge of C++ pre-dates auto_ptr<>s. (And they seem strangely absent from the C++ code that my coleagues write: not sure what that means.) It's possible that there is now enough runtime smarts to avoid the problems I mentioned, above. If so, I'd like to know about it (but not enough to actually go and look it up...) > Writing the code correctly once is still in the hands of the programmer. > Copying the code where it is needed now is the job of the compiler. The > compiler can do the more tedious parts and in this way help the programmer. The problem is that it is not always obvious (particualry when there can be promotion of arguments through non-default copy constructors) exactly where the compiler's magic is invoked in C++. Almost everything is always explicit in C, and IMO that's a significant benefit. > Whew, this got longer than intended. Hopefully I could point out one of > the benefits of C++. Please bear in mind this is no anti-C campaign. I > just want to point out that C++ provides mechanisms to help writing > better code. Frankly, I'd really quite like to see something like a Java subsystem built in. Sure, you don't want to pull in the whole huge standard library (restriction of subsetting by licencing has always been Java's main drawback, IMO), but as you say: there are often places where simpler construction of safe code is a benefit in and of itself. Maybe C++ is a useful step in that direction, but I just don't think so. The age and seeming dead-end-ness of the LinuxCXX project reference that was posted here would seem to argue so. On the other hand, both eCos and OK-L4 (and some other L4 implementations) are in C++, so clearly it can be made to work under some circumstances. On the other, other hand, Eiffel is a language with all of the safety and object-orientation (including multiple inheritance and generic containers) of C++. Device drivers and low-level code have been written for quite a few things (HP laser printers were the pin-up for a while). There are implementations that compile through C as an intermediate language, so integration and portability shouldn't be too much of a stretch. Importantly, Eiffel has always required garbage collection, so issues of collection responsilbility and leakage don't arise. If Eiffel seems too complicated (or ill, if not dead) then Modula3 has some history within FreeBSD and has most of the same plusses (but not multiple inheritance). [Sorry: I shouldn't have commented. I'm a bit of a language junkie. I just think that C++ was mostly a wrong turn in the language design space.] Cheers, Andrew
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20090216055602.GA70145>