Re: [PATCH 00/45] C++: Convert the kernel to C++

From: David Howells
Date: Tue Jan 09 2024 - 18:41:11 EST


H. Peter Anvin <hpa@xxxxxxxxx> wrote:

> Hi all, I'm going to stir the hornet's nest and make what has become the
> ultimate sacrilege.

:-)

> Both C and C++ has had a lot of development since 1999, and C++ has in fact,
> in my personal opinion, finally "grown up" to be a better C for the kind of
> embedded programming that an OS kernel epitomizes.

And gcc got rewritten in C++ some time back, so they have a vested interest.

> > (8) 'virtual'. Don't want virtual base classes, though virtual function
> > tables might make operations tables more efficient.
>
> Operations tables *are* virtual classes. virtual base classes make sense in a
> lot of cases, and we de facto use them already.

You end up adding storage for a 'this' pointer for each virtual base class, I
think - and then you may have extra fun if you inherit from two classes that
both inherit the same virtual base class. Abstract base classes that are just
ops tables are probably fine, though.

> > Issues:
> > (1) Need spaces inserting between strings and symbols.
>
> I have to admit I don't really grok this?

You're not allowed to do things like:

asm volatile("btl "__percpu_arg(2)",%1"

but rather have to do:

asm volatile("btl " __percpu_arg(2) ",%1"

as you're now allowed to specify type qualifiers. See

https://en.cppreference.com/w/cpp/language/user_literal

> > (2) Direct assignment of pointers to/from void* isn't allowed by C++, though
> > g++ grudgingly permits it with -fpermissive. I would imagine that a
> > compiler option could easily be added to hide the error entirely.
>
> Seriously. It should also enforce that it should be a trivial
> type. Unfortunately it doesn't look like there is a way to create user-defined
> implicit conversions from one pointer to another (via a helper class), which
> otherwise would have had some other nice applications.

Might require a compiler option to kill the warning. Inserting all the
missing casts would be a pain.

> > (3) Need gcc v8+ to statically initialise an object of any struct that's not
> > really simple (e.g. if it's got an embedded union).
>
> Worst case: constexpr constructor.

There was also a problem with leaving gaps in static array initialisation and
a problem with statically initialising fields out of order (with respect to
the order they're declared in the struct declaration). Possibly these have
been fixed in g++.

> > (4) Symbol length. Really need to extern "C" everything to reduce the size
> > of the symbols stored in the kernel image. This shouldn't be a problem
> > if out-of-line function overloading isn't permitted.
>
> This really would lose arguably the absolutely biggest advantage of C++:
> type-safe linkage. This is the one reason why Linus actually tried to use C++
> in one single version of the kernel in the early days (0.99.14, if I remember
> correctly.) At that time, g++ was nowhere near mature enough, and it got
> dropped right away.

I know. It depends on how much you want to grow your symbol table by. Given
the number of struct pointers we use, it increases it a lot IIRC. Also, you
might want a demangler for stack traces.

David