Skip site navigation (1)Skip section navigation (2)
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>