web-dev-qa-db-ja.com

C over C ++、およびC ++ over Cを使用する場合

私は1年以上前からコンピュータサイエンスを紹介してきましたが、私の経験から、CとC++はどちらも「超高速」言語と見なされているようですが、他のPythonそのようなスクリプト言語は通常やや遅いと見なされます。

しかし、ソフトウェアプロジェクトまたは小さなプロジェクトでも、特定の数nのファイルがCで書き込まれ、特定の数mのファイルがC++で書き込まれるファイルをインターリーブする多くのケースを見てきました。

(C++ファイルにはほとんど常に対応するヘッダーがあるが、Cファイルはそれほど多くないことにも気づいた)。しかし、私の質問の主な目的は、C++ではなくCを使用するのが適切な場合と、CよりもC++を使用する方が適切な場合の一般的な直感を得ることです。(1)C++がオブジェクト指向であるという事実以外にCはそうではなく、(2)構文は非常に似ており、C++は多くの点でCに似せるために意図的に作成されましたが、それらの違いはわかりません。多くのドメインで(ほぼ)完全に交換可能であるように私には思えます。

だから誰かが状況を片付けていただければ幸いです!ありがとう

164
Dark Templar

あなたはCを選ぶ

  • なんらかの理由で、ポータブルアセンブラ(Cは実際にはCです)が必要です。
  • あなたのプラットフォームはC++を提供していません(Cコンパイラは実装がはるかに簡単です)、
  • cとのみやり取りできる他の言語とやり取りする必要があり(通常、どのプラットフォームでも共通の最小要素)、コードはインターフェイスだけで構成されているため、CインターフェイスをC++コード上に配置する価値はありません。
  • あなたはオープンソースプロジェクトをハックします(その多くは さまざまな理由で 、Cに固執します)、
  • あなたはC++を知りません。

他のすべてのケースでは、C++を選択する必要があります。

184
sbi

Cを選択する理由はいくつかあります。主な理由は、C++で本当に小さな実行可能ファイルを作成することがより困難になる傾向があることです。本当に小さなシステムでは、とにかく大量のコードを書くことはめったになく、CではなくC++に必要な余分なROMスペースが重要になる場合があります。

ただし、really小さなシステムの場合、Cにもまったく同じ理由で問題があり、アセンブリ言語がほぼ唯一の合理的な選択肢であることも付け加えておきます。 Cが実際に意味をなすシステムサイズの範囲は非常に小さく、絶えず小さくなっています(私は認めますが、かなりゆっくりと)。

Cを使用するもう1つの時期/理由は、基本的に他の言語からバインドできる一連の関数を提供することです。これらの関数をextern "C"関数として定義することで、canをC++で記述できますbutこれにより、これらの関数は本質的にCライフの「顔」を世界に提示するように制限されます。クラス、オーバーロードされた関数、テンプレート、およびメンバー関数などは適用する必要がありません。ただし、これは必ずしも開発をCに限定するものではありません。外部インターフェイスがある限り、あらゆる種類のC++機能internallyを使用することは完全に合理的です。 Cのように見えます.

同時に、@ Tollの回答(明らかな例の1つ)は、ほとんどの点で逆のことを言っているに違いありません。合理的に書かれたC++は、一般に少なくともCと同じくらい高速で、多くの場合少なくとも少し高速です。最も簡単なアルゴリズムとデータ構造、すべてのエラー処理など、すべてのコードの雪崩に埋もれないためといっても、一般的に読みやすさははるかに優れています。

テンプレートは「言語の型システムの問題を修正」するのではなく、テンプレートなしでCやC++にほぼ完全に欠けているいくつかの基本的な機能を追加するだけです。元々の意図の1つはタイプセーフなコンテナーを提供することでしたが、実際にはそれをはるかに超えています-基本的にCが提供するものはまったくありません。

自動化されたツールも、ほとんどが赤ニシンです。Cパーサーを作成する方がC++パーサーを作成するよりも作業量が少ないことは事実ですが、実際には、最終的にはほとんど違いがありません。どちらか一方の使用可能なパーサーを作成する意思がある、またはできる人はほとんどいません。したがって、妥当な出発点はどちらにせよClangです。

偶然にも、CとC++は同じプロジェクトで一緒にかなり頻繁に使用され、同じ人によって保守されています。これにより、それ以外の場合は非常にまれなことが可能になります:a study これは、2人の言語で書かれたコードの保守性を、全体的に同等の能力を持つ人々(つまり、まったく同じ人々)が客観的に比較します。少なくともリンクされた調査では、「Cの代わりにC++を使用すると、ソフトウェアの品質が向上し、メンテナンスの労力が削減されることがわかりました」という結論が1つ明確で明確でした。

88
Jerry Coffin

CとC++の違いは、すでに詳細に列挙されています here 。時々人々はどちらか一方を選択する正当な理由があるかもしれませんが(OOPまたはCはC++の追加機能が望ましくないオーバーヘッドをもたらすと感じたときなど)Cです)、私の経験では通常それだけですこれらの言語はどちらもパフォーマンスが重要なアプリケーションに取り組んでいるのは事実であるため、ほとんどの場合、これが理由だと思います。

(サイドノート:チェックアウト Linus Torvads 'rant 彼がC++よりもCを好む理由について。私は必ずしも彼の主張に同意するわけではありませんが、人々がC++よりもCを選択する理由についての洞察を提供します。むしろ、彼に同意する人々はこれらの理由でCを選択するかもしれません。)

24
Casey Patton

(この投稿の時点で)既存の回答に欠けている主な問題は、選択です。

それは簡単です。まったく不合理な理由で、例外はオーバーヘッドに値しないと感じた場合は、それらを使用する必要はありません。テンプレート、RAII、および標準ライブラリを引き続き使用でき、単一の「スロー」を作成することはできません。テンプレートについても同様です。なんらかの理由で、それらが取り返しのつかない(そして実際に重要なことですが、埋め込みにのみ存在する)実行可能ファイルの膨張を引き起こすと感じた場合は、驚いたことに、void *とsizeof(T)を終日使用できます。 CではなくC++機能の使用を強制するものはありません。

これが、C++が本質的に優れた言語である理由です。必要な機能を簡単に選択でき、特定の機能が嫌いな場合はCスタイルのプログラミングにフォールバックできます。したがって、C++がCのすべてである以上、C++が優れた言語であることは明らかです。それ以外の場合の提案は、4が5より大きいことを提案しようとするようなものです。

13
DeadMG

Cプログラマを緊張させるC++に関すること

内部では多くの魔法が起こっています。コンストラクター、デストラクター、仮想メソッド、テンプレートなどを使用すると、C++コードを同等のCコードよりもはるかに簡単かつ高速に作成できますが、理解と推論が難しくなります(C++とそれに関連する規則をどの程度知っているかによって異なります)。クラスFoo(およびそれが依存するすべてのクラス)のコンストラクターの方法に応じて、Foo newFoo;のような単純なコードがlotのコードを呼び出す場合があります。定義されました。これは、コンテナを反復処理するときに++itではなくit++と表記することが慣例となっている理由でもあります。後置++は、高価なコピー操作を伴うことが多いためです。

特に単純なタスクの場合、何をしているのかに応じて、いくつかの重要なオーバーヘッドが発生する可能性があります。次の2つのプログラムを見てください。1つ目はCで、2つ目はC++です。

/* C version */
#include <stdio.h>
int main(void)
{
  char greeting[] = "Hello, world";
  printf("%s\n", greeting);
  return 0;
}
/* end C version */

/* C++ version */
#include <iostream>
#include <string>
int main(void)
{
  std::string greeting("Hello, world");
  std::cout << greeting << std::endl;
  return 0;
}
/* end C++ version */

ソースの点で大きな違いはありませんが、gcc 4.1.2で作業するSLES 10ボックスでは、前者はサイズが〜9kbの実行可能ファイルを生成しますが、2番目は12.5kbを超えます(最適化なし) )、ほぼ28%大きい。 C++ stringタイプは、IMOでの操作がC文字列ライブラリよりもはるかに簡単です。C++ストリームは、Cストリームよりもはるかに柔軟でカスタマイズ可能ですが、このような本当に頭の痛いコードでは、かもしれないオーバーヘッドの価値がない。

C++はCと比較して巨大な言語であり、セマンティクスは非常に複雑です。 C++よりもC++に習熟するには、Cよりもはるかに時間がかかります。つまり、C++を知っていると主張する多くの人々は、C++を知っていると思っているほど、それを知りません。

C++プログラマーを緊張させるCについてのこと

Cは、想像力を駆使した安全なプログラミング言語ではありません。配列の境界チェックがないと、悪用される可能性のある動作が多数発生します(現在は無効になっているgets関数を使用するか、scanfを使用して%sおよび%[変換指定子を使用します)。 C++は少なくとも、現在定義されている範囲外にアクセスしようとすると例外をスローするコンテナーを提供します。 Cが与えるすべては(運が良ければ)セグメンテーション違反です。

C++が提供するツールと比較して、Cでのメモリ管理は非常に労働集約的でエラーが発生しやすくなります。独自のコンテナを構築している場合は、mallocfreeのすべての呼び出しを照合して、割り当てが正常に行われていることを確認し、エラーが発生した場合は部分的な割り当てを取り消す必要があります。など。C++では、コンテナーにアイテムを追加したり、コンテナーからアイテムを削除したりするだけです。問題がある場合は、例外がスローされます。

同様に、Cでのエラー処理は、C++が提供するツール(つまり、例外)と比較すると、お尻の面倒です。本当に楽しいのは、大量のメモリを割り当ててから、処理の壁にぶつかったときです。バックアウトする必要があるので、そのメモリを正しい順序で解放する必要があります。 C++とRAIIの原則では、これは(比較的)簡単です。

どちらを使用するのですか?

あなたが書いているものが単純なものである場合は、それを読む/それをいじくる/そのアプリケーションを取り除く、その動作は入力と出力の観点からきれいに記述できるおよびパフォーマンスが重要な場合は、C++よりもCを優先します。それ以外の場合は、C++を優先します

9
John Bode

Bjarne Stroustrupは、C++を使用する アプリケーションと会社のリスト を維持しています。手続き型vs OOPプログラミングのすべてについて議論できますが、過去20年間の業界の結果については議論できません。

C++は、大規模でマルチマンの複雑なプロジェクトで一般的に使用され、別々の人がモジュール化されたコンポーネントで作業する必要があります。もちろん、モジュール化されたコードをCでビルドして維持することもできますが、C++の本質的なOOPの性質により、優れたモジュール化、テスト容易性、およびコードの再利用が可能になります。

C++標準ライブラリ(STL)は、それ自体がベクターとマップだけで構成されているため、C++を使用するのに十分な理由があります。

Cは一般に組み込みシステムに使用されます。

個人的にCを使用するのは、C APIのみを含むライブラリーがある場合のみです。

私がC++ではなくCを選択する主な理由は、「これは1000%安定している必要がある」というNASAのようなものに頼らなければならないときだけだと思います。

パフォーマンスを見ると、C++は約99%Cであり、生産性が大幅に向上します。したがって、CでもC++よりも高速なコードを書くことができます(例外なく、仮想、ストリーミング、抽象化などなしでC++のサブセットを使用できますが、それは基本的にCです)、すべてのいまいましいことを最適化する時間STLはテスト済みであり、すでにそうなっていますが、STLアルゴリズムは専門家のグループによって作成されており、おそらくすべての専門家ではないため、達成する可能性のある小さなパフォーマンス向上よりもコストがかかります。

一方、C++には大量の抽象化があります。状況下でリークが発生すると、問題が発生します。そして、C++の落とし穴を100%知っている人はほとんどいませんが、すべてのCの落とし穴を知っている人はもっと多いので、チームのすべてのメンバーがすべてのステップを完全に理解できるソリューションを書くのは、Cではずっと簡単です。

例:shared_ptr<smthn>はその参照カウントをオーバーフローしますが、例外をスローしますか?シャトルが大気圏に再び入らなければならないとき、これらのようなものはクールではありません、少なくとも私はそう思います。

また、例外処理はエラーコードに比べて非常に困難です。クラスが100%例外セーフであり、リークに陥りやすいかどうかを確認することは困難です。多くの高担当者がこの意見を表明しています。

9
Coder

Cはより優れた構文を備えた移植可能なアセンブリであり、プログラマーがすべてを制御できます

一方、C++は、多くのファンキーな魔法(仮想関数、オーバーロード、自動変換など)を実行します。

  • 必要以上のメモリを使用しないでください
  • nillyメモリページにアクセスしないでください(vtableはどこにでも配置できます)
  • 誤って多くのコードを呼び出さないでください

そして、あなたはパフォーマンスに集中しているので、本当に簡単に扱えるものを求めています。

驚きはありませんが、それは非常に貴重です。

必要に応じて(そして私はそれをお勧めします)、軍用航空電子制御用のC++を作成するときに考慮する必要があることについて JSFコーディングガイドライン をお読みください。あなたが知っておく必要のある多くの罠がそこにあり、それはあなたを捕まえるかもしれません。 Bjarneはそのドキュメントの一部だったので、彼はそれが何であるかを知っています。

また、Cは落雷した火傷したトロールのようにコンパイルされます。 C++、OTOHは、SSD企業に投資したのと同じ人々によっておそらく後援されました。 :)

(個人的には私はC++を好みますが、私はそれが好きではありません……。;-P)

6
Macke

(両方の言語について同等の知識がある場合)

プラットフォームにC++コンパイラがない場合を除き、C++を使用してください。好きな言語の部分(クラス、例外、仮想継承、適用したい個人的な制限はありません)なしでC++コードを記述できます。その後、将来的には、結局のところ、これらの機能を使用すれば、簡単に使用できます。 C++では、Cスタイルのコードの記述を妨げるものはありません。

(同等のツールセットと開発者の知識が与えられた場合)プラットフォームにC++コンパイラーがある場合は、C++ではなくCを選択する理由はありません。後で拡張するための扉を開いたまま、今日の希望の言語のサブセットに制限することができます。

2
anon

どちらの言語も優れています。多くのポスターがそれぞれの長所と用途を詳しく説明していると思います。私はこれを単に追加します:

C言語は4つの分野で完璧だと思います。1)あらゆるタイプのプログラミングを最初に学習するときに使用するのに最適な言語だと思います[アセンブリとマシンコードの知識を組み合わせて]、2)ドライバーを書くのに最適、3)組み込みソフトウェア、および4)最下位レベルのシステムソフトウェア。

C++はオブジェクト指向言語ですが、手続き型にすることもできます(ほとんどCの邪魔になります)。大規模なプロジェクト、GUIベースのソフトウェア、ゲームソフトウェア、その他のグラフィックを多用するソフトウェアに取り組んでいる場合は、C++、Java、またはObjective-Cが最適な選択肢であると思います。ただし、C++がCより優れている、または優れていると思われるコマンドラインプログラムやシステムソフトウェアはたくさんあります。

1
Jonathan

Cコードが生成される場合は、C++よりもCの方が望ましい(たとえば、高水準言語の実装で)。たとえば、Cコードを出力するLISPに似たコンパイラがいくつかあります(例 ChickenScheme48 ...))が、本物のC++コードを出力するものはありません(my- [〜#〜] melt [〜#〜] ツールはC++コードを出力しますが、そのコードを本物のC++コードとは呼びません。使用するC++機能はほとんどありません)。

Cコードは、半自動的に証明するのも簡単です。 Frama-C (コードに関する証明者の理由に役立つようにACSLコメントでCコードに注釈を付ける)のような静的アナライザーはCで利用できますが、完全なC++ 11ではそれほど多くありません。

私の意見では、この議論には欠けている点が1つあります。Cの方が、ライブラリから安定したバイナリインターフェースを提供する方が簡単です。他の言語やC++で使用するための両方。

C++では、異なるコンパイラーは異なる名前のマングリングを使用するため、ライブラリーとは異なるコンパイラーでコンパイルされたライブラリーのコンシューマーは、それを使用する際に問題が発生する可能性があります。 Cでは、バイナリインターフェイスは通常、プラットフォーム用に標準化されています。

最近のコンパイラには、gcc互換のものを生成するためのスイッチが付いていることがよくありますが、それが常に役立つとは限りません。

Solarisでこれを比較的頻繁に観察します。特にSparcシステムでは、多くの場合、ディストリビューションやさまざまなソフトウェアベンダーがSun Studioを使用します。 Manのオープンソースプロジェクトはgcc固有のコードで記述されています。それらを一緒に機能させるにはかなりの苦痛になる可能性があります。

0
johannes