内核开发和 C++

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12385485/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:14:11  来源:igfitidea点击:

Kernel development and C++

c++operating-systemkernel

提问by coredump

From what I know, even though the common OS have parts written in other languages, the kernel is entirely written in C.

据我所知,尽管通用操作系统有部分是用其他语言编写的,但内核完全是用 C 编写的。

I want to know if it's feasible to write a Kernel in C++ and if not, what would be the drawbacks.

我想知道用 C++ 编写内核是否可行,如果不可行,有什么缺点。

采纳答案by DevSolar

This is covered explicitly in the OSDev Wiki.

这在OSDev Wiki 中有明确的介绍

Basically, you either have to implement runtime support for certain things (like RTTI, exceptions), or refrain from using them (leaving only a subset of C++ to be used).

基本上,您要么必须为某些东西(如 RTTI、异常)实现运行时支持,要么避免使用它们(只留下 C++ 的一个子集可供使用)。

Other than that, C++ is the more complex language, so you need to have a bit more competent developers that won't screw it up. Linus Torvalds hating C++ being purely coincidental, of course.

除此之外,C++ 是一种更复杂的语言,所以你需要有更多能干的开发人员,不会把它搞砸。当然,Linus Torvalds 讨厌 C++ 纯属巧合。

回答by marko

There are plenty of examples of well-used operating systems (or parts of them) implemented in C++ - IOKit - the device driver subsystem of MacOSX and IOS is implemented in EC++. Then there's the eCOSRTOS - where the kernel is implemented in C++, even making use of templates.

有很多使用 C++ 实现的操作系统(或其中的一部分)的例子 - IOKit - MacOSX 和 IOS 的设备驱动子系统是在EC++ 中实现的。然后是eCOSRTOS - 内核是用 C++ 实现的,甚至使用模板。

Operating systems are traditionally awash with examples of OO concepts implemented the hard way in C. In the linux device model kobjectis effectively the base-class for driver and device objects, complete with DIY v-tables and some funky arrangements implemented in macros for up and down-casting.

操作系统传统上充斥着以 C 语言艰难实现的 OO 概念的例子。在 linux 中,设备模型kobject实际上是驱动程序和设备对象的基类,包括 DIY v-tables 和一些在宏中实现的时髦安排,用于 up 和向下铸造。

The Windows NT kernel has an even more deeply rooted inheritance hierarchy of kernel objects. And for all of the neigh-sayers complaining about the suitability of exception handling in kernel code, exactly such a mechanism is provided.

Windows NT 内核具有更加根深蒂固的内核对象继承层次结构。对于所有抱怨内核代码中异常处理的适用性的反对者,提供的正是这样一种机制。

Traditionally, the arguments against using C++ in kernel code have been:

传统上,反对在内核代码中使用 C++ 的论点是:

  • Portability: availability of C++ compilers for all intended target platforms. This is not really an issue any more
  • Cost of C++ language mechanisms such as RTTI and exceptions. Clearly if they were to be used, the standard implementation isn't suitable and a kernel-specific variant needs using. This is generally the driver behind the use of EC++
  • Robustness of C++ APIs, and particularly the Fragile base-class problem
  • 可移植性:适用于所有预期目标平台的 C++ 编译器的可用性。这不再是一个真正的问题
  • RTTI 和异常等 C++ 语言机制的成本。显然,如果要使用它们,则标准实现不合适,需要使用特定于内核的变体。这通常是使用 EC++ 背后的驱动程序
  • C++ API 的健壮性,尤其是脆弱的基类问题

Undoubtedly, the use of exceptions and RAIIparadigm would vastly improve kernel code quality - you only have to look at source code for BSD or linux to see the alternative - enormous amounts of error handling code implemented with gotos.

毫无疑问,异常和RAII范式的使用将极大地提高内核代码质量——你只需要查看 BSD 或 linux 的源代码就可以看到替代方案——大量的错误处理代码是用gotos实现的。

回答by SeventyFive

To address Torvalds' concerns and others mentioned elsewhere here: In hard-RT systems written in C++, STL/RTTI/exceptions are not used and that same principal can be applied to the much more lenient Linux kernel. Other concerns about "OOP memory model" or "polymorphism overhead" basically show programmers that never really checked what happens at the assembly level or the memory structure. C++ is as efficient, and due to optimized compilers many times more efficient than a C programmer writing lookup tables badly since he doesn't have virtual functions at hand.

为了解决 Torvalds 的担忧和其他地方提到的其他问题:在用 C++ 编写的 hard-RT 系统中,不使用 STL/RTTI/异常,并且相同的原则可以应用于更宽松的 Linux 内核。其他关于“OOP 内存模型”或“多态开销”的担忧基本上表明程序员从未真正检查过汇编级别或内存结构发生了什么。C++ 也同样高效,并且由于优化的编译器比 C 程序员编写查找表的效率高很多倍,因为他手头没有虚函数。

In the hands of an average programmer C++ doesn't add any additional assembly code vs a C written piece of code. Having read the asm translation of most C++ constructs and mechanisms, I'd say that the compiler even has more room to optimize vs C and can create even leaner code at times. So as far as performance it's pretty easy to use C++ as efficiently as C, while still utilizing the power of OOP in C++.

在普通程序员的手中,与 C 编写的代码相比,C++ 不会添加任何额外的汇编代码。阅读了大多数 C++ 构造和机制的 asm 翻译后,我想说编译器甚至比 C 有更多的优化空间,有时甚至可以创建更精简的代码。因此,就性能而言,使用 C++ 和 C 一样高效,同时仍然利用 C++ 中 OOP 的强大功能非常容易。

So the answer is that it's not related to facts, and basically revolves around prejudice and not really knowing what code CPP creates. I personally enjoy C almost as much as C++ and I don't mind it, but there is no rational against layering an object oriented design above Linux, or in the Kernel itself, it would've done Linux a lot of good.

所以答案是它与事实无关,基本上围绕偏见而不是真正了解 CPP 创建的代码。我个人喜欢 C 几乎和 C++ 一样多,我不介意,但是没有理由反对在 Linux 之上分层面向对象的设计,或者在内核本身中,它会给 Linux 带来很多好处。

回答by Rook

You can write an OS kernel in more or less any language you like.

您可以或多或少地使用您喜欢的任何语言编写操作系统内核。

There are a few reasons to prefer C, however.

然而,有几个理由更喜欢 C。

  • It is a simple language! There's very little magic. You can reason about the machinecode the compiler will generate from your source code without too much difficulty.
  • It tends to be quite fast.
  • There's not much of a required runtime; there's minimal effort needed to port that to a new system.
  • There are lots of decent compilers available that target many many different CPU and system architectures.
  • 这是一种简单的语言!很少有魔法。您可以毫不费力地推理编译器将从您的源代码生成的机器码。
  • 它往往很快。
  • 没有太多必需的运行时;将其移植到新系统所需的工作量很小。
  • 有许多不错的编译器可用,它们针对许多不同的 CPU 和系统架构。

By contrast, C++ is potentially a very complex language which involves an awful lot of magic being done to translate your increasingly high-level OOP code into machine code. It is harder to reason about the generated machine code, and when you need to start debugging your panicky kernel or flaky device driver the complexities of your OOP abstractions will start becoming extremely irritating... especially if you have to do it via user-unfriendly debug ports into the target system.

相比之下,C++ 可能是一种非常复杂的语言,它涉及到将越来越高级的 OOP 代码转换为机器代码的大量魔法。生成的机器代码更难推理,当你需要开始调试你的恐慌内核或脆弱的设备驱动程序时,你的 OOP 抽象的复杂性将开始变得非常令人恼火……尤其是如果你必须通过用户不友好的方式来做这件事调试端口进入目标系统。

Incidentally, Linus is not the only OS developer to have strong opinions on systems programming languages; Theo de Raadt of OpenBSD has made a few choice quotes on the matter too.

顺便提一下,Linus 并不是唯一一个对系统编程语言有强烈意见的操作系统开发人员。OpenBSD 的 Theo de Raadt 也对这个问题做出了一些选择。

回答by otto

The feasibility of writing a kernel in C++ can be easily established: it has already been done. EKA2is the kernel of Symbian OS, which has been written in C++.

可以很容易地确定用 C++ 编写内核的可行性:它已经完成了。EKA2是 Symbian OS 的内核,它是用 C++ 编写的。

However, some restrictionsto the usage of certain C++ features apply in the Symbian environment.

但是,在 Symbian 环境中对某些 C++ 特性的使用有一些限制

回答by dtech

Revision after many years:

多年后改版:

Looking back, I'd say the biggest problem is actually with the tons of high level features in C++, that are either hidden or outside the control of the programmer. The standard doesn't enforce any particular way of implementing things, even if most implementations follow common sanity, there are many good reasons to be 100% explicit and have full control over how things are implemented in a OS kernel.

回顾过去,我认为最大的问题实际上是 C++ 中的大量高级功能,这些功能要么隐藏,要么超出了程序员的控制范围。该标准不强制执行任何特定的实现方式,即使大多数实现遵循共同的理智,也有很多充分的理由 100% 明确并完全控制操作系统内核中的实现方式。

This allows (as long as you know what you are doing) to reduce memory footprint, optimize data layout based on access patterns rather than OOP paradigms, thus improve cache-friendliness and performance, and avoid potential bugs that might come hidden in the tons of high level features of C++.

这允许(只要你知道你在做什么)减少内存占用,基于访问模式而不是 OOP 范式优化数据布局,从而提高缓存友好性和性能,并避免可能隐藏在大量数据中的潜在错误C++ 的高级特性。

Note that even tho far more simple, even C is too unpredictable in some cases, which is one of the reasons there is also a lot of platform specific assembly in the kernel code.

请注意,即使更简单,在某些情况下,甚至 C 也太不可预测了,这也是内核代码中存在大量平台特定程序集的原因之一。

回答by David Elson

While there is something "honest" about (ANSI) C, there is also something "honest", in a different way, about C++.

虽然 (ANSI) C 有一些“诚实”的东西,但也有一些“诚实”的东西,以不同的方式,关于 C++。

C++'s syntactic support for abstracting objects is very worthwhile, no matter what the application space. The more tools available for misnomer mitigation, the better ... and classes are such a tool.

C++ 对抽象对象的语法支持非常值得,无论什么应用空间。可用于缓解误称的工具越多越好……而类就是这样的工具。

If some part of an existing C++ compiler does not play well with kernel-level realities, then whittle up a modified version of the compiler that does it the "right" way, and use that.

如果现有 C++ 编译器的某些部分在内核级现实中不能很好地发挥作用,那么将编译器的修改版本精简为“正确”的方式,并使用它。

As far as programmer caliber and code quality, one can write either hideous or sublime code in either C or C++. I don't think it is right to discriminate against people who can actually code OOP well by disallowing it at the kernel level.

就程序员的素质和代码质量而言,人们可以用 C 或 C++ 编写可怕或崇高的代码。我认为通过在内核级别禁止 OOP 来歧视那些实际上可以很好地编写 OOP 的人是不对的。

That said, and even as a seasoned programmer, I miss the old days of writing in assembler. I like 'em both ... C++ and ASM ... as long as I can use Emacs and source level debuggers (:-).

也就是说,即使作为一个经验丰富的程序员,我也怀念过去用汇编语言编写代码的日子。我喜欢它们……C++ 和 ASM……只要我可以使用 Emacs 和源代码级调试器 (:-)。

回答by user2826084

One of the big benefits of C is it's readability. If you have a lot of code, which is more readable:

C 的一大好处是它的可读性。如果你有很多代码,这更具可读性:

foo.do_something(); 

or:

或者:

my_class_do_something(&foo); 

The C version is explicit about which type foo is every time foo is used. In C++ you have lots and lots of ambiguous "magic" going on behind the scenes. So readability is much worse if you are just looking at some small piece of code.

C 版本明确说明每次使用 foo 时 foo 是哪种类型。在 C++ 中,您在幕后有很多模棱两可的“魔法”。所以如果你只看一小段代码,可读性会差很多。