web-dev-qa-db-ja.com

C ++コードでCを使用/混合しますか?

C++でCを使用するのは悪いですか?

多くの人が、C++でCを使用するのは安全性が低く、より多くのメモリ管理が必要なため悪いと言っています。私は、あなたが何をしているのかを知っていて、あなたがあなたの「新しい」を削除し、あなたの「マロック」を解放する限り、Cは問題ではないと彼らに言い続けます。

私は現在、std::stringchar*をめぐる議論が行われているフォーラムに参加しています。単純なchar*メモリブロックを割り当てる方が効率的であり、割り当てを解除する限りは問題ないと言う人もいます。一方、std::stringはメモリ管理が含まれていないが効率が悪いため、優れていると言われています。

したがって、ここでの主な質問は次のとおりです。

  • C/C++の混合は悪いですか? C++をコーディングする場合は、100%C++のみを使用する必要がありますか?

どんな答えでもいただければ幸いです!

22
Brad

私は、あなたが何をしているのかを知っていて、新しいものを削除し、mallocを解放する限り、Cは問題ではないと彼らに言い続けています。

これは本当です;非常に注意深く、手動でクリーンアップすることを確認すれば、問題はありません。しかし、あなたは本当にそれをする時間がありますか? newを呼び出すたびに、std::bad_allocがスローされる可能性があります。 常にキャッチすべてスローされ、リソースを手動でクリーンアップできる例外はありますか?

そのようなコードを書くのは非常に面倒であり、まれな失敗の場合でも、そのように書かれたコードが正しいことを絶対に確信することは難しいので、その答えを「いいえ」と推測するのは危険です。

答えが「はい」の場合、なぜリソース管理について心配するのに多くの時間を無駄にしているのですか?スコープにバインドされたリソース管理(SBRM、より一般的にはリソース取得として知られている初期化(RAII))などのC++イディオムや、標準テンプレートライブラリなどのライブラリがあり、正しいコードをより簡単に記述できます。あなたがする必要がないのに、なぜ物事は難しい方法をするのですか?

C++をコーディングするときは、100%C++のみを使用する必要がありますか?

はい。ただし、必要なことを実行するCライブラリがある場合、または使用したいレガシーCコードがある場合は、そのコードを確実に使用できます。必ず注意してください。多くの場合、Cコードと相互運用する最もクリーンな方法は、その周りにC++ラッパーを作成することです。

17
James McNellis

私の強い信念は、あなたの質問はCやC++とはまったく関係がないということです。あなたの質問は、疑わしい効率を安全と交換することについてです。はい、Cの方が効率的です。しかし、どれだけ効率的ですか?そして、あなたはそれに対して何を支払いますか?これらはあなたが答えるべき質問です。ほとんどの場合、stringとconst char *のオーバーヘッドは目立ちません。効率が非常に重要なアプリケーションを開発している場合は、そもそもCでコーディングしてみませんか?

12
Armen Tsirunyan

回答とコメントの二極化には本当に驚いています。

私の目には、答えは非常に単純です。

C++プロジェクトを作成するときは、C++を使用し、C(およびファミリ)を避け、標準ライブラリとSTLに固執します。均質なC++インターフェイスを確保します(結局のところ、C++プロジェクトです!)Cで記述された外部プロジェクトをCで使用する場合は、もちろんそれを使用できます。 (以下の例を参照)

2つの代表的な例:

  1. 科学的計算を行うC++プログラム/ライブラリを作成します。私は間違いなくGSL(GNU Scientific Library)を使用し、Cで記述されています。std::unique_ptrtypedefに吸収できる注意点(GSL内の特定の構造体や関数用の特殊な初期化関数や解放関数など)はわずかです。エラー処理の問題もあります。エラーコードのチェックは、必要に応じて例外メカニズムで抽象化することができます。または、計算関数内にエラーコードを含めておくことができます。 GSLにはエラーハンドラーを設定する方法があります。他のいくつかのCライブラリにはそのような機能があると思います。

  2. 恐ろしくCベースのWin32APIを使用してC++プログラムを作成します。ディレクトリ内のファイルの読み取り、ファイルが存在するかどうかの確認など、重いGDI +やその他のものではなく、軽いAPIの使用法について話しています。 Win32APIが公開するすべてのC関数をNiceC++スタイルの関数でラップするのが好きです。ただし、必要な例外を除いて、引数としてstd::stringバッファーを渡す代わりにchar*を返します。

どちらの例もかなり...浅い...とは思いますが、一般的な考え方を表現していると思います。

7
rubenvb

はい、CとC++を混在させるのは悪いことです。理由は、パフォーマンスやセキュリティとは何の関係もありません。

それは保守性の悪い原因です:
* C++プログラマーは、すべてのコードがC++のように動作することを期待しています。
* Cプログラマーは、すべてのコードがCのように動作することを期待しています。

したがって、C++とCを組み合わせると、物事がどのように機能するかについて、両方のプログラマーの期待を破ることになります。

4
UnixShadow

ここでのより良い質問は、なぜCを使用するのかということです。パフォーマンス?第一に、同じ機能を持つプログラムでは、測定可能なパフォーマンスの違いはないと思います。次に、特定のケースではC++の方が遅いことをプロファイリングして証明する必要があります。第三に、C++の代わりにCを使用することで、大量のアプリケーションセキュリティを放棄していることになります。

3
Puppy

std :: string vs char *で引数を再グレードします。

std :: stringはそのchar *(ヒープchar *の場合)より遅くなることはありません。多くの実装は、プライベートメモリプールを使用するため、はるかに高速です。そしてとにかく、std :: stringの堅牢性は、(ありそうもない)パフォーマンスヒットをはるかに上回ります

2
pm100

もちろん、答えは次のとおりです。状況によって異なります。

一般に、混乱を引き起こす可能性があり、さらに見つけにくいバグにつながる可能性のあるものを混在させないようにします。 「あなたは自分のしていることを知っている」からといって、次にあなたのコードに触れた人があなたのしていることを知っているとは限りません。自分だけが使用するコードを開発している場合は、おそらく大丈夫ですが、そうなることはめったにありません。

注意が必要な場合は、パフォーマンスにCを使用しても問題ありません。ただし、パフォーマンスが必要であることがわかっている場合にのみ実行する必要があります。時期尚早の低レベルの最適化は悪魔の仕事です。

Std :: stringではなくchar *を使用すると、パフォーマンスに顕著なメリットがもたらされることは非常にまれなケースであり、確かにそうなる場合にのみ、メモリ管理の手間をかけるだけの価値があります。

2
Gerald

あなたがテクニックについて話しているなら、私は上記をすることは大丈夫だと言うのに注意するでしょう。

Cスタイルのプログラム編成手法を使用してC++プログラムを作成すると、多くの保守性の問題が発生する可能性があります。一般に、プログラマーはオブジェクト指向言語が提供する多くの利点を無視しています。 C構文の多くが有効なC++であり、多くのコーディング手法の転送がC++で実行する必要があるという意味ではありません。

とはいえ、C関数などの使用に注意する限り、C関数などの使用は問題ありません。場合によっては、そうしなければなりません。

1
J. Polfer

ここでの簡単な答えは、profile;です。 あなたのケースでどちらが最適かを判断し、賢く使用してください!

1
Nim

C++でCを使用するのは悪いですか?

主観的な質問ですが、私の意見では、c ++プログラムでcを使用しないように十分な対策を講じてください。

多くの人が、C++でCを使用するのは安全性が低く、より多くのメモリ管理が必要なため悪いと言っています。私は、あなたが何をしているのかを知っていて、新しいものを削除し、mallocを解放する限り、Cは問題ではないと彼らに言い続けています。

あなたは、c ++が克服するように設計された欠陥と危険性を再導入していますが、それはc ++プログラムで行われる方法ではありません。

「cwithc ++機能」または「c ++ withc機能」のコードベースを入力するコードを定期的にチェック/拒否/書き換えます。私は、mallocやfreeなどを変更してルート名前空間でアサートすることさえします(とりわけ)。

私は現在、std :: stringとchar *をめぐる議論が行われているフォーラムに参加しています。単純なchar *メモリブロックを割り当てる方が効率的であり、割り当てを解除する限りは問題ないと言う人もいます。一方、std :: stringはメモリ管理が含まれていないが効率が悪いため、優れていると言われています。

c ++で文字列を表すためのオプションはstd :: stringよりも多くあります。

私の意見では、文字列を表し、特定の目的を果たす、または追加のコントラクトに従う(必要な場合)新しいクラスを作成することは完全に有効です。このような文字列表現のコントラクトの一部は、(もちろん)動的メモリが使用されている場合にnew[]/delete[]を使用して独自のリソースを管理することです。

効率がそれほど重要であり、std::stringが特定のタスクにとって理想的とは言えない場合、c ++は、c ++で特殊なインターフェイスを作成することにより、これらの特定のケースに対する意図を表現するのに十分強力です。これが許容できる場合(imo)はたくさんありますが、時間の投資に見合うだけの価値があるとは限りません。いずれにせよ、cのイディオム/スタイル/危険をc ++プログラムに統合するよりも管理が簡単です。

したがって、ここでの主な質問は、C/C++の混合は悪いですか? C++をコーディングするときは、100%C++のみを使用する必要がありますか?

ニーズに合わせて再利用可能なオブジェクトベースのソリューションを作成することをお勧めします。提供されている例の危険性は完全にカプセル化でき(この最適化が本当に時間投資の価値がある場合)、パフォーマンスを低下させることなく、保守性を向上させて、c ++イディオムを使用するように記述できます。

1
justin

stringconst char *の特定のケースでは、文字列定数(およびのみ文字列定数)を保持するすべての変数に裸のconst char *を使用する必要があります。 stringを必要とするAPIに渡す場合にのみ、stringに変換します。これを一貫して行うことで、膨大な数のグローバルコンストラクターを排除でき、メモリ割り当ての問題を引き起こさず(文字列定数は永続的な定数データであるため)、IMOは実際にコードを明確にします-const char *が表示され、それが文字列になることがわかります絶え間ない。

1
zwol

さて、私は奇妙な状況にあります。私はC++(C++コンパイラが使用され、C++という用語が使用されている)であるはずのシステムに取り組んでいますが、すべてがCで書かれています。これは、証明しなければならないところまで来ているので、非常にイライラします。 'C++でコーディングしている場合でも、C++を使用する方がCよりも優れています。 std :: stringを導入したとき、それはすべて地獄でした。私の考えでは、今ではすべてが雑然とし始めています(CとC++の混合)。エラー処理のまれな例があります。実際、私は3つのシステム全体のtry-catchステートメントを数えることができると思います。コードは乱雑で、メモリリークが目立ち、エラーを見つけることは干し草の山の中の針です。 C++関数で置き換えることができるコードは数百行あります。コードを書く方が効率的で、クリーンで、理解しやすいと思います。

私の経験から、もちろん、CとC++を組み合わせることができます。やりたいことはほとんど何でもできますが、何が起こっているのかを維持し、デバッグし、実際に把握することが問題になります。メモリ割り当てをクリーンアップしようとしていると言うのは簡単ですが、他の誰かがあなたのコードを使用していて、使用していない可能性があります。たぶん、あなたはそれをするのを忘れて、何か生産的なことをするためにその時間を使う代わりに、ばかげたバグを見つけることに時間を浪費します。議論があるべきだとは思いません。 C++を実行するときは、C++を実行します。 Cを実行するときは、Cを実行します。

0
Jan Swart