6

だから私はいくつかのコードを書いていて、構文、型、および他のコンパイル時のエラーを除いて、C++は他の例外をスローしないことに気づきました。だから私はこれを非常に簡単なプログラムでテストすることにしました:

#include<iostream>

int main() {
    std::count<<5/0<<std::endl;
return 1
}

g ++を使用してコンパイルすると、g ++は、0で除算しているという警告を表示しました。しかし、それでもコードはコンパイルされました。それから私がそれを実行したとき、それはいくつかの非常に大きな任意の数を印刷しました。私が知りたいのは、C ++はどのように例外を処理するのですか?0による整数除算は、例外がスローされてプログラムが終了する場合の非常に簡単な例です。

基本的に、プログラム全体を巨大なtryブロックで囲み、特定の例外をキャッチする必要がありますか?Pythonでは、例外がスローされると、プログラムがすぐに終了してエラーが出力されることを知っています。C ++は何をしますか?実行を停止してプログラムを強制終了する実行時例外さえありますか?

4

4 に答える 4

12

実行時例外がありますが、「間違っている」すべてが実行時例外をスローするわけではありません。たとえば、範囲外の配列にアクセスしたり、nullポインターを逆参照したりすることは、単に「未定義の動作」です。つまり、何でも起こり得るということです。ゼロによる除算も「未定義」のカテゴリに分類されます。

例外ではなく「未定義の動作」をもたらす一部の操作の理論的根拠は、効率です。範囲外の配列アクセスでは、例外をスローする必要があるとします。次に、コンパイラは、配列アクセスごとにコードを生成して、範囲外かどうかをチェックし、範囲外の場合は例外をスローする必要があります。これは多くのチェックであり、そのほとんどは不要です。代わりに、コンパイラが行うことは、要素が範囲内にあると仮定して、要素アクセスの命令を生成することです。範囲外の場合は、何が起こっても(セグメンテーション違反など)発生します。チェックを実行したい場合は、いつでも明示的にコーディングできます。

これにより、チェックを実行するタイミングと実行しないタイミングを選択できるため、C ++は常にチェックを実行する言語(JavaやPythonなど)よりも強力になります。(一方、C ++はJavaやPythonよりも安全性が低くなります。トレードオフです)。


例外がスローされたがどこにもキャッチされなかった場合に何が起こるかについては、通常、コンパイラの実装は例外のを含むエラーメッセージを出力しますwhat()。あなたの例では、実行時例外がスローされていないため、これは適用されません。

于 2012-06-07T04:35:44.323 に答える
3

はい、実行時の例外があります。例はout_of_range、によってスローされる、vector::atです。

ただし、ゼロによる除算は定義されていません(C++0x§5.6/4):

/または%の第2オペランドがゼロの場合、動作は定義されていません。

そのため、コンパイルに失敗したり、作成された例外をスローしたり、「非常に大きな任意の数」を出力したり、セグメンテーション違反を起こしたりする可能性があります。

于 2012-06-07T04:33:13.593 に答える
2

C ++は、C ++標準で明確に定義されている標準例外のみをスローします(はい、いくつかの実行時例外が含まれています) 。

整数をゼロで割ったものは、標準のC ++例外ではありません(技術的には未定義動作です)。したがって、暗黙の例外はスローされません。特定のコンパイラは、実行時エラーをある種の例外にマップする場合があります(これについては、コンパイラのドキュメントを確認する必要があります。一部のコンパイラは、ゼロ除算をある例外にマップします)。その場合、その特定の例外をキャッチできます。ただし、これは移植可能な動作ではなく、すべてのコンパイラで機能するとは限らないことに注意してください。

最善の方法は、エラー条件(除数がゼロに等しい)を自分でチェックし、そのような場合に明示的に例外をスローすることです。

編集:コメントに答える

class A
{
    public:
         void f()
         {
             int x;
             //For illustration only
             int a = 0;
             if(a == 0)
                  throw std::runtime_error( "Divide by zero Exception"); 
             x=1/a;
         }

         A()
         {
              try
              {
                   f();
              }
              catch(const std::runtime_error& e)
              {
                   cout << "Exception caught\n";
                   cout << e.what(); 
              }
         }
 };     
于 2012-06-07T04:36:32.377 に答える
0

Visual C ++は、これをゼロ除算エラーとして正しくフラグ付けします。したがって、コンパイルされない場合は、実行することに問題はありません。

于 2012-06-07T04:31:31.340 に答える