mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Michael de Lang <kingoipo@gmail.com>
To: "Enrico Weigelt, metux IT consult" <info@metux.net>,
	"H. Peter Anvin" <hpa@zytor.com>,
	David Howells <dhowells@redhat.com>,
	linux-kernel@vger.kernel.org, pinskia@gmail.com
Subject: Re: [PATCH 00/45] C++: Convert the kernel to C++
Date: Fri, 12 Jan 2024 22:58:41 +0100	[thread overview]
Message-ID: <d535f0b5-7319-4a21-a002-eb4074758c22@gmail.com> (raw)
In-Reply-To: <69fe1c0c-b5ec-4031-b719-d9c14742929c@metux.net>

Thanks for your reply.

>> Namely, to prevent stagnation for the Kernel as well as continue to be 
>> interesting to new developers.
> 
> Which stagnation are you talking about, exactly ?

While I do not know what Linus was exactly thinking about when he 
mentioned stagnation, I assume he was looking at it from the lens of 
long-term maintainers. I'm basing this on the 2021 discussion on lwn: 
https://lwn.net/Articles/870581/. Obviously there are plenty of 
contributors every kernel release and while I don't have any numbers 
there, I don't think # of contributors or # of contributions is an issue.

Still, the idea of C discouraging people to contribute resonates with 
me. That is largely based on subjectivity so feel free to ignore it.

> 
> While I've got a long list of ideas for modernizing the kernel
> (which I'm lacking time to actually work on), I'm unsure whether
> C++ really would be of much benefit. Especially considering that for
> many things there's no way to know / define how things will really
> look like on binary level.

Do you have any examples on what exactly in C++ obfuscates the resulting 
binary? Everything I can think of, also applies to C: anything 
implementation-defined, e.g. struct layout, high-order bit propagation 
for shift operations,

There are things in the STL that are implementation defined, but the 
proposal excludes the STL.

> Personally, the opposite had been one my primary reasons.
> Because it's so simple to understand - in contrast to the usual C++
> monster's i've seen so often in the wild. (I usually try to keep far
> away from C++ projects). 

I have never understood the sentiment that C is supposedly simple. 
Looking at the macros used in the kernel is one obvious big argument 
against using C, as macros can be considered their own 
language-inside-a-language. Another big argument against the sentiment 
is the loose type system, where void* casts are everywhere you want to 
do anything remotely type-generic, losing type information and making it 
harder to grok the original intent.

Creating a compiler for C is 'easier' than creating one for C++ (or Rust 
for that matter), but coding in it as a user requires years of 
experience to avoid a lot of the pitfalls. A simple language would be 
something like golang, with its GC and prescribed coding patterns.

C is a language to be (ab)used like any other, the same goes for C++. 
The kernel has shown that it is possible to create maintainable C, I 
feel confident saying that it is also possible in C++.

 > Note that C++ is a very complex language,
 > and w/ STL it's even much, much more complex.

Note that the proposal here is to use C++ without the STL as well as 
apply some other restrictions.

> Can't judge what you see as interesting, but frankly, I really don't
> have it on my list of interesting things - instead would prefer phasing
> C++ out in favour of many other languages.

I could give you concrete examples of C++ language addition examples, 
but I don't think that adds much to the discussion. Many languages, 
including C++, have additions that C does not have and provide benefits 
such as reduced cognitive load, standardised ways to do things 
preventing NIH syndrome and possibly enthuse more people to contribute 
to the kernel.

The biggest merit of using C++ in the kernel is that in comparison to 
other systems language (Zig, Rust, Swift to name a few) it requires the 
least re-skilling of existing contributors. A close second would be the 
low barrier to integrate various C++ and C codebases. Especially when 
taking into account the architectures that the kernel needs to support 
vs the other languages. Even Rust with its big push towards being a 
replacement isn't there yet today (e.g. PA-RISC).

> 
>> other languages, unlike C. The aforementioned metaprogramming is one 
> 
> Metaprogramming can be very interesting indeed - Oberon once made a 
> really good show case, but I wouldn't dare trying that in kernel space.
> And it's hard to do that w/o causing extra performance penalties.

I believe this is a case of having to try it first before being able to 
decisively say anything about the impact. Counter-examples have been 
mentioned elsewhere in the thread.

> 
>> such example, but things like RAII, smart pointers and things like 
>> gsl::not_null would reduce the changes on kernel bugs, especially 
>> memory safety related bugs that are known to be vulnerable to security 
>> issues.
> 
> These are exactly the things I would prefer keeping out of kernel space.
> Indeed there're several areas where it could be nice, but there're
> others where we really can't take it.

As you mention yourself, there are places where such constructs would be 
a boon and places where we should not apply them. I have faith in the 
Kernel processes to weed out using things where they should not, as is 
presumably done already for certain C constructs today.

> 
>> On the other hand, the benefits I mention can also turn into 
>> downsides: if constructs like gsl::not_null are desired, does that 
>> mean that there 
> 
> this seems to be pretty much an assert() - obviously something we really
> cannot have in the kernel.

gsl::not_null prevents constructing a pointer with NULL, ensuring at 
compile-time that it never happens. As such, an assert() would be 
superfluous. It is exactly an example of a C++ construct that has no 
downsides and only upsides.

> 
>> will be a kernel-specific template library? A KTL instead of STL? That 
>> might be yet another thing that increases the steepness of the kernel 
>> development learning curve.
> 
> Most likely we'd need our own kernel specific library. (we also have one
> instead of libc). Some simple pieces might look similar to STL on the
> front, but it would have to be very different from userland.
> 
> At that point, your previous argument about attracting more people
> who're already used to / like C++ breaks down, because it wouldn't be
> that C++ as usual C++ devs know it (IIRC, STL is integral part of the
> standard), but just the core lang plus some very custom template lib.

It's not that the argument breaks down, it's that it applies to a 
smaller, but still greater than 0, target audience. There are plenty of 
C++ programmers out there that disable the STL on purpose: game 
developers, automotive engineers that I know and so on. You're going to 
be hard-pressed to find concrete numbers, but the fact that the EASTL 
and ETL exist shows the proliferation of non-STL C++ and that the STL 
itself is not an integral part of C++. I recommend you check out ETL 
specifically, I'm sure you'll be amazed at how much functionality it 
has, especially geared for the embedded world.

> 
>> Although compiler-specific, C++20 has enabled implementing RTTI 
>> without RTTI as well as (partial) reflection. 
> 
> You name it: compiler specific.
> 
> Is it even specified how this exactly looks at binary level, and methods
> to control the exact binary data structures ?
> 
> The least thing's need to implement such things is some pointer or tag
> inside each struct/object instance - this would change struct layouts!
> Note that we often use structs to reflect HW specific data structures,
> so we'd need a way to have exact control over this. And then we need to
> be very careful on which instances have RTTI and which ones don't.
> I see debugging nightmares on the horizon ...

I could be convinced that RTTI of any sort is just a bad idea in the 
kernel. It is one of the things that is first to be disabled in embedded 
C++ usage, alongside exceptions. Still, it has its uses even in those 
areas, but that's outside of the scope of this proposal I think.

> 
>> On top of increasing the binary size, 
> 
> That's also a huge problem:
> 
> Templates in general have the strong tendency of producing lots of
> duplicated code. That's what they're designed for: expressing similar
> things (that have to be different on binary level) by the same
> generic source code.
> 
> It might be possible to write them in a way they don't increase binary
> size, but that's not entirely trivial, and so the actual gain of all
> of that becomes questionable again.

Hmm, explicit template instantiations are an 'easy' fix to taming the 
code bloat, but any use of templates is going to mean _some_ extra code 
generation. I do not have any concrete Kernel examples here, but I'm 
sure there are switch/case statements somewhere in there that can be 
optimized away by using templates. For those, the question is: code 
bloat or run-time performance?

> 
>> this then becomes a discussion on what requirements the kernel puts on 
>> compilers, as I'm sure that the kernel needs to be compiled for 
>> architectures which have a less than stellar conformance to the C++ 
>> specification. 
> Indeed. Also think about embedded environments, where folks can't easily
> upgrade toolchains (e.g. due regulative constraints)
> 

This argument also applies against using Rust and is directly opposed to 
modern security practices. Updating to the latest version for 
OS/compilers/libraries etc is pretty much a given since UN R155 and UN 
R156 came into effect. Though those apply only to automotive so far, the 
Cyber Resilience Act is going to force manufacturers of all kinds to 
adhere to better security. There is definitely a whole debate we can 
have just on the impacts of these regulations and what that should mean, 
but I've already written a lot ;)

Cheers,
Michael de Lang

  parent reply	other threads:[~2024-01-12 21:58 UTC|newest]

Thread overview: 104+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-01 20:40 David Howells
2018-04-01 20:40 ` [PATCH 01/45] Use UINT_MAX, not -1, to represent an invalid UID, GID or project ID David Howells
2018-04-01 23:04   ` Randy Dunlap
2018-04-01 20:40 ` [PATCH 02/45] Fix exception_enter() return value David Howells
2018-04-05  1:34   ` Sasha Levin
2018-04-01 20:40 ` [PATCH 03/45] Fix loop var in be32_to_cpu_array() and cpu_to_be32_array() David Howells
2018-04-01 20:40 ` [PATCH 04/45] Fix use of ACPI_COMPANION_SET() David Howells
2018-04-01 20:40 ` [PATCH 05/45] C++: Set compilation as C++ for .c files David Howells
2018-04-02  6:10   ` kbuild test robot
2018-04-02  6:10   ` kbuild test robot
2018-04-03 13:16   ` David Howells
2018-04-03 13:27     ` Fengguang Wu
2018-04-10  8:44     ` David Howells
2018-04-10  9:45       ` Fengguang Wu
2018-04-11  1:13         ` Li, Philip
2018-04-01 20:40 ` [PATCH 06/45] C++: Do some basic C++ type definition David Howells
2018-04-02  4:37   ` kbuild test robot
2018-04-02  6:10   ` kbuild test robot
2018-04-01 20:40 ` [PATCH 07/45] C++: Define a header with some C++ type traits for type checking David Howells
2018-04-02  7:00   ` kbuild test robot
2018-04-01 20:41 ` [PATCH 08/45] C++: Implement abs() as an inline template function David Howells
2018-04-01 20:41 ` [PATCH 09/45] C++: x86: Fix the x86 syscall table production for C++ David Howells
2018-04-02  7:57   ` kbuild test robot
2018-04-01 20:41 ` [PATCH 10/45] C++: x86: Turn xchg(), xadd() & co. into inline template functions David Howells
2018-04-01 20:41 ` [PATCH 11/45] C++: x86: Turn cmpxchg() " David Howells
2018-04-01 20:41 ` [PATCH 12/45] C++: x86: Turn cmpxchg_double() " David Howells
2018-04-01 20:41 ` [PATCH 13/45] C++: x86: Turn cmpxchg64() " David Howells
2018-04-01 20:41 ` [PATCH 14/45] C++: x86: Turn put_user(), get_user() " David Howells
2018-04-01 20:41 ` [PATCH 15/45] C++: Need space between string and symbol David Howells
2018-04-01 20:41 ` [PATCH 16/45] C++: Disable VERIFY_OCTAL_PERMISSIONS() for the moment David Howells
2018-04-01 20:41 ` [PATCH 17/45] C++: Turn READ_ONCE(), WRITE_ONCE() & co. into inline template functions David Howells
2018-04-01 20:42 ` [PATCH 18/45] C++: Turn RCU accessors " David Howells
2018-04-01 20:42 ` [PATCH 19/45] C++: Turn ktime_add/sub_ns() " David Howells
2018-04-01 20:42 ` [PATCH 20/45] C++: init/main: Constify pointers David Howells
2018-04-01 20:42 ` [PATCH 21/45] C++: Set the type of atomic64_t to s64 David Howells
2018-04-01 20:42 ` [PATCH 22/45] C++: Define apic_intr_mode after the enum definition, not before David Howells
2018-04-01 20:42 ` [PATCH 23/45] C++: Don't do "extern asmlinkage" David Howells
2018-04-01 20:42 ` [PATCH 24/45] C++: Fix BUILD_BUG_ON_ZERO() David Howells
2018-04-01 20:42 ` [PATCH 25/45] C++: Fix void variables David Howells
2018-04-01 20:42 ` [PATCH 26/45] C++: Can't have variable/member names the same as typedef names David Howells
2018-04-01 20:42 ` [PATCH 27/45] C++: Disable __same_type() for the moment David Howells
2018-04-01 20:43 ` [PATCH 28/45] C++: Move ctx_state enum out of struct context_tracking David Howells
2018-04-01 20:43 ` [PATCH 29/45] C++: Move the print_line_t enum before first use David Howells
2018-04-01 20:43 ` [PATCH 30/45] C++: Include linux/hrtimer.h from linux/timer.h David Howells
2018-04-01 20:43 ` [PATCH 31/45] C++: Avoid using 'compl' and 'and' as names David Howells
2018-04-02  7:57   ` kbuild test robot
2018-04-01 20:43 ` [PATCH 32/45] C++: __to_fd() needs to reduce the size of v for struct fd::flags David Howells
2018-04-01 20:43 ` [PATCH 33/45] C++: Move irqchip_irq_state enum David Howells
2018-04-01 20:43 ` [PATCH 34/45] C++: Fix up use of LIST_POISON* David Howells
2018-04-01 20:43 ` [PATCH 35/45] C++: Fix static_branch_likely/unlikely() David Howells
2018-04-01 20:43 ` [PATCH 36/45] C++: Fix kernfs_type() int->enum David Howells
2018-04-01 20:43 ` [PATCH 37/45] C++: Fix page_zonenum() int->enum David Howells
2018-04-01 20:44 ` [PATCH 38/45] C++: mutex_trylock_recursive_enum() int->enum David Howells
2018-04-01 23:10   ` Randy Dunlap
2018-04-01 20:44 ` [PATCH 39/45] C++: Fix spinlock initialisation David Howells
2018-04-01 20:44 ` [PATCH 40/45] C++: Fix sema_init() David Howells
2018-04-01 20:44 ` [PATCH 41/45] C++: Cast in bitops David Howells
2018-04-02  6:10   ` kbuild test robot
2018-04-01 20:44 ` [PATCH 42/45] C++: Hide C++ keywords David Howells
2018-04-02  7:32   ` kbuild test robot
2018-04-01 20:44 ` [PATCH 43/45] C++: Don't need to declare struct pgd_t after typedef David Howells
2018-04-01 20:44 ` [PATCH 44/45] C++: Can't declare unsized-array in struct cgroup David Howells
2018-04-01 20:44 ` [PATCH 45/45] C++: Move initcall_level_names[] to __initdata section David Howells
2018-04-01 22:20 ` [PATCH 00/45] C++: Convert the kernel to C++ Randy Dunlap
2018-04-02  9:28 ` Vegard Nossum
2024-01-09 19:57 ` H. Peter Anvin
2024-01-09 23:29   ` Andrew Pinski
2024-01-11 21:01     ` Arsen Arsenović
2024-01-10  0:29   ` David Howells
2024-01-10  8:58   ` Jiri Slaby
2024-01-10 13:04     ` Neal Gompa
2024-01-10 15:52       ` Jason Gunthorpe
2024-01-10 16:05         ` H. Peter Anvin
2024-01-10 16:25         ` Neal Gompa
2024-01-10 17:57           ` Theodore Ts'o
2024-01-12  2:23             ` H. Peter Anvin
2024-01-12  2:52               ` Kent Overstreet
2024-01-11  8:06       ` Andreas Herrmann
2024-01-10 15:01   ` Michael de Lang
     [not found]     ` <69fe1c0c-b5ec-4031-b719-d9c14742929c@metux.net>
2024-01-12 21:58       ` Michael de Lang [this message]
2024-01-11  4:24   ` John Hubbard
2024-01-11  5:09     ` Dave Airlie
2024-01-11 15:24       ` Eric Curtin
2024-01-11 21:37       ` David Laight
2024-01-11 12:39   ` Chris Down
2024-01-11 19:40     ` David Laight
2024-01-24  6:53       ` Jiri Slaby
2024-01-12  2:54   ` H. Peter Anvin
2024-01-12  8:52   ` David Howells
2024-01-12 23:53     ` H. Peter Anvin
2024-01-09 23:40 ` David Howells
2024-01-10  7:13   ` Alexey Dobriyan
2024-01-12  2:25   ` H. Peter Anvin
2024-01-12  2:40   ` H. Peter Anvin
2024-01-11 23:09 ` Arsen Arsenović
2024-01-12  9:20 ` David Howells
2024-01-12 21:35   ` Arsen Arsenović
2024-01-12 23:41   ` David Howells
2025-02-27 16:44 ` Convert the kernel to C++: Lock-holding class David Howells
2018-04-01 21:32 [PATCH 00/45] C++: Convert the kernel to C++ Alexey Dobriyan
2024-01-11 10:56 Alexey Dobriyan
2024-01-11 10:58 ` Neal Gompa
2024-01-11 11:12   ` Alexey Dobriyan
2024-01-11 12:12   ` Andreas Herrmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d535f0b5-7319-4a21-a002-eb4074758c22@gmail.com \
    --to=kingoipo@gmail.com \
    --cc=dhowells@redhat.com \
    --cc=hpa@zytor.com \
    --cc=info@metux.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pinskia@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®