オペレーティングシステムがCおよびC ++で低レベルの処理を行うのはなぜですか?なぜC ++だけではないのですか?


20

WindowsWikipediaページには、Windowsがブートローダーとタスクスイッチャー用にAssemblyで、カーネルルーチン用にC C ++で記述されていることが記載されています。

IIRC、あなたがからC ++の関数を呼び出すことができるextern "C"「Dブロック。カーネル関数にCを使用して、純粋なCアプリがそれらを使用できるようにすることができます(printfなど)が、それらをextern "C "ブロックにラップすることができるのであれば、なぜCでコードを書くのですか?


10
さまざまな「C ++があるときにCを使用する理由」を見たことがありますか?ここで質問?これは必ずしもそれらのいずれかの複製ではありませんが、それら関連しています。

1
「C ++関数をextern「C」 'dブロックからC ++として呼び出すことができます」C関数を呼び出せるということですか?
Code-Guru

ノーコード-達人@、エクスポートされたCおよびC ++の機能の唯一の違いは、名前の装飾およびC ++の添加であるため、this変数
コール・ジョンソン

2
ISRで例外をスローし、何が起こるかを確認
ジェームズ

さらに別のC対C ++の質問。
マチャド

回答:


31

これは主に歴史的な理由によるものです。Windowsカーネルの一部はもともとCで書かれていました。これは、1983年、30年以上前にWindows 1.0がリリースされたときにC ++がほとんどリリースされなかったためです。これは、Microsoftが下位互換性をセールスポイントにし、C ++のCパーツのバグ互換バージョンを書き換えるのに効果的なメリットがないために多大な労力を必要とするためです。


+1、私はそれが最も現実的な答えだと思います(C ++を好まない、またはその低レベルのものに対してC ++コンパイラを信頼しないWindowsカーネル開発者がいる可能性があることに加えて)。たとえば、ここstackoverflow.com/questions/520068/…を見てください。なぜLinuxカーネルがCで書かれているのですか?
Doc Brown

@ back2dos-それらのCコードは破棄されませんが、使用または更新されないという意味ではありません。私はもともとWindows 8の中にC ++ライブラリを移植されたCライブラリの中に書かれ、含まれていた何かを少なくとも一つの方法がありますことを保証
Ramhound

8
最近のWindowsのリリースにはWindows 1.0のコードがあるとは信じられません。Windows MEは、Windows NTコードベースに基づいていない最後のWindowsリリースでした。そして、それでも新しいR​​Tカーネルに大部分が置き換えられています(私が理解しているように、これは後方互換性の点であまり期待できません)。
TMN

@TMN:引数はおそらくおそらく正しいです-Win 1.0から現在までの道には、現在のWin8コードベースの一部であるCで書かれたライブラリたくさんあり、MSの誰も見ていませんそれらをC ++で書き直すと便利です。
ドックブラウン

1
とにかく、Windowsカーネルと通信するコードはほとんどありません。基本的に、ドライバーだけが行います。通常、アプリケーションはWin32 APIまたはPOSIX APIと通信します。
MSalters

24

ほとんどの人が指摘しているように、理由ははるかに歴史的ですが、誰も言及していないものがあり、それが人々が低レベルのCコードを書く理由だと思います。

Cは、仕様が(比較的)短いという意味で小さな言語です。C ++は巨大であり、控えめな表現です。これはプログラマにとってはそれほど重要ではないかもしれませんが(そうは思いますが)、正式な検証を行いたい場合には非常に重要です。さらに、Cコード分析用の確立されたツールがあり、バグなどの防止に役立ちます。

また、これは、他の業界に比べて展開されるバグのコストが非常に高い組み込みソフトウェアでは非常に重要です(Webを比較すると、すべてのユーザーにパッチをすぐに適用できます)。ミッションクリティカルなソフトウェアや医療製品は言うまでもありません。

BitCのように、これでさらに優れた言語を使用して、低レベルプログラミングでCを支配的な場所から置き換える試みがありましたが、これまでのところ成功していません。


4
+1純粋なCのミッションクリティカルなソフトウェア(航空ソフトウェアなど)に言及する場合。ただし、医療ソフトウェアではC ++も使用されます(C ++では非常に難しい正式な検証の代わりに広範なテストが使用されます)。
ジョルジオ

1
また、Cにはかなり成功した安全なサブセットMISRA-Cがあります。C ++には同等のものがありますが、それらは業界の事実上の標準ではありません(まだ)。安全重視のプログラミングの傾向は、ライブラリとコンパイラもMISRAのような安全なサブセットの使用を余儀なくされることです。C ++標準ライブラリ全体のMISRA-C ++互換バージョンを書き直すことは、ほとんどの場合、悪夢です。

2
@Lundin MISRAガイドラインは安全なサブセットではありません-Cを安全にしない生のポインターやその他のほとんどの機能がまだあります-それらは主に実装固有の動作を使用または文書化しないことに焦点を当てています。
ピートカーカム

@PeteKirkham MISRA-Cは、最も古典的なポインターバグをすべてキャッチし、静的分析を実施します。業界の安全基準(IEC 61508 et al)は、MISRA-CをCの安全なサブセットとして承認しているようです。サポート。

2
これは正しいので、ベストアンサーとして選択されているはずです。Cが歴史的な理由でのみ使用されていることを示唆する人は、それ自体がヒステリックです。
ロブ

15
  1. Cランタイムははるかに小さいです。
  2. C ++から低レベルの構成体への変換は、Cよりも透過性が低くなります(2つの簡単な例については、参照とvtablesを参照してください)。
  3. Cには通常、安定したABIがあります。C ++は通常そうではありません。つまり、最低限、システムコールインターフェイスはCスタイルにする必要があります。さらに、何らかの動的モジュールが必要な場合は、一貫したABIがあれば非常に役立ちます。

(2)および(3)に対して+1。私は(1)に納得していません。
トーマスエディング

7
@Thomas Eding:C ++ランタイムは、Cランタイムに加えて、例外、RTTI、別のメモリアロケーターなどのC ++機能で構成されています。YMMVは、それがはるかに大きいかどうかについて。(そして、標準ライブラリがあります...)
wnoise

ああ、例外と新しい/削除プールについて忘れていました。D:RTTIでも、私は決して使用しない
トーマスEding

11

理由は技術的なものではありません。アセンブリの少しは不可避であるが、それらはされていない強制的に、彼らは時折Cを使用したいと。私の会社は、ほぼ完全にC ++で記述された独自の独自のカーネルを使用していますが、埋め込みカーネルはC ++アプリケーションでモノリシックにコンパイルされているため、他のほとんどの人のようにカーネルへのCインターフェイスをサポートする必要はありません。あなたはCインタフェースを持っている場合は、それはそれはだにもかかわらず、Cのインターフェイスのコードを記述する方が簡単だ可能使用するextern "C"C ++でそれを書くこと。

サードパーティのコードが主な原因で、Cファイルのごく一部しかありません。サードパーティの低レベルコードはほとんどの場合Cで提供されます。CコードをC ++アプリに組み込む方が他の方法よりはるかに簡単だからです。


6

多くの場合、カーネル開発者は、ソースからすぐにコードが実際に何をするのかが明らかになったとき、より幸せに感じる種類の人々です。

C ++にはさらに多くの機能があり、単純なCコードが隠すよりもコードが行うことを隠します:オーバーロード、仮想メソッド、テンプレート、参照、スロー...それを使用するコード。

C ++の力は、ライブラリとフレームワークを作成する非常に強力なツールであり、アプリケーション開発を簡単にするものだと思います。C ++アプリケーション開発者は、そのライブラリを使用してアプリケーションを作成する能力が非常に高い場合でも、ライブラリのテンプレートで満たされた内部で完全に失われます。C ++ライブラリの権利を書くことは非常に難しいプログラミングタスクであり、アプリケーション開発者の利益のために優れたフレームワークを提供するためにのみ行われます。C ++ライブラリは、内部的に単純ではありません。アプリケーションプログラマーの観点から見ると、強力でありながら単純です。

ただし、カーネルAPIはC ++ APIにすることはできません。言語に依存しないAPIである必要があるため、C ++の優れた機能のほとんどは、そのインターフェイスで直接使用できません。さらに、カーネルは独立して開発された「ライブラリ」部分と「アプリケーション」部分に実際には分割されず、論理的に1つのライブラリに移動して、大量のアプリケーションの作成を容易にします。

また、カーネル内ではセキュリティと安定性がより重要であり、仮想メソッドは、プレーンコールバックや他のCのようなメカニズムよりもはるかに動的であるため、分離と検証がはるかに困難です。

要するに、もちろんC ++としてのカーネルを含むCプログラムを書くことはできますが、C ++の力のほとんどはカーネルでうまく使用されていません。そして、多くの人は、プログラミングツールは、あなたがすべきでないことをするのを防ぐべきだと主張するでしょう。C ++はそうしません。


+1。カーネル開発者としての私の「経験則」は、「キャッシュされたキャッシュライン」を簡単に推定できない場合、使用している言語は良いことよりも害があることです。
ブレンダン

明確化:カー​​ネルの場合、CPUはユーザー空間でほとんどの時間を費やし、カーネルコードは散発的に使用されると仮定する必要があります(たとえば、ユーザー空間がカーネルAPIを呼び出したり、割り込みが発生した場合)。つまり、「コールドキャッシュ」を想定する必要があります。最近のCPU(RAMはCPU速度に比べて遅い)キャッシュとTLBミスは高価であるため、(「コールドキャッシュ」の予想と組み合わせて)「キャッシュラインタッチ」メトリックは、パフォーマンスやスケーラビリティの非常に重要な指標になります。
ブレンダン

5

Bjarne Stroustrup、1999年7月のインタビュー

これらの言語はいずれも、他の現代の言語と根本的に異なるものや劇的に優れたものはありませんでした。しかし、彼らは十分であり、運と社会的要因の受益者でした


2
ようこそデビッド。引用または引用する場合、参照を追加することをお勧めします(追加!)
アンドリュー

3

Cは、その設計上、非常に低レベルの言語です。これは、アセンブラーからわずか1ステップです。対象のチップセットを知っていれば、少し知識があれば、Cを手動でASMに「コンパイル」できます。この種の「金属に近い」言語は、高レベルの最適化(パフォーマンス、メモリ効率など)の鍵となります。ただし、これは金属に近いため、この言語では無料で手に入れることはできません。これは手続き型の非オブジェクト指向言語であるため、このような構成体を使用するには、メモリ内で複数値の構成体を作成および使用するための多くの定型コードが必要です。

C ++は「C one better」であり、動的メモリ割り当て、組み込み構造マーシャリング、定義済みコードの大規模なライブラリなど、いくつかの使いやすさの機能を追加しますが効率はいくらか低下します(さらにはるかに優れています)管理されたランタイム環境よりも)。平均的なコーダーにとっては、メモリ割り当てなどの肛門保持制御を必要としないコードベースの領域の欠点よりも利点の方がはるかに優れています。

この2つの組み合わせは、かなり伝統的なものです。Cを使用して、コードベースの最もパフォーマンスが重要でメモリ効率の高い領域を記述します。その後、C ++コードからのメソッド呼び出しを介して、より抽象化された方法で作業できます。 、非常に最適化されたCコード。


2
効率性については、繰り返します。(1)C ++の人々は、それがでたらめだとあなたに言うでしょう。(2)私は、これが事実であるはずの理由が見当たらないと言っており、具体的な例が欲しい。効率の悪いコードを書くのが簡単な例ではありませんが、Cほど効率的であるには、過度のさを必要とする例があります。

3
「ugい」を定義する; 私はC#で生計を立てており、StackOverflowでC ++のコード例を見るたびに、言語の日々の使用においてどれほどの問題が普通と考えられているかが気になります。昔のC ++でコーディングしたとき、私はCコードをよく見ました。ハンドパッキング構造タイプ、手動ジャンプの実行ポインター計算、組み込みASM ... 一部の人々は、Java / .NETプログラマーの低レベルの知識の喪失を嘆きます。生産性にとって大きな恩恵だと思います。
キース

1
あなたは私の質問に答えませんでした;)「ugい」とは、「C ++の達人の基準によるugい」という意味です。換言すれば、実施例は、一つには、「現代C ++の」使用できない場合やC.として効率的なようである

2
それは本当かもしれません(正直に知りません)。ただし、カーネル開発(および他のいくつかのフィールド)については、平均的なプログラマーのことではありません。

3
C-> C ++は連続体であることを人々は忘れています。多くの場合、これらの引数は優れた最新のC ++とCを比較しています。Cプログラムを使用して、比較的短時間でC ++コンパイラーでコンパイルすると、まったく同じ速度で実行できます。最新のC ++機能が「遅すぎる」場合は、使用しないでください。それにはのようなものも含めることができiostreamます。「遅すぎる」というのは、C ++を介してCを使用する良い言い訳にはなりません。
ロボット

1

Cでは、ほとんどの時間を手元の問題とソリューションのコーディング方法について考えることに費やしている可能性があります。C ++では、C ++とその無数の機能、関数、および曖昧な構文について考えることになります。

また、多くのC ++ショップでは、コードが最新のデザインパターンセット、または偉大な神Stroustrupの最新の判読できない文言に夢中になっている「ファッションポリス」によって監視されます。きれいなコードは作業コードよりも価値が高くなります。最新のBoostテンプレートセットの使用を見つけることは、ビジネスに適したソリューションを見つけることよりも賞賛されます。

私の経験では、C ++のすべての巧妙な機能とオブジェクト指向の純度について、プレーンなCでコーディングすることで、より迅速かつ効果的に仕事をすることができます。


0

Cパーツは、C ++パーツに使用されるC ++コンパイラーにうまく移植できない可能性があります。たぶん、CコードはC ++コンパイラーを破壊する方法でCコンパイラーに乱雑です。

高品質のC ++コンパイラを使用している場合、プロジェクトでCとC ++を混在させる理由はほとんどありません。ほぼ。

1つの理由は、プロジェクトが他のプロジェクトとCコードを共有し、コードがC ++としてコンパイルされず、そのコードのC ++フォークを維持したくないためです。


-1

私はあなたがそれを逆に持っていると思う- extern "C"ブロックはC呼び出し規約がブロック内のすべての関数に使用されることを保証します。したがって、CのC ++関数ではなく、C ++から純粋なC関数を呼び出すことができます。とにかく、人々がCとC ++の両方を使用する理由は、多くの低レベルライブラリがCを使用して記述されており、独自に作成するよりもすでに存在します(おそらくデバッグおよび最適化されます)。OTOH、C ++は、人々が一緒に作業したいと思う多くの素晴らしい高レベルの機能を提供します。


-2

プログラミング言語としてCを使用するさまざまなレベルの組み込みプラットフォームがあります(もちろん、いつでもアセンブリ言語を使用できます)

「レベル」については、システムの内部SRAMおよびROMリソースレベルについて説明しています。

これらのプラットフォームは、リソースに制約がある場合があります(たとえば、一部の8051プラットフォームには128バイトのユーザーSRAMしかありません)。

このように少量のRAMで動的メモリ割り当てをサポートすることは無意味です。(新規/削除)またはCのmalloc

CからC ++への主な改善点の1つは、オブジェクト指向のパラダイムです。C ++は、メモリフットプリントが大きいソフトウェアに適しています

ただし、最大32 KBのサイズ制限がある組み込みファームウェアでは使用できません。(例:16ビットMCUプラットフォーム)

一般にCコンパイラよりも複雑なC ++コンパイラは必要ありません。(少なくともSDKプロバイダーはこれを行うことを気にしません)。

実際、32ビットARM7プラットフォームでC ++コンパイラを見つけることはほとんどできません。

複雑さだけの価値はない

一部の8051(8ビット):1MB ROM、128B RAM

TI MSP430(16ビット):32KB ROM、4KB RAM

ST Microelectronics ARM 32ビットCortex™-M3 CPUコア(STM32F103T4):16または32Kバイトのフラッシュメモリ6または10KバイトのSRAM


2
これは、すでにここに投稿されている他の回答に新しいことではありません。
マーティンピーターズ14

ARM用の32ビットC ++コンパイラですか?必要に応じて、iOS用のC ++コンパイラを取得するためにいくつかの変更を加えた後、ソースから自分でLLVMをコンパイルできます。
コールジョンソン14

-4

考えられる理由はいくつかあります。

  • C ++の同等物と比較すると、Cは少し効率的です。
  • 彼らが使用するいくつかのライブラリはCで書かれています。
  • Cで記述されたLinuxカーネルの一部を使用します。

編集済み:結局のところ、3番目の引数は真ではありません(コメントを参照)。


5
(1)C ++の人々は異なることを請うでしょう。そして客観的には、これが事実であるべき理由はないと思います。(2)C ++は、Cコードを正常に呼び出すことができます(これは、後方互換性との全体的なポイントですextern "C")。

1
MSがLinuxカーネルの一部を使用し、LinuxカーネルがGPLである場合、WindowsもGPLでなければならないということではないでしょうか?
TomJ

1
@TomJは、実際にLinuxに数千行も寄付することを余儀なくされた理由です。+なぜ彼らはLinux開発をサポートすると思いますか?
ピジュスン

2
@Pius彼のポイントは(そして彼の言うとおりです)、WindowsカーネルにリンクされたGPLのコードがある場合、カーネル全体をGPLする必要があります(著作権者との別個の契約がない場合)。

@delnan、詳細についてはわかりません。私は弁護士ではないので、コメントすることはできません。しかし、これについては数年前に小さなスキャンダルがありました。確かではありませんが、私はすべてのクレイジーなものが関係していたネットワーキングモジュールだったのではないかと思います。
ピジュスン

-4

CはおそらくC ++よりも優れた言語だからです。また、一部のコードはC ++が普及する前に記述されたため、人々はそれを置き換える理由がありませんでした。

また、C ++には、カーネルで使用する際に注意を払わないとコードを壊す可能性のある機能がたくさんあるためです。


C ++は動的ライブラリを期待していますか?そして、動的メモリとは何ですか?

4
-1の場合[stuff] that C++ expects。C ++がCよりも多くのヒープを使用するのはなぜですか?C ++がCよりも多くのdllを必要とするのはなぜですか?単純に
真実では

1
修正:C ++で書かれたライブラリを失います。したがって、C ++またはCを使用している場合は、1に戻ります。テンプレート、クラス、デストラクタ、const、およびその他のあらゆる利点を使用できる場合、なぜC機能に限定するのでしょうか。
トーマスエディング

6
何?テンプレート、例外、オブジェクト(コンストラクタ、デストラクタ、オーバーロードされた演算子を含む、構築を移動する、そして実際には他のすべて)などは、メモリの場所(スタック、静的メモリ、カスタムプールなど)に関係なく正常に動作します。標準のコンテナはデフォルトでヒープ割り当てを使用しますが、アロケータはカスタマイズでき、カーネル担当者は独自のコレクションとメモリ管理を作成します。-1

2
参考までに、私はあなたの答えが今まで積極的に有害であるとは思わないので、私のダウン票を削除しましたが、それは特に有用または洞察力があるとは思いません。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.