• ベストアンサー

try catchは避けるべき?

C++の質問ですが、 gotoレスは当たり前として(C++に限ったことではないですが)、 try catchもやっぱり避けるべきですか?

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

C++ の例外機能の使い方が時として問題になるのは、エラーの発生点(through した点)とエラーを補足した点(catch した点)が離れているからです。 一方、例外処理の思想自体が、 ・エラーの発生点は、具体的なエラーの内容はわかるが、修復方法はわからない。 (srqt() の引数が、-1 だったらエラーだというのは、sqrt() の中ではわかるが、どうして -1 が来たのか、どう回復したらいいのかはわかない) ・エラーの補足点は、具体的なエラーの内容はわからないが、エラーの原因や対処方法は知っている (sqrt() の引数が「範囲外」だったら、入力されたデータがおかしい。だから、もう一度入力をしてもらおう) という、発生点と補足点の距離をふまえて適切に処理を仕様というところから来ています。 なので、「例外処理の思想」にはずれないように、発生点の役割と、補足点の役割が把握できている限り問題はありません。 逆に、「エラーが起こったら、とりあえず例外処理」という発想だと、設計が破綻することが多いですね。 goto レスにしても、今では「あたりまえ」ではありません。goto を使うべきところで、goto を回避するための「テクニック」を駆使すると、制御の流れがとても不自然になります。

karatekakarateka
質問者

お礼

ご回答ありがとうございます。 >・エラーの発生点は、具体的なエラーの内容はわかるが、修復方法はわからない。 (srqt() の引数が、-1 だったらエラーだというのは、sqrt() の中ではわかるが、どうして -1 が来たのか、どう回復したらいいのかはわかない) >・エラーの補足点は、具体的なエラーの内容はわからないが、エラーの原因や対処方法は知っている (sqrt() の引数が「範囲外」だったら、入力されたデータがおかしい。だから、もう一度入力をしてもらおう) とても分かり易い具体例、勉強になりました。

その他の回答 (4)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.5

try/catch(正確には監視ブロック)は適切に使うべきという意見ばかりのようですので、監視ブロックを使わなければどうなるかについて、少し書いてみたいと思います。 まず、監視ブロックがどこにもなければ、送出された例外は捕捉されませんので、std::teminate()が呼び出されます。これはエラー処理を放棄したのと同じ意味になります。 また、監視ブロックを使わなければ、例外処理にまつわるオーバーヘッドがないかというと、そんなことはありません。例外指定 throw() がない関数を、デストラクタを持つ自動オブジェクトの生存期間で呼び出した場合には、処理系にもよりますが、巻き戻し用のコードがどっさり生成されます(遅くて大きくなります)。 例外処理のオーバーヘッドをなくすには、コンパイルオプションで例外処理を抑止するのが一番ですが、その状態でライブラリが例外を送出した場合は、何が起こるか全くわからなくなり、信頼性の高いソフトウェアを実装することは不可能です。

karatekakarateka
質問者

お礼

ご回答ありがとうございます。 >例外処理のオーバーヘッドをなくすには、コンパイルオプションで例外処理を抑止するのが一番ですが、その状態でライブラリが例外を送出した場合は、何が起こるか全くわからなくなり、信頼性の高いソフトウェアを実装することは不可能です。 確かにそうですね。試験工程でいつも痛い目にあっています。

  • rigidbody
  • ベストアンサー率60% (20/33)
回答No.4

いいえ。そんな事はないと思いますよ。 使うか否かは、状況により変わると思います。 【長所】 ・厳格できめ細かなエラー処理が、少ないコードで実現できる 【短所】 ・遅くなる可能性がある きちんと使えば、エラー処理コードが凄く単純化されます。こういう機能を持たない言語で同様のエラー処理をする事は、恐らくできないと思います。 が、私は極力避けています。何故なら"エラー処理の価値が低い分野のソフトを扱っている為"です。 その代わりエラーは、大量のアサーションコードで捕まえるようにしています。 More Effective C++という本に、エラーハンドリングコードのオーバーヘッドについて詳細が書かれています。 私はそれを鵜呑みにしている、って感じです。

karatekakarateka
質問者

お礼

ご回答ありがとうございます。 >エラーは、大量のアサーションコードで捕まえるようにしています。 設計工程がしっかりしていれば、確かに速度で優れるかもしれませんね。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

gotoもtry/catchも使うべきところで適切に使うべきものです。下手糞な使い方が問題になるのは、ifでもforでも同じです。 ところで、try/catchを使わなければ例外処理と無縁でいられるかというと決してそんなことはありません。 C++を使う場合には、常に例外と隣り合わせであることを認識すべきです。

  • MASATO3
  • ベストアンサー率60% (27/45)
回答No.1

C++の原則は 「エラーの通知には例外を使おう」 だと思います。 よってエラー発生を検出するためにtry catchを使うのは問題ないでしょう。 ところでgotoも、使ってはいけないものではなく、場所をわきまえれば使って良いと思いますよ。

karatekakarateka
質問者

お礼

ご回答ありがとうございます。 >「エラーの通知には例外を使おう」 なるほど、勉強になりました。

関連するQ&A

  • C++のtryとcatch

    C++で、例外処理としてtryがあるのですが、どういった使い方をするのでしょうか? それと、catchも使い方がわかりません。 どなたか教えてください。 よろしくお願いします。

  • try catch

    public String getMessage() { try { .... return "okay"; } catch (Exception e) { return "error"; } のように、エラーが起こったら catch 句で String を返すとうプログラムはありですか?

    • ベストアンサー
    • Java
  • try catchについて

    try catchの動きで質問があります。 以下が簡略化したソースです。 -------ここから--------------------- ストリーム1; ストリーム2; try{ try{ //ストリーム1を使った処理 }catch(IOException e){ throw e; }finally{ //ストリーム1のクローズ } try{ //ストリーム2を使った処理 }finally{ //ストリーム2のクローズ } } catch(IOException e){ throw new hogeException(); } ------ここまで-------------------------- 内側でスローされた例外は、外側でcatchされるのですか? また、内側でcatchをしなかった場合、外側でcatchされるのですか? この2点を教えていただきたいです。 よろしくお願いします。

    • ベストアンサー
    • Java
  • try ~ catch構文が使えない

    ロリポップサーバを利用しています。 http://lolipop.jp/?mode=manual&state=hp&state2=cgi try ~ catchやthrowでエラーがでます。 仕方なくcatch文を外したり、throwを使わない構文に していますが、どうも不安です。 try ~ catchやthrowを使えないとあきらめるしか ないのでしょうか? PHPのバージョンが対応していないのでしょうか?

    • ベストアンサー
    • PHP
  • TRY CATCHでシステムエラーを検知できない

    TRY CATCHをネストさせた状態で、 テーブルがドロップされていることを検知するにはどうすればよいでしょうか? BEGIN TRY   ★   BEGIN TRY     ▲   END TRY   BEGIN CATCH   END CATCH CATCH END CATCH としているときに、 ★の位置だとテーブルのドロップはCATCH できるのですが ▲の位置だとテーブルのドロップはCATCH できないようですが、 テーブルがドロップされていることを検知するにはどうすればよいでしょうか?

  • try catch finally は必要か???

    smtpでメールを同期送信しております もちろん通常とおり前後をtry catch finally で囲んでおります 送信に時間が掛るので、今回非同期送信に改めました それに伴いイベントハンドラーも追加しました するとエラーが発生してもcatchには来ずイベントハンドラーのエラー発生の判定部分に来ます 質問? イベントハンドラーを設置した場合、try catch finallyは取り外しても良いのでしょうか?

  • Try, Catch についての質問

    すみません!!VB超初心者です。 PriceとCostのテキストボックスにマイナスやアルファベットを記入して計算ボタンを押した場合、Errorを示すメッセージボックスを出したいのです。 ところが、このプログラムだとちゃんと正の数字を入れた場合でもエラーのメッセージボックスがでてしまいます・・・。これはなぜなのでしょうか?よろしくお願いします! Dim priceDecimal, costDecimal, answerDecimal As Decimal Try priceDecimal = Decimal.Parse(txtprice.Text) costDecimal = Decimal.Parse(txtcost.Text) answerDecimal = Decimal.Parse(lblcomission.Text) Try txtprice.Text = priceDecimal < 0 txtcost.Text = costDecimal < 0 Catch priceException As FormatException MessageBox.Show("You have entered Invalid Data.", "Error", MessageBoxIcon.Exclamation) End Try Catch costException As FormatException MessageBox.Show("You have entered Invalid Data", "Error",MessageBoxButtons.OK, (MessageBoxIcon.Exclamation) End Try answerDecimal = Commision_rate_Decimal * (priceDecimal - costDecimal) lblcomission.Text = answerDecimal.ToString("C") End Sub

  • phpのtry and catchについて

    PHPについて質問ですが try and catchの命令についてPHP5から対応していたはずですが さくらインターネットで0除算の処理を作成し、試してみたのですが 500エラーとなってしまいます。 どなたか、ご存知の方はいらっしゃいませんでしょうか?

    • ベストアンサー
    • PHP
  • 2つの“try ~ catch”

    こんにちは。 Javaの簡単なネットゲームのサンプルで勉強しています。 ゲームに使う変数[プレイヤー名、プレイヤー座標X,Y プレイヤー残体力]は、プレイヤーごとにハッシュテーブルに格納されることがわかりました。 JavaのハッシュテーブルのデータをJSObjectを使ってJavaScriptに渡したいのですが、ハッシュテーブルも、 JSObjectも try~catch を使っています。 ハッシュテーブルのtry~catch内でなければゲームに使う変数は取得できないと思うのですが、try~catch にJSObjectのtry~catchを入れ子にするようなプログラムの組み方がわかりません。 このような場合どのように組むのでしょうか? ご教授ください。

  • Javaのエラー処理(try catch)について

    Java初心者です。とても基本的な質問、というか変な質問で恐縮です。あるアプリケーション開発用のソフトウェアが使っていて、これ上に文字列編集の機能を実装しています。要はただの関数なのですが、このソフト上ではJavaで書く必要があるので以下のように記述しました。UI画面上からユーザが入力した文字列が"ZenkakuNumber"という名前の変数でこのコードに渡されて来ます。それから、文字列を編集した後で最後に文字列を返します。ただそれだけの簡単な関数なのですが、上司のレビュー時にエラー処理(try and catch)があった方がいいのではないかと指摘を受けました。もちろん、コードにエラー処理があった方がいいのはわかるのですが、このようなコードの場合、どのようなエラー処理を記述すればよいのでしょうか。インプットとして文字列を受け、文字列を返すだけなので、ArrayIndexOutOfBoundsExceptionエラーもありえなければ、IOExceptionもありえないと思います。どのようなtry and catchを書けばいいのか、何かアイデアがございましたら教えて下さい。質問がまわりくどくなったのはパッケージを使っているので、完全にJava単体の質問とも異なる可能性があると思ったからです。 MyFunc ---------------------------------------------------- StringBuffer HankakuNumber = new StringBuffer(); for(int i=0; i<ZenkakuNumber.length(); i++) { char c = ZenkakuNumber.charAt(i); if(c >= '0' && c <= '9') { HankakuNumber.append((char)(c - '0' + '0')); } else { HankakuNumber.append(c); } } return HankakuNumber.toString(); ---------------------------------------------------- ↑このコードにエラー処理を加えたい

    • ベストアンサー
    • Java

専門家に質問してみよう