35

組み込みプラットフォームの開発者はC++ exceptionsSDKsなぜ .

たとえばBada SDK、例外の使用法について次の回避策を提案していますが、これは非常に見苦しく見えます

 result
 MyApp::InitTimer()
 {
    result r = E_SUCCESS;

    _pTimer = new Timer;

    r = _pTimer->Construct(*this);
    if (IsFailed(r))
    {
        goto CATCH;
    }

    _pTimer->Start(1000);
    if (IsFailed(r))
    {
        goto CATCH;
    }

    return r;
 CATCH:
     return r;
 }

この動作の理由は何ですか?

私の知る限り、ARMコンパイラは完全にサポートC++ exceptionsしており、これは実際には問題ではありません。ほかに何か?ARMプラットフォームでの例外の使用と巻き戻しのオーバーヘッドは、そのような回避策を作成するのに多くの時間を費やすほど大きなものですか?

多分私が気づいていない何か他のものはありますか?

ありがとうございました。

4

6 に答える 6

56

ちょうど私の2セント...

私は組み込みシステムについてのみ相談しますが、そのほとんどはリアルタイムおよび/またはセーフティ/ライフクリティカルです。それらのほとんどは256K以下のフラッシュ/ROMで動作します。つまり、これらは1GB以上のRAM/フラッシュと1GHz以上のCPUを備えた「PCのような」VMEバスシステムではありません。それらは深く埋め込まれ、いくらかリソースに制約のあるシステムです。

C ++を使用する製品の少なくとも75%は、コンパイラーで例外を無効にします(つまり、例外を無効にするコンパイラースイッチでコンパイルされたコード)。私はいつも理由を尋ねます。信じられないかもしれませんが、最も一般的な答えは、ランタイムやメモリのオーバーヘッド/コストではありません。

答えは通常、いくつかの組み合わせです。

  • 「私たちは、例外安全なコードを書く方法を知っているとは確信していません」。彼らにとって、戻り値のチェックは、より馴染みがあり、複雑ではなく、より安全です。
  • 「例外的な場合にのみ例外をスローすると仮定すると、これらはとにかく[独自の重大なエラーハンドラルーチンを介して]再起動する状況です。」
  • レガシーコードの問題(jalfが述べたように)-彼らは、コンパイラが例外をサポートしていなかった、またはそれらを正しくまたは効率的に実装しなかった何年も前に始まったコードを扱っています

また、オーバーヘッドについてはあいまいな不確実性/恐れがあることがよくありますが、ほとんどの場合、それは定量化されていない/プロファイルされていないため、そこに投げ出されて額面通りに受け取られます。例外のオーバーヘッドが3%、10%-15%、または〜30%であると述べているレポート/記事を表示できます-選択してください。人々は自分の視点を前進させる図を引用する傾向があります。ほとんどの場合、記事は古く、プラットフォーム/ツールセットは完全に異なるなどです。そのため、Roddyが言うように、プラットフォームで自分自身を測定する必要があります。

私は必ずしもこれらの立場のいずれかを擁護しているわけではありません。組み込みシステムでC++を使用している多くの企業から聞いた実際のフィードバック/説明を提供しているだけです。あなたの質問は「なぜ多くの組み込み開発者が例外を回避するのか」です。 ?」

于 2011-07-13T15:11:23.803 に答える
19

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

  • 古いバージョンのコンパイラは例外をサポートしていなかったため、例外が使用されていない多くのコードが記述されています (そして規則が確立されています)。
  • 例外にはコストがかかり、合計実行時間の 10 ~ 15% になる可能性があります (実質的に時間がかからないように実装することもできますが、代わりにかなりの量のメモリを使用しますが、これはおそらくあまり望ましくありません)。組み込みシステムのいずれか)
  • 組み込みプログラマーは、コードのサイズ、パフォーマンス、そして特にコードの複雑さについて少し偏執的である傾向があります。彼らは、「高度な」機能が自分のコンパイラで正しく動作しないのではないかと心配することがよくあります (多くの場合、彼らも正しいのです)。
于 2011-07-13T11:13:07.037 に答える
8

最近はほとんどがFUDだと思います。

例外には、コンストラクター/デストラクタを持つオブジェクトを作成するブロックへの入口と出口で小さなオーバーヘッドがありますが、ほとんどの場合、実際には豆の缶にはなりません。

最初に測定し、次に最適化します。

ただし、例外のスローは通常、ブール値のフラグを返すよりも遅くなるため、例外的なイベントに対してのみ例外をスローします

あるケースでは、デバッグに使用する可能性がある例外がスローされるたびに、RTL がシンボル テーブルから印刷可能なスタック トレース全体を構築していることがわかりました。ご想像のとおり、これは良くないことでした。これは数年前のことであり、これが明らかになったとき、デバッグ ライブラリは急いで修正されました。

しかし、IMO では、例外を正しく使用することで得られる信頼性は、わずかなパフォーマンスの低下をはるかに上回ります。それらを使用しますが、慎重に行ってください。

編集:

@jalf はいくつかの良い点を指摘しています。上記の私の回答は、なぜ多くの組み込み開発者が一般的にまだ例外を軽視しているのかという関連する質問を対象としています。

ただし、特定のプラットフォーム SDK の開発者が「例外を使用しないでください」と言った場合は、おそらくそれに従う必要があります。ライブラリまたはコンパイラでの例外の実装に特定の問題がある可能性があります。または、独自のコードで例外の安全性が欠如しているため、コールバックで例外がスローされて問題が発生することを懸念している可能性があります。

于 2011-07-13T11:21:52.160 に答える
5

他の回答では、「ゴトは悪である」とは反対の意見が支持されています。この反対意見が煽られることを知っているので、私はこのコミュニティwikiを作成しています。

塩に値するリアルタイムプログラマーなら誰でも、この使用法を知っていますgoto。これは、エラーを処理するために広く使用され、広く受け入れられているメカニズムです。多くのハードリアルタイムプログラミング環境は、<setjmp.h>を実装していません。例外は、概念的にはsetjmpとの制約付きバージョンですlongjmp。では、基礎となるメカニズムが禁止されているのに、なぜ例外を提供するのでしょうか。

スローされたすべての例外が常にローカルで処理されることが保証できる場合、環境は例外を許可する可能性があります。問題は、なぜこれを行うのかということです。唯一の正当化は、gotoが常に悪であるということです。まあ、彼らは常に悪ではありません。

于 2011-07-13T11:55:09.460 に答える
5

例外に対するこの態度は、パフォーマンスやコンパイラのサポートとはまったく関係がなく、例外はコードに複雑さを加えるという考えにすべて関係しています。

この考えは、私が知る限り、ほとんど常に誤解ですが、考えられない理由で強力な支持者がいるようです.

于 2011-07-13T11:49:44.627 に答える
4

最新の C++ コンパイラは、実行時の例外の使用をオーバーヘッドの 3% まで削減できます。それでも、極端なプログラマーがそれが高価であると感じた場合、彼らはそのような汚いトリックに頼っていたでしょう.

こちらの Bjarne Strourstrup のページで、Why use Exceptionsを参照してください。

于 2011-07-13T11:21:37.950 に答える