C言語と比較してC ++の制限は何ですか?[閉まっている]


116

C ++の利点は次のとおりです

  • C ++は、彼らが求めている特定の機能を提供します
  • 彼らのCコンパイラはほぼ間違いなくC ++コンパイラなので、ソフトウェアのコストへの影響はありません
  • C ++はCと同様に移植可能です
  • C ++コードは、Cと同じくらい(またはそれ以上またはそれ以下)効率的です。

C ++ではなくCを使用する必要がある具体的な理由と特定のシナリオはありますか?

この質問への参照:Cのジェネリックのライブラリ

重複ではありません。この質問は言語の制限について尋ねているのであり、ある言語を別の言語で学ぶべき/すべきではないためです。

Peter Kirkhamの投稿は、特に私が考慮していなかったC99の問題に関して、私にとって最も有益であったので、それを受け入れました。参加してくれた他のすべての人に感謝します。


12
この質問が議論の対象となるかどうかは問題ではありませんが、それでも問題はありません。プロジェクトの言語の選択はまさにそれです:選択。
ボンベ

7
@bombeは、情報に基づいた選択を行う方法について話し合うべきではないのですか?



10
CプログラマがC ++に移行するようにアドバイスするとき、CプログラマがC ++を捨ててCに移行するように指示した場合と同じように、彼らがあなたのアイデアを受け入れるのと同じくらい皮肉ではありませんか?
ウォレンP

回答:


136

これは、Cのジェネリックライブラリについて尋ねる現在の質問に対する答えによって促されます。質問者は、C ++を使用したくないと具体的に述べています。

Cは完全なプログラミング言語です。CはC ++の任意のサブセットではありません。CはC ++のサブセットではありません。

これは有効なC:

foo_t* foo = malloc ( sizeof(foo_t) );

C ++としてコンパイルするには、次のように記述する必要があります。

foo_t* foo = static_cast<foo_t*>( malloc ( sizeof(foo_t) ) );

これはもはや有効なCではありません。(Cスタイルのキャストを使用できます。この場合、Cでコンパイルされますが、ほとんどのC ++コーディング標準によって、そして多くのCプログラマーによって避けられます。スタックオーバーフロー全体で「mallocをキャストしない」コメントを確認してください) 。


これらは同じ言語ではありません。Cに既存のプロジェクトがある場合、ライブラリを使用するためだけに別の言語で書き直したくありません。作業している言語でインターフェースできるライブラリーを使用することをお勧めしますextern "C"

私が取り組んでいるプロジェクトの最初のCファイルを取得すると、次のようにスワップgcc std=c99しただけですg++

sandiego:$ g++ -g  -O1 -pedantic -mfpmath=sse -DUSE_SSE2 -DUSE_XMM3  -I src/core -L /usr/lib -DARCH=elf64 -D_BSD_SOURCE -DPOSIX -D_ISOC99_SOURCE -D_POSIX_C_SOURCE=200112L -Wall -Wextra -Wwrite-strings -Wredundant-decls -Werror -Isrc  src/core/kin_object.c -c -o obj/kin_object.o | wc -l
In file included from src/core/kin_object.c:22:
src/core/kin_object.h:791:28: error: anonymous variadic macros were introduced in C99
In file included from src/core/kin_object.c:26:
src/core/kin_log.h:42:42: error: anonymous variadic macros were introduced in C99
src/core/kin_log.h:94:29: error: anonymous variadic macros were introduced in C99
...
cc1plus: warnings being treated as errors
src/core/kin_object.c:101: error: ISO C++ does not support the z printf length modifier
..
src/core/kin_object.c:160: error: invalid conversion from void*’ to kin_object_t*’
..
src/core/kin_object.c:227: error: unused parameter restrict
..
src/core/kin_object.c:271: error: ISO C++ does not support the z printf length modifier
src/core/kin_object.c:271: error: ISO C++ does not support the z printf length modifier

合計69行のエラーがあり、そのうち4行は無効な変換ですが、ほとんどがC99には存在するがC ++には存在しない機能に関するものです。

それは私がそれを楽しむためにそれらの機能を使用しているようではありません。それを別の言語に移植するにはかなりの作業が必要になります。

したがって、それを示唆するのは明らかに間違っています

[a] Cコンパイラはほぼ確実に実際にはC ++コンパイラであるため、ソフトウェアのコストへの影響はありません

多くの場合、既存のCコードをC ++の手続き型サブセットに移植すると、コストに大きな影響があります。

したがって、Cでキューのライブラリ実装を探すための質問への回答として「C ++ std :: queueクラスを使用する」ことを提案することは目的Cを使用する」および「JNIを使​​用してJava java.util.Queueクラスを呼び出すことを提案するよりも後回しです。または'CPythonライブラリを呼び出す' -Objective Cは実際にはC(C99を含む)の適切なスーパーセットであり、JavaおよびCPythonライブラリはどちらもCから直接呼び出すことができ、無関係なコードをC ++言語に移植する必要はありません。

もちろん、CファサードをC ++ライブラリに提供することもできますが、一度実行すると、C ++はJavaやPythonと変わりません。


21
はい。Cスタイルのキャストは、mallocを使用する場合はよくあることです。mallocを使用する場合、cサブセット内にとどまります。C ++スタイルをプログラムする場合は、static_cast + mallocではなく、演算子newを使用します。
スマ

33
CがC ++のサブセットではないと言うのは、信じられないほどの知識です。確かに、「クラス」と呼ばれるメンバーを持つ構造体はコンパイルされませんが、実際に必要なのはほんのわずかな変更であり、ほとんどのコンパイラーにはC ++にいくつかのC専用機能を追加するオプションがあります。
Kaz Dragon

27
mallocの例に関する限り、キャストの追加は、C ++プログラマーだけでなく(特に)Cプログラマーも避けます。Cコードでキャストを省略するのには十分な理由があります。これは必須ではなく、追加するとエラーが隠れる可能性があります。ええ、それらを2つの異なる言語として扱います。+1 :)
2009年

26
@BlueRaja Guidoがスクリプト言語にオブジェクトを追加しないことに決め、2つのグループが相互に互換性のないPythonのフォークを作成してオブジェクトを追加したとします。1つはSmalltalkに基づくオブジェクトモデル、もう1つはSimulaに基づくクラスシステムです。その後、GuidoはPythonのコア使用に焦点を合わせて改善を続けました。これは、C / Objective C / C ++の状況に近いものです。
Pete Kirkham、2010年

11
@BlueRaja:かなり大きな共通コアを共有する2つの異なる言語です。その共通のコアでプログラムする場合、どちらの言語でも良いコードではないことをすることになります。特定のプログラムを作成するために1つの言語を選択し、その言語でそれを適切にしてください。
David Thornley、2010年

115

私はそれが専門家でも特に良い答えでもないことを理解していますが、私にとってはそれは私が本当にCが好きだからという理由だけです。Cは小さくてシンプルで、言語全体を頭の中に収めることができます。C++は常に巨大な混乱のように見えましたあらゆる種類のレイヤーで、私はグロッキングに苦労しています。このため、C ++を書くときはいつでも、Cをコーディングするときよりもデバッグとハードサーフェスに頭を叩くのにずっと多くの時間を費やしてしまいます。これも、多くの場合、自分自身の「無知」の結果であることに気づきます。

選択できるようになった場合は、Python(またはおそらくC#)でのインターフェイスやデータベースの相互作用などのすべての高レベルのものと、Cで高速でなければならないすべてのものを記述します。私にとっては、すべての世界で最高のものを提供します。すべてをC ++で書くことは、すべての世界で最悪の事態に陥るようなものです。

編集: いくつかのC ++機能を備えたCは、プロジェクトで複数の人が作業する場合、または保守性が優先される場合、主に悪い考えだと私は付け加えたいと思います。何が「少数」を構成するのか、どのビットをCで実行する必要があるのか​​、C ++のどのビットが最終的に非常に統合失調症のコードベースにつながるのかについては意見の相違があります。


24
私は数年間C ++を使用していましたが、コードのリファクタリングに50%費やして「C ++正しい」ものにしました。あなたが言うように、それは悪夢です。
カイ

12
いつでも最初から正しく実行できます。constを追加することは難しくありません。
GManNickG 2009

14
私はC ++を10年間使用しており、C(私の場合は組み込みシステムの場合)に戻ることが、これまでで最高のことでした。
ウォレンP

私はこの答えが大好きです。あなたも私の気持ちを釘付けにした。私はC ++開発者として何年も働いてきましたが、私の仕事はまだ C ++です。しかし、それは、私がCの美しさを参照言語のようにIを意味するものではありません
マット・ジョイナー

10
+1、これが原因で、C ++を作成するときはいつでも、Cをコーディングするときよりもデバッグとハードサーフェスに対する頭の強打にかなりの時間を費やすことになります。これ以上あなたに同意することはできません。最良の答え。:)
ApprenticeHacker

58

C ++は、低レベルの組み込みシステムなど、実際の環境ではサポートされていないだけです。そして、それには十分な理由があります。Cはそのようなことを十分に容易に行えるので、なぜもっと大きなものを使うのですか?


2
正しい。8ビットマイクロコントローラー用のcコンパイラを見てきました。
dmckee ---元モデレーターの子猫

6
もちろん。最近では、ほとんどの8ビットチップにCコンパイラが搭載されています。
Eli Bendersky 2009


+1これが正解です。C ++コンパイラーは、主に(複数の)継承が複雑であるため、Cコンパイラーよりも作成がはるかに困難です。
BlueRaja-Danny Pflughoeft 2010年

9
@BlueRaja:テンプレートと比較して...複数継承は、ここでの本当の抑止力ではないかもしれません。結局、テンプレートは独自の完全な言語を構成します。
Matthieu M.10年

49

C ++でのプログラミングは嫌いです。


6
笑私は

30
とても説得力があります!私はあなたの議論に基づいてPythonに切り替えることを考えています。
ジミーJ

8
納得できないかもしれませんが、それが本当の理由です。
GeorgSchölly2009年

@Jimmy J:Pythonは素晴らしいです。これは、Unix、C、およびすべての「最新の」言語機能が正しく行われた中で最高です。パフォーマンスの問題がある場合、Python Cにドロップすることを要求し、簡単にそれを行います。
マットジョイナー、2015年

2
@Georg:私は一度も見たことがないことを認めますが、Pythonにはとても感銘を受けました。
マットジョイナー

38

いくつかの理由が考えられます。

  • サポートの欠如-すべてのCコンパイラがC ++コンパイラでもあるわけではありません。C ++のサポートを主張している場合でも、すべてのコンパイラーが標準に特に準拠しているわけではありません。また、一部のC ++コンパイラは、絶望的に肥大化した非効率的なコードを生成します。一部のコンパイラには、標準ライブラリのひどい実装があります。カーネルモードの開発では、通常、C ++標準ライブラリと一部の言語機能を使用できません。言語のコアに固執している場合でもC ++コードを記述できますが、Cに切り替える方が簡単な場合があります。
  • 親しみやすさ。C ++は複雑な言語です。C ++よりもCを教える方が簡単で、優れたC ++プログラマよりも優れたCプログラマを見つける方が簡単です。(ここのキーワードは「良い」です。多くのC ++プログラマーがいますが、それらのほとんどは言語を適切に学習していません)
  • 学習曲線-上記のように、誰かにC ++を教えることは大きな仕事です。将来他の人が保守する必要があり、他の人がC ++プログラマではない可能性のあるアプリを作成している場合、Cでそれを書くと、より簡単に理解できるようになります。

私はC ++で書くことを好みますが、それでうまくいくのであれば、全体として、メリットよりデメリットを上回ると思います。しかし、場合によってはCを使用することについての議論も見ることができます。


4
CコードはC ++よりもはるかに速くコンパイルできることを付け加えておきます。弊社の巨大なプロジェクト(100万行以上)のコンパイル時間は30秒未満です。
カルマリウス

31

組み込みプログラミング、パフォーマンスなどに関する議論はたくさんあります。私はそれらを購入しません。C ++は、これらの領域でCと簡単に比較できます。しかしながら:

15年以上C ++でプログラミングした直後に、Cのルーツを再発見してきました。C ++には、生活を楽にする優れた機能がある一方で、多くの落とし穴があり、ある種の「常により良い方法」で物事を行うこともあると私は言わなければなりません。あなたが実際にあなたがした解決策についてかなり満足することは決してありません。(誤解しないでください。これは良いことかもしれませんが、ほとんどの場合はそうではありません)。

C ++はあなたに無限の銃撃を与えます。これは間違いなく良いことかもしれませんが、どういうわけかいつもそれを使いすぎてしまいます。これは、抽象化や一般性などの「素敵な」層や「かなりの」層でソリューションを偽装していることを意味します。

Cに戻って発見したのは、プログラミングが本当に楽しいということでした。継承を最大限に活用し、モデリングする方法について非常に多くの時間を費やしてきたため、Cでプログラミングすると、実際にソースコードが小さくなり、読みやすくなります。これはもちろん、自己規律のレベルに依存します。しかし、実際に必要になることのない単純なコードに抽象化しすぎることは非常に簡単です。


8
違反はありませんが、C ++が何であるかによります。継承は私がC ++よりもJavaに関連付けるものであり、C ++をJavaのOOP言語(Cとクラス)として厳密に扱う場合、私はあなたに同意します。C ++のよりモダンな味にこだわるなら、Cよりも楽しいと思います
jalf

11
もう一度言いますが、私はC ++をオブジェクト指向言語とは考えていません。C++をオブジェクト指向言語として扱うべきではありません。ジェネリックプログラミングはC ++のはるかに強い特徴だと思います。私が目にするC ++コードのほとんどは、特に "OO"になるように頑張ったり、不要なコードを含んでいない。多くの場合、同等のCコードよりも
無駄が少ない

3
@jalf:C ++で「常により良い方法」の注意散漫になる可能性があると私が思うもう1つのことは、テンプレートで一般化することです。「たぶん、このクラスのユーザーに、使用する基になる整数型を決定させるべきでしょうか?」しかし、おそらくあなたはそれを必要としないでしょう、そしてCではあなたは気にしないでしょう。Cで最初の要素へのポインターとカウント、または(空想の高さ)をとる関数を公開するとき、「私は本当にこのクラスへのフォワードイテレーターインターフェースを提供する必要がある」と思うことがあります。コールバック関数ポインタ。
j_random_hacker

2
C ++でのコーディングが役立つときに一歩下がると思います。目標を決めて、それに向かって書きます(Cスタイル)。C ++ ismの有用性が明らかになったときの因数分解。
マットジョイナー、2015年

2
infinite gunfire、そうそうそうそうそう。私たちの足は文字通り震えます:)
ケツァルコアトル2013

27

Cの主な利点は、コードの一部を見たときに実際に何が起こっているかを確認できることです(そう、プリプロセッサー:-Eを指定してコンパイルすると、それが表示されます)。いくつかのC ++コードを見ると、あまりにもしばしば正しくないことがある。そこには、スコープに基づいて、または割り当てのために暗黙的に呼び出されるコンストラクターとデストラクターがあり、悪用されていなくても、予期しない動作をする可能性のある演算子のオーバーロードがあります。私はコントロールの変種者だと認めますが、信頼できるソフトウェアを書きたいソフトウェア開発者にとって、これはそれほど悪い習慣ではないという結論に達しました。私のソフトウェアは本来の機能を正確に果たし、同時に胃に不快感を与えないという公正な機会を与えたいと思っています。バグがまだたくさんあるため、

C ++にもテンプレートがあります。私は嫌いで愛していますが、誰かが彼らを完全に理解していると言ったら、私は彼/彼女を嘘つきと呼びます!これには、コンパイラの作成者だけでなく、標準の定義に関係する人々(これを読んでみると明らかになります)も含まれます。実際には、実際にコードを記述している間、それらすべてを検討することは不可能であるほど多くのばかげて誤解を招くコーナーケースが含まれています。C ++テンプレートの強力な機能が大好きです。それらを使って何ができるかは本当に驚くべきことですが、同様に、想像できないほど奇妙で難しいエラーを見つけることができます。そして、これらのエラーは実際には起こり、まれではありません。C ++ ARMでテンプレートを解決するために必要なルールについて読むと、頭が爆発しそうになります。また、コンパイラが実際に何を望んでいるのかを理解するためにすでに10分以上必要な、長さが数1000文字のコンパイラエラーメッセージを読む必要があるという無駄な時間を感じさせます。典型的なC ++(ライブラリ)コードでは、特定のテンプレートを可能にするためにヘッダーファイルに多くのコードが含まれていることが多く、高速マシンでもコンパイル/実行サイクルが非常に遅くなり、何かを変更するときにコードの大部分を再コンパイルする必要がありますそこ。

C ++にはconstトラップもあります。最も些細なユースケースを除いてconstを回避するか、遅かれ早かれそれをキャストするか、コードベースの大きな部分をリファクタリングする必要があります(特に、優れた柔軟なOO設計を開発しようとしている場合)。

C ++は、Cよりもタイピングが強力です。これは素晴らしいことですが、C ++コードをコンパイルしようとすると、たまごっちに餌を与えているように感じることがあります。通常私が受け取る警告とエラーの大部分は、実際には私が機能しないことをしているのではなく、コンパイラーが私にこのようにしてはいけないことや、ここにいくつかの追加のキーワードをキャストしたり配置したりしないとそこ。

これらは、堅牢であるとされている外部ライブラリの一部のみを使用して単独で書くソフトウェアでC ++が嫌いな理由の一部にすぎません。実際の恐怖は、他の人とチームでコードを書くときに始まります。彼らが非常に賢いC ++ハッカーであるか、初心者初心者であるかはほとんど関係ありません。誰もがエラーを犯しますが、C ++では故意にエラーを見つけにくくし、エラーが発生する前に見つけるのがさらに難しくなっています。

C ++を使用すると、常にデバッガーを使用せずに単純に失われますが、私は頭の中でコードの正当性を検証でき、デバッガーに頼って、予想外のパスで実行されているコードを見つける必要がないようにします。私は実際にすべてのコードを頭の中で実行し、サブルーチンなどでもコードのすべての分岐を取り、デバッガーをときどき使用して、準備したすべての居心地の良い場所をどれだけうまく実行できるかを確認します。すべてのコードパスがあらゆる種類の奇妙な入力データとのあらゆる組み合わせで使用されているほど多くのテストケースを作成して実行することは、単に不可能です。したがって、C ++プログラムのバグを知らないかもしれませんが、それはそれらがそこにないことを意味しません。C ++プロジェクトが大きくなるほど、手元にあるすべてのテストデータで完全に実行されたとしても、検出されないバグが多くないという確信が持てます。最終的に私はそれを捨てて、他の言語または他の言語の組み合わせで新たに始めます。

私は続けることができましたが、私は今までに私のポイントを明らかにしたと思います。C ++でプログラミングすると、これらすべてが非生産的になり、自分のコードの正確さに自信を失うようになりました。つまり、20を超えて記述したCコードを引き続き使用していても、それを使用しなくなりました。数年前。多分それは単に私がC ++プログラマーではないからか、Cや他の言語でかなり上手いから、C ++に関しては自分が何者であるかを認識することができ、それを完全に理解することはできないでしょう。 。

人生は短いです...


2
+1、これ以上同意できませんでした。
missingfaktor 2010年

2
これは、Linusの主張と非常に類似しているようです。(オブジェクトコンテキストが少ない=理解しやすい。)
Warren P

20

低レベルの組み込み環境では、「ソフトウェアエンジニア」の一部はEEのバックグラウンドを持ち、ほとんどCを習得していません。C++はより複雑であり、これらの一部の人は単に新しい言語を学ぶことを恐れています。したがって、Cは最小公分母として使用されます。(あなたがこれらの人を取り除くことを提案する前に、彼らは少なくとも筋金入りのアナログのものを理解していないCSメジャーと同じくらい重要です。)

両方を継承して維持した経験から言えば、Cでの恐ろしい設計は理解し、ほどいて、使用可能なものにリファクタリングするのが困難です。

C ++の恐ろしい設計は、抽象化のランダムなレイヤーが、どのコードがどのような状況で実行されるのかを理解しようとするコードベースの周りに頭を悩ませるので、無限に悪化します。

優れたデザインを生み出さないことがわかっているエンジニアと協力しなければならない場合は、後者よりも前者の方がいいです。


アーメン、兄弟。ハードウェアエンジニアが作成したCソースを使用していて、C ++で実行した場合に直面するであろうことを考えて、身震いしました。
Richard Chambers

19

組み込みシステムや同様のものをプログラミングする場合でも、私は個人的な嫌い以外の理由は見ません。C ++では、使用する機能に対してのみオーバーヘッドが発生します。C ++のオーバーヘッドが高すぎる特定の状況では、C ++のCサブセットを使用できます。つまり、一部のCプログラマーは、一部のC ++構成体のオーバーヘッドを過大評価していると思います。いくつか例を挙げましょう。

  • クラスおよびメンバー関数は、通常の関数と比較してオーバーヘッドがゼロです(仮想関数を使用する場合を除く)。この場合、関数ポインターの使用と比較してオーバーヘッドはありません)
  • テンプレートのオーバーヘッドはほとんどありません(ほとんどの場合、オーバーヘッドはまったくありません)。

適切な理由の1つは、まともなC ++コンパイラーがない(C ++コンパイラーがないか、コンパイラーが存在するが、実装が不十分で、一部のC ++機能に不要な高いオーバーヘッドを課す)プラットフォーム用にプログラミングしている場合です。


3
仮想関数を持つクラスは、オーバーヘッドが大きくなります。各インスタンスは、タイプを識別するために追加のフィールドを持ち歩く必要があります。
bstpierre 2009年

6
何よりもオーバーヘッド?タイプはvtblに含まれています。関数ポインタを使用して同様のメカニズムを実装する場合、使用する関数ポインタを選択するには、少なくとも1つのポインタ(またはインデックスなど)が必要です。
スマ

3
bstpierre:私は何須磨が言っていることだと思いません:それは持っていることは多くのオーバーヘッドC.に手動で自分で機能を実装するより
マーティンニューヨーク

2
クラスvtableへのポインタは、クラスの各インスタンスに格納されます。
tstenner 2009

5
オーバーヘッドがありますが、動的型の解決が必要な場合は、Cでもタイプを識別するためのストレージが必要です。動的型が不要な場合は、オーバーヘッドを支払う必要はありません(仮想関数が必要ない場合は使用しないでください)。
スマ

13

なぜ英語で話すことを制限するのですか?おそらく、あなたはセルビア語でより創造的な作家になるでしょう。

これは同じ主張ですが、明らかな誤りがあります。タスクがあり、快適なツールがタスクを効率的に解決する場合、適切な理由で快適なツールを使用する可能性があります。


3
流暢な英語と流暢なセルビア語の両方を話せば、私はもっと創造的になると確信しています。反対ですか?

2
@ニールは確かに、しかしセルビア語を学ぶために必要な努力は私の現在の創造性のブロックを解決するために正当化されないかもしれません。
スリムな

2
Arnoは、あなたがCPUのために書いているのではなく、同僚が読んだり、他のライブラリーがリンクするために書いたりしているという事実を強調していると思います。結局のところ、表現力とスピードだけを追求するのであれば、OCamlで記述します。
Ken

10

C ++の学習曲線ははるかに長くなります。Cには、知っておく必要がある構成要素がほとんどないため、強力なソフトウェアのコーディングを開始できます。C ++では、Cベース、次にオブジェクト指向プログラミングと汎用プログラミング、例外などを学習する必要があります。しばらくすると、ほとんどの機能を知って、おそらくそれらを使用できるようになりますが、コンパイラーがどのように機能するかはまだわかりませんそれらを翻訳し、暗黙のオーバーヘッドがあるかどうか。これには多くの時間とエネルギーが必要です。

専門家のプロジェクトでは、すでにC ++をよく知っている人を雇うことができるので、この議論は重要ではないかもしれません。しかし、Cが未だに使われているオープンソースプロジェクトでは、人々は好きな言語を選択し、使用することができます。すべてのOSプログラマーがプロのプログラマーであるとは限りません。


1
えっと…違う?Cのベースを学習し(おそらく、配列とC形式の文字列処理を除いて、<vector>と<string>を優先して削除されます)、学習に取り掛かります。あなたが進むにつれて、あなたは他のすべてを拾うことができます。C ++を使い始めるのにOO、GP、または例外について何も知る必要はありません...
DevSolar 2009年

4
Cは「小さい」かもしれませんが、長期的には使いやすくありません。手動メモリ管理?結構です。
ジミーJ

7
C ++には自動メモリ管理などはありません。
ウォーレンP

3
C ++はメモリ管理の問題を解決しません。ポインターを操作したと思ったとき、C ++はひどい例外モデルを追加します。C99の土地に来てください。データ構造を除いて、mallocにはほとんど触れません。それでも、少数のmalloc呼び出しを「カプセル化」できます。これは、C ++の場合とほとんど同じです(暗黙的なメモリ管理、スタックではなくヒープ上でのみ行われます)。すべてのスマートポインタージャズに関してのみです。
マットジョイナー、2015年

1
@ereOn:確かに、私が3年前に書いたコメントはもはや成立しません。:)
マットジョイナー2013

10

Dan Olsonの回答をフォローアップしたいと思います。人々はC ++の潜在的に危険で非生産的な機能を恐れていると私は信じています。しかし、Danの言うこととは異なり、次の2つの理由から、単純にコーディング標準を決定することが効果的であるとは思いません。

  1. コーディング標準を厳密に実施するのは難しい場合があります
  2. 良いものを思いつくのはとても難しいことです。

ここで2番目の理由は、最初の理由よりもはるかに重要であると思います。コーディング基準の決定は、簡単に政治的な問題になり、後で改訂される可能性があるためです。次の単純化されたケースを考えてみます。

  1. stlコンテナの使用は許可されていますが、独自のコードでテンプレートを使用することはできません。
  2. このクラスまたはそのテンプレートクラスをコーディングすることを許可されれば、生産性が向上すると人々は不満を言い始めます。
  3. それを可能にするためにコーディング標準が改訂されました。
  4. 誰も従わない過度に複雑なコーディング標準に勾配をスライドさせ、標準が防止するはずの危険なコードを正確に使用し、標準を取り巻く過剰な官僚主義と組み合わせます。

(ステップ3で標準が修正されないという代替案は、経験的に考えて考えるのは不可能であり、とにかくそれほど良くはありません。)

私は数年前はほとんどすべてにC ++を使用していましたが、CまたはC ++のいずれかで処理する必要がある低レベルのタスクではCが優先され、他のすべては他で行う必要があると強く感じ始めています言語全体。(特定の高性能問題ドメインである唯一の可能な例外は、wrt。Blitz ++


10

Cを使用するか、少なくともライブラリコードを作成するときにCインターフェイスをエクスポートします。

明確に定義されていないABIの面倒は必要ありません。


同じ。インターフェースのみで厳格なC。私が最後に欲しいのは、誰かにばかげたオブジェクトフレームワークが押し付けられてしまうことです。
マットジョイナー、2015年

9

C ++ではなくCを使用することについて、私が納得できると考える引数は見たことがありません。ほとんどの人は、C ++が提供する特定の機能を恐れていると思います。しかし、コーディング標準を通じて特定の機能を使用するかどうかを強制できるので、これは私を納得させません。C言語であっても、避けたいことはたくさんあります。C ++を完全に破棄するとは、本質的には、Cより優れたコードを書くのに役立つ具体的な利点がないということです。

さらに、人々は常にC ++コンパイラが存在しないプラットフォームの状況を提起しているようです。確かにここではCが適切ですが、最近では、そのようなプラットフォームを見つけるのは難しいでしょう。


3
「CはC ++より優れている」という発言は、精査に耐えることは決してない。
ジミーJ

6
私はC ++が私に非常に小さな利点を提供し、偶然の複雑さの莫大な量を私に費やすと私は信じています。私が現在C、Pascal、Python、Objective-Cにいるのと同じくらいC ++に習熟するには、約1500ページのC ++教科書と10年の努力が必要だと思います。上記の各言語は、私が使用する環境で言うまでもなく、より強力で、言うまでもなく、直交、コンパクト、そして精神的に便利に使用できます。私の通常の開発環境では、C ++を合理的に正当化できる使用法はありません。
ウォレンP

@Warren他の言語と同じように、使用した分だけ支払います。言語ではなく、C ++で賢くコーディングする方法を決定できない場合。
Dan Olson、

2
そうではありません。あなたがプロジェクトの唯一の開発者である場合、そうかもしれません。しかし、開発者が2人になるとすぐに、戦いが始まります。何?あなたはIoCコンテナを主張しますが、私はデリゲートを実行する他の方法を好みます...ネストされたテンプレートの3つのレベルが好きで、テンプレートはゼロが好きです。混乱。
ウォレンP

私はこの投稿が10歳であることを知っていますが、CとC ++を比較することさえ本当に公正ですか?どちらも(C99以降の)分離された異なる言語であり、どちらにも、それぞれがカバーする利点と欠点があります。C ++のデバッグと保守は難しいですか?Cの明示性により、デバッグを改善できます。Cにジェネリックはありませんか?C ++にはジェネリックがあります!この時点で、他の言語に勝る言語はありません。
ネルガル

9

私がまだ見ていない1つのポイントは、最も重要だと思います。

私が日常的に使用するライブラリのほとんどは、Python、Ruby、Perl、Javaなどのバインディングを備えたCライブラリです。これまでに見てきたように、Cライブラリを19の異なる言語バインディングでラップする方がはるかに簡単です。 C ++ライブラリをラップします。

たとえば、カイロを 1度学び、それ以来3つか4つの異なる言語で使用しました。大勝利!将来も再利用できるようなプログラムを書きたいのですが、他のプログラミング言語にも簡単に取り入れられるようなプログラムを書くのは極端なケースです。

C ++ライブラリをバインドすることは可能ですが、AFAICTは同じではありません。私は他の言語でQt(v3とv4)を使用しましたが、使用するのはそれほど良い方法ではありません。ネイティブライブラリではなく、他の言語でC ++を書くような感じです。(C ++メソッドのシグニチャーを文字列として渡す必要があります!)

一度使用する関数を作成している場合、または世界中がC ++であると考えている場合は、C ++がおそらくより優れた言語です。最初から言語の移植性を考慮して設計している場合、Cはより簡単な言語のように見えます。


「メソッドを文字列として渡す!」これはC ++ではなくQtの欠陥です。あなたは実際にあなたが望むCフレームワークと同じ愚かなメカニズムを持つことができます。Qtのメンバーでさえ、それが間違いであることに同意しています。当時、彼らの心にはこれ以上良い選択肢はありませんでした。
ereOn 2013

7

Windowsカーネル開発はc ++をサポートしていません(悲しいことに)。


どう?どうして?C ++コンパイラから生成されたバイナリはCコンパイラとは異なりますか?ドライバー開発は単にAPIに準拠しているのではないですか?
Dave Van den Eynde 2009年

4
多くのC ++機能はランタイムサポートを必要とするため、カーネルモードで実装するのは簡単ではありません。1つには、異なるメモリ割り当て関数が使用されるため、標準ライブラリのチャンクを置き換える必要があります。例外も一般的に悪いです。
jalf

3
Linux Torvaldsが幸運にも、例外よりも多くの理由で、LinuxでC ++の可能性に火をつけたと付け加えます。他の言語のいくつかのOSがあります:Java、C ++、アセンブラー。アセンブラーだけが妥当な使用法で生き残っています。
マットジョイナー、2015年


それがVisual Studio 2015用であることに注意してください。
LegendLength 2016年

6

Linus TorvaldsがCを好む理由についての面白い発言をここで読むことができます


6
これは、C ++に対する怒りよりも、オブジェクト指向設計に対する半コヒーレントな怒りのようなものです。
ダン・オルソン

16
Torvalds氏は、C ++、emacs、Subversion、OOなど、嫌いなものの長いリストを持っています。一つは、時々 、彼はボタンもう少し彼の唇だろう願い

11
Linusは、人を怒らせたり、怒らせたり、怒らせたりするのが好きです。残念ながら、彼はそれが悪いと宣言する前にC ++ を学ぶことに煩わされていません。残念ながら、彼のカルト信者は彼が言うすべてが真実でなければならないと信じています。
2009年

9
リンクは教育よりも娯楽のためのものだった
ポールディクソン

6
天才でさえ時として無茶苦茶であることの証明。
Kaz Dragon

5

Macのネイティブコードはobjective-cです。PCのネイティブコードはc(window.h)またはc ++(mfc)です。これらの環境の両方で、cをほとんどまたはまったく変更せずに使用できます。コードのライブラリをクロスプラットフォームにしたい場合は、ANSI Cが良い選択のようです。


4

いくつかの理由が考えられます。

満足のいくC ++コンパイラがない場合があります。C ++ははるかに大きな言語であり、最新のC ++を処理できないシステムでCコンパイラを実行しました。

質問者、または彼または彼女と一緒に働く人々は、Cに精通しているかもしれませんが、C ++には精通していません。

プロジェクトはCにある可能性があります。CにいくつかのC ++機能を追加することは可能ですが、保守が困難な混乱を招く可能性があります。どちらか一方の言語を選択することをお勧めします(実際には、通常はC ++)。

質問者は、C ++の学習曲線の古いビューを持っている可能性があります。(正しく近づくと、Cよりも簡単になります。私が見たほとんどの入門書では、正しく近づきません。)

CとC ++は2つの異なる言語であり、時間の経過とともにますます異なるものになることを覚えておいてください。両方を同時にコーディングすることは悪い考えであり、CのようなC ++のサブセットを使用すると、C ++の利点のほとんどが失われます。


3

2つの言語がある環境で作業する場合、パフォーマンスクリティカルな低レベル関数にはCを使用し、ビジネスロジックにはC#/ Javaのようなより機能的/高レベルな言語を使用することができます。これらの関数にC ++コードを使用する場合、JNI /アンマネージコードにCラッパーが必要になるため、Cを単独で使用するよりも複雑になります。


3

CプログラミングでC ++を使用する理由は2つあります。

  • vector そして string私から離れアレイメモリ管理を取得します
  • 厳密な型チェックとキャストにより、他の方法では見逃してしまうすべての迷惑を警告またはキャッチします。

したがって、Cは本当にいくつかのc ++を借用していますが、c ++コンパイラを可能な限り使用しています。他の誰かが答えで言っているように、私は今、実際にこの方法でより多くのC ++を選択していることを発見しました。RAIIを使用した監視/ロックは、最近マルチスレッドプログラムを処理するときに使用したものの1つであり、ファイルを開く/閉じるための別の同様の構成要素です。


3

Cの方が移植性が高いと思います。5年ほど前に、多くの種類のUNIX(AIX、Irix、HPUX、Linux)にコードを移植する作業を行いました。Cコードの移植は簡単でしたが、一部のC ++コードの移植にさまざまな問題がありました。たぶんそれは未熟な開発環境だったかもしれませんが、私はむしろこの理由でC ++ではなくCを使用したいと思います...


1
15年前、私はHPUX、AIX、およびSolarisをターゲットとするC ++プロジェクトの主任開発者でした。C ++の移植性の問題はほとんどありませんでした。ほとんどの問題は、Cシステムコールの非互換性に関するものでした。

1
10年も経たないうちに、私はHPUX、Solaris、およびTru64を使用するプロジェクトに携わり、従来のコンパイラーを使用しました。私たちのナイトリーは決して構築されませんでした。AIXを追加したとき、標準のC ++に切り替えることにしました。
David Thornley、

多分あなたのコードを書いた人々は私が対処しなければならなかったがらくたよりも優れたコーダーでした:-)
Gordon Thompson

3
  1. Cは単純な言語ですが、C ++はそうではありません。多くの人にとって、C ++は複雑すぎて完全に習得できません。http://en.wikipedia.org/wiki/C%2B%2B#Criticismを参照してください

  2. 複雑さのために、通常、異なるプログラマは言語の異なるサブセットしか習得しません。他の人のコードを読むのは面倒です。

  3. 言語の複雑さ、落とし穴が気を散らしすぎ、生産性を損なうことがあります。仕事そのものに集中するのではなく、自分自身が言語そのものと戦っていることがよくありました。Java / pythonはより生産的な選択肢です。

  4. 壊れたCコードのデバッグは、通常、壊れたC ++コードのデバッグよりもはるかに簡単です。

  5. Java / C#とは異なり、C ++標準ライブラリはC標準ライブラリの範囲をほとんど超えていません。

  6. Linus Torvalds(Linux)やRichard Stallman(Emacs)などの有名なプログラマーは、C ++を嫌います。


3
引数#6を読むまで、あなたの答えに投票することを検討しました。
fuz

1

ほとんどのプログラマーは、誰もが品質を最優先事項と考えることを当然のことと考えています。いつもそうとは限りません。Cを使用している場合、C ++は裏で多くのことをしているように見えるかもしれません。C ++での型チェックの厳密さも制限されているように見えるかもしれません。多くの人々は、C ++がこれらの「迷惑」を回避するのを助けることができる種類のバグを導入する危険を冒して進んで進んでいます。


1
うーん、私がCからC ++に(かなり前に)切り替えた理由は、より厳密な型チェックのためでした。ユーザーがコアダンプを経験するよりも、コンパイラに間違いを見つけてもらいたい。

1

考えられる理由は3つあります。1つは、バイナリのサイズが小さく、あらゆるシステムでCコンパイラを利用できるため、Cは組み込みシステムにより適していることです。2つ目は移植性です。Cはより小さな言語であり、ANSI Cコードはどこでもコンパイルできます。C ++の移植性を壊す方が簡単です。最後は言語そのものです。C ++はより難しく、間違いなく非常に不十分に設計された言語です。Torvaldsの不満は上に報告されています。また、C ++のよくある質問の回答(http://yosefk.com/c++fqa/)もご覧ください


5
そして、もしあなたが賢いなら、FQAを見た後で、それは本当にC ++を理解していないがとにかくそれを嫌っている誰かによるハックジョブであることに気付くでしょう。
David Thornley、2010年

1

移植性が問題になる可能性があります。Gordon Carpenter-Thompの答えとは異なり、それはむしろ、異なるバージョンのlinux / unixでのlibstdc ++の異なるバージョンのランタイムサポートであると提案します。これに関する良い議論については、このリンクを参照してください。少し抜粋:

C ++アプリケーションのさまざまな部分で使用されるランタイムサポートコードには互換性が必要です。プログラムのある部分でdynamic_castまたは別のオブジェクトによって提供されるオブジェクトをキャッチする必要がある場合、両方の部分で特定の実装の詳細(vtableの検索方法、スタックの巻き戻し方法など)について合意する必要があります。

C ++および同様の機能を持つGCCでサポートされている他のいくつかの言語の場合、そのような詳細はC ++ ABIによって指定されます。GCCで使用されるABIが変更されると、異なるGCCバージョンで作成された互換性のないライブラリが作成されます。同じことがプレーンCにも当てはまりますが、C ABIははるかに単純で、ずっと以前から存在しているため、かなり安定しています。


1

私はここで双方向の多くの提案に従うことができます。しかし、最終的には、a)同等の単純なb)同等の複雑なものになります。

誰かが一種の言語の複雑さの測定を「発明」したかどうかはわかりません。

0から10のスケールでは、Cを2または3と評価しますが、C ++は8から10の間です。C ++は最も複雑な言語の1つだと思いますが、AdaやPL1などは知らないため、他の言語と比べてそれほど複雑ではないかもしれません。

C ++はCのすべての複雑度を継承するため、Cの複雑度レベルを下回ることはできません。

私としては、スクリプト言語とCを使用する方がはるかに快適です。そのため、結局のところ、次の質問に答える必要があります。「もっといいの?」


1

私がCで見つけた最も有用なことは、名前空間とオーバーロードの欠如です。関数名とシンボル名は一意の識別子です。これらのシンボルが使用されている場所を見つけるには、grep、ソースコードファイルを検索、検索結果に場所が表示されます。

新しい機能やコンポーネントを古い絡み合ったシステムに配線する場合に不可欠です。

洗練されたコールグラフ作成ツールなしでは、C ++ではこれを簡単に行うことはできません。


0

ほとんどの人はCとC ++は何らかの形で関連していると考えているようですが、悲しいことに間違っています。C ++はCとは完全に異なる言語です。

C ++では、オブジェクトとそれらがどのように相互に関連するかという観点から考えます。Cでは、APIの観点から考えます。それは、日と17の違いのようなものです。

貧弱な類推:誰かが英語に中国語を追加してそれをEnglish ++と呼ぶ場合、最新のラブレターに中国語の行を追加することはおそらく快適ではないでしょう。


0

以下は、プロジェクトをCに制限することが有益である理由のすべてです。

  • 言語がはるかに単純であるため、コンパイルが高速
  • 実行時のサポートが少なくて済むため、低レベル環境により適したものになります
  • 他の言語とのインターフェースがはるかに簡単
  • スタックで可変サイズの配列をサポート
  • 名前のマングリングがないため、アセンブリコードが読みやすくなります。
  • 異なるコンパイラによって生成されたコードは、事実上の標準アプリケーションバイナリインターフェイスであるため、簡単に組み合わせることができます。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.