Re: C++ pushback

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Kyle Moffett wrote:

And that breaks a _massive_ amount of kernel code, including such core functionality like SPIN_LOCK_UNLOCKED and a host of others. There are all sorts of macros that use member initialization of that form.

This does not break the code at run time, this breaks the code at compile time, and should be less painful.

So breaking 90% of the source code at compile time is ok? I think not. The kernel relies really _really_ heavily on such structure initializers, and breaking them would effectively break the world as far as the kernel is concerned.


Since we're now discussing how to effectively port the kernel to C++, I'd suggest getting g++ to accept these structure initializers, and move them incrementally to standard C++ code.

Should be similar to the conversion to C99 initializers.


I agree, it would be a bad idea to compile the existing C code by g++. The good idea is to be able to produce new C++ modules etc.

No, this is a reason why C++ modules are _not_ a good idea. If you could write the module in C or C++, but in C++ it compiled 100-200% slower, then you would write it in C. Why? A simple matter of numbers:

Say it takes you 100 hours to write and debug the module in C++, and 140 to write and debug it in C. I estimate that at least 200,000 people would download and compile a single version of the kernel with your module (not an unreasonable estimate). Note that I'm not even including the people who do repeated regression testing of versions, or people who download and compile multiple versions of the kernel. If the source file takes an average of 1.0 seconds to compile in C and 2.0 seconds to compile in C++, then:

(2.0 sec - 1.0 sec) * 200,000 = 200,000 seconds = 55.6 hours
140 hours - 100 hours = 40 hours
40 hours < 55.6 hours

So for a single version of the kernel your module, you've already wasted 15.6 hours of time across people using it. Over time that number is just going to grow, _especially_ if people start writing more and more modules in C++ because they can. If you want to build C++ in the kernel, write a compiler that does not include all the problematic C++ features that add so much parsing time (overloaded operators, etc).



It looks like you don't value your time much. You're comparing human time (yours!) to machine time.

If we accept your 1.4 C++ vs C factor, then these 200,000 people would be compiling 2.6.24 instead of 2.6.16.12.

(Of course, not all code benefits equally from C++. I'd guess the VM internals wouldn't benefit as much, filesystems and drivers benefiting a lot).

C++ compilation isn't slower because the compiler has to recognize more keywords. It's slower because it is doing more for you: checking types (C++ code is usually free of void *'s except for raw data) and expanding those 4-line function to their 14-line goto-heavy equivalents.



You mentioned a bad example. The struct list_head has [almost?] all "members" inlined. If they were not, one could simply make a base class having [some] members outlined, and which class does not enforce type safety and is for inheritance only. The template class would then inherit the base one enforcing type safety by having inline members. This technique is well known, trust me. If you need real life examples, tell me.

Ok, help me understand here: Instead of helping using one sensible data structure and generating optimized code for that, the language actively _encourages_ you to duplicate classes and interfaces, providing even _more_ work for the compiler, making the code harder to debug, and probably introducing inefficiencies as well. If C++ doesn't work properly for a simple and clean example like struct list_head, why should we assume that it's going to work any better for more complicated examples in the rest of the kernel? Whether or not some arbitrary function is inlined should be totally orthogonal to adding type-checking.

C++ works excellently for things like list_head. The generated code is as efficient or better that the C equivalent, and the API is *much* cleaner. You can iterate over a list without knowing the name of the field which contains your list_head (and possibly getting it wrong if there is more than one).



For #defines core_initcall() ... late_initcall() I would type something like this:
    class foo_t { foo_t(); ~foo_t(); }
    static char foo_storage[sizeof(foo_t)];
    static foo_t& foo=*reinterpret_cast<foo_t*>(foo_storage);
    static void __init foo_init() { new(foo_storage) foo_t; }
    core_initcall(foo_init);

This ugly-looking code can be nicely wrapped into a template, which, depending on the type (foo_t in this case), at compile time, picks the proper stage for initialization.

You proved my point. Static constructors can't work. You can add silly wrapper initcall functions which create objects in static memory at various times, but the language-defined static constructors are yet another C++ feature that doesn't work by default and has to be hacked around. C++ gives us no advantage over C here either. Plus this would break things like static spinlock initialization. How would you make this work sanely for this static declaration:

spinlock_t foo_lock = SPIN_LOCK_UNLOCKED;

Under C that turns into (depending on config options):

spinlock_t foo_lock = { .value = 0, .owner = NULL, (...) };

How could that possibly work in C++ given what you've said? Anything that breaks code that simple is an automatic nonstarter for the kernel. Also remember that spinlocks are defined preinitialized at the very earliest stages of init. Of course I probably don't have to say that anything that tries to run a function to iterate over all statically-allocated spinlocks during init would be rejected out of hand.


Why would it be rejected?

A static constructor is just like a module init function. Why are modules not rejected out of hand?


--
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 [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux