Messages in this thread | | | Date | Tue, 25 Apr 2006 10:08:02 +0300 | From | Avi Kivity <> | Subject | Re: Compiling C++ modules |
| |
[de-cc'ed original poster, he's far away by now]
Kyle Moffett wrote: > On Apr 24, 2006, at 17:03:46, Avi Kivity wrote: >> Alan Cox wrote: >>> There are a few anti C++ bigots around too, but the kernel choice of >>> C was based both on rational choices and experimentation early on >>> with the C++ compiler. >> >> Times have changed, though. The C++ compiler is much better now, and >> the recent slew of error handling bugs shows that C is a very unsafe >> language. >> >> I think it's easy to show that the equivalent C++ code would be >> shorter, faster, and safer. > > Really? What features exactly does C++ have over C that you think > make that true? Implicit memory allocation? Exceptions? Operator > overloading? Tendency to use StudlyCaps? What else can C++ do that C > can not? > > For example, I could write the following: > > class Foo { > public: > Foo() { /* ... init code ... */ } > ~Foo() { /* ... free code ... */ } > int do_thing(int arg) { /* ... code ... */ } > > private: > int data_member; > }; > > Or I could write it like this: > > struct foo { > int data_member; > }; > > int foo_init() { /* ... init code ... */ } > int foo_destroy() { /* ... free code ... */ } > int foo_do_thing(int arg) { /* ... code ... */ } > > > The "advantages" of the former over the latter: > > (1) Without exceptions (which are fragile in a kernel), the former > can't return an error instead of initializing the Foo. Don't discount exceptions so fast. They're exactly what makes the code clearer and more robust.
A very large proportion of error handling consists of: - detect the error - undo local changes (freeing memory and unlocking spinlocks) - propagate the error
Exceptions make that fully automatic. The kernel uses a mix of gotos and alternate returns which bloat the code and are incredibly error prone. See the recent 2.6.16.x for examples. > > (2) You can't control when you initialize the Foo. For example in > this code, the "Foo item;" declarations seem to be trivially > relocatable, even if they're not. > spin_lock(&foo_lock); > Foo item1; > Foo item2; > spin_unlock(&foo_lock); They only seem relocatable with your C glasses on. Put on your C++ glasses (much thicker), and initialization no longer seems trivially movable.
On the other hand, you can replace the C code
{ Foo item1, item2; int r;
spin_lock(&foo_lock); if ((r = foo_init(&item1)) < 0) { spin_unlock(&foo_lock); return r; } if ((r = foo_init(&item2)) < 0) { foo_destroy(&item1); spin_unlock(&foo_lock); return r; } foo_destroy(&item2); foo_destroy(&item1); spin_unlock(&foo_lock); return 0; }
with
{ spinlock_t::guard foo_guard(foo_lock); Foo item1; Foo item2; }
14 lines vs 3, one variable eliminated. How many potential security vulnerabilities? How much time freed to work on the algorithm/data structure, not on error handling? > > (3) Foo could theoretically implement overloaded operators. How > exactly is it helpful to do math on structs? It isn't. It's nice for other application domains (matrix algebra, etc.) not for kernels.
This mailing list has a full complement of reviewers who can detect trailing whitespace in a dark room three miles away. Surely they can spot an attempt to sneak in the "operator" keyword. > Does that actually make it any easier to understand the code? How > does it make it more obvious to be able to write a "+" operator that > allocates memory? > Not all C++ features need to be used in the kernel. In fact, not all C++ features need to be used, period. Ever tried to understand code which uses overloaded operator,() (the comma operator)?
-- error compiling committee.c: too many arguments to function
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |