先頭へ戻る

エラーについて | Programming Place Plus 新C++編

Programming Place Plus トップページ -- 新C++編

先頭へ戻る

このページの概要

このページでは、「エラーについて ~プログラムが間違っていたらどうなるか~」を取り上げます。

以下は目次です。



エラーとは

エラー(用語集) (error) とは「誤り」のことです。何かが間違っているため、予定していたとおりの動作にならず、正しくない結果が出てしまう状態のことをいいます。

C++ の文法や機能の話題に入る前に、エラーについて話をするのは、プログラミングではエラーが付き物で避けられないことだからです。

とくに入門者は間違いを恐れすぎることがありますが、そのような恐れはまったく不要であることを強調しておきたいと思います。プログラミングをしていくと、エラーは必ずどこかで出ます。これは熟練者でも同じです。間違えることを完全に避けることはできません(減らす努力はするべきですが)。

エラーは避けられないことである以上、エラーが出るとどのようなことが起こるのか、エラーが出たらどうすればいいのか、といったことを理解しておかなければなりません。

そこで、このページでは、実際にソースコードに間違いを入れて、どのようなことが起こるのか体験してみます。

ビルドエラー

エラーには種類があります。まずは代表的な、ビルドエラー (build error) について取り上げます。ビルドエラーは、ビルド(用語集)をしたときに発覚するエラーです。

ビルドエラーが起きるソースコードからは、実行ファイル(用語集)をつくることができません。よって、実行(用語集)することができません。

ビルドエラーにも種類があります。ビルドという操作には、複数の処理の段階が含まれているため、それぞれの段階ごとにエラーが起こる可能性があるからです。たとえば、コンパイル(用語集)の処理中に起こるエラーは、コンパイルエラー (compile error) と呼ばれます。

遭遇するビルドエラーの大半は、コンパイルエラーです。そして、コンパイルエラーの原因のほとんどは、ソースコードが、プログラミング言語の文法ルールに違反した記述になってしまっていることにあります。

ビルドエラーが発生すると、Visual Studio(などのコンパイラ(用語集))が、どの辺りがどのように正しくないのか、教えてくれますから、何がおかしいのか確認して修正します。

ビルドエラーを直してみる

では実際にビルドエラーを体験してみましょう。前のページで作った Hello, Worldプログラムを、あえて間違いがある状態に変えて試してみます。

まず、Hello, Worldプログラムのプロジェクトを Visual Studio で開きます(新規で作り直しても構いません)。

既存のプロジェクトを開くには、エクスプローラーで、拡張子が .vcxproj のファイルの場所までいって、そのファイルを開くか、Visual Studio を起動して、メニューバーの【ファイル】>【開く】>【プロジェクト/ソリューション】から選択します。

ソースファイルを次のように変更します(違いに気付けるでしょうか?)

#include <iostream>

int main()
{
    std::cout << "Hello, World\n"
}

違いは、5行目の行末にあるべき ; がないことです。

ビルドエラーはコンパイラに教えてもらえることなので、自力で気付けなくても大丈夫ですが、早く気付けると、ビルドを繰り返す回数が減るので、開発効率が上がるという意味はあります。細かいことに気付けることは立派な能力です。

このプログラムをビルドしてみると、次のように失敗します。

ビルドエラー
ビルドエラー

ビルドエラーを直すときには、まずエラーメッセージをきちんと読むことから始めます。赤い × の印が付いているものが、ビルドによって発見されたエラーです。エラーメッセージにはこう書いてあります。

C2143 構文エラー: ';' が '}' の前にありません。

「C2143」はエラーの種類をあらわす番号です。同じ類のエラーなら同じ番号が割り当てられるようになっています。この番号とエラーの対応は、Visual Studio(Microsoft)が定めたものです。「C2143」をそのまま Web検索すると情報が見つかります。

エラーの内容を書いた文章(構文エラー: ';' が '}' の前にありません。)は十分理解可能でしょう。落ち着いて文章を読んで理解してください。この場合、「} の前にあるべき ; がない」ということです。

理解不能な内容のエラーが出ることもありますが、そういうときは、上述したようにエラーの番号をそのまま Web検索するか、文章のほうをそのまま Web検索してみましょう。なんらか情報が見つかると思います。

また、エラーメッセージの右側には、そのエラーの発生箇所についての情報も表示されています。ここでは、「HelloWorld というプロジェクトの Source.cpp の 6行目」でエラーが起きていると報告されています。エラーメッセージのところでダブルクリックすると、ソースコード内の該当箇所へカーソルが移動します。

ただし、エラーの根本原因が本当にその位置にあるかどうか、信じすぎないようにする必要があります。今回のエラーの場合、欠けている ; を補うのは 5行目の行末ですが、エラーは 6行目にあると報告されています。

C++ の文法ルールとしては、; が行末になければならないわけではないので、このエラー報告が間違っているということではありません。6行目の先頭に ; を置いてもエラーは解消します。とはいえ、そういう分かりづらいソースコードにはしない方がいいです。

エラーの内容を理解したら、エラーが消えるようにソースコードを修正し、保存し、ビルドしなおします。ここでは、足りない ; を補って再度ビルドします。するとエラーが消えて、実行できるようになります。

これがビルドエラーを解決する基本的な流れです。


ところで、Visual Studio 2019 では、ビルドせずとも、ビルドエラーが起きる箇所に、赤い波線が表示されます。そうなっている部分にマウスカーソルを合わせると、エラーの内容が表示されます。

コード解析によるエラー報告
コード解析によるエラー報告

この機能はすべてのビルドエラーを漏れなく表示してくれているとは限りませんが、簡単なミスに気付きやすく、便利な機能です。

【オンラインで検索】というリンクが付いています。これをクリックすると Webブラウザが起動して、エラーに関する情報を Web検索してくれます。

また、【考えられる修正内容を表示する】というリンクをクリックすると、修正方法の候補が表示されます。

コードの自動修正
コードの自動修正

適切な修正提案があれば、それをクリックします。すると、自動的にソースコードが修正されます。

実行時エラー

代表的なエラーとしてもう1つ、実行時エラー (runtime error) があります。実行時エラーは、プログラムを実行してから発覚するエラーです。

実行時エラーの原因の多くは、ソースコードがプログラマーの意図どおりに書かれていないか、そもそもプログラマーの考え自体が正しくないかです。

ほかの原因として、実行に必要なファイルにアクセスできない、メモリなどのリソース(用語集)が不足しているといったことがあります。

実行時エラーは、発生したときの結果に応じて、次のように分類できます。

  1. 実行が強制的に終了させられてしまう
  2. 実行途中で処理が先に進まなくなってしまう
  3. 実行は続いているが、結果が正しくない

1は、プログラムが最後まで実行されず、途中で突然終了させられてしまう現象です。なんらかのエラーメッセージが出る場合もあります。クラッシュ (crash)、強制終了 (shut down)、異常終了 (abend) などと呼ばれます。

2は、プログラムは実行されたままだが、どこかの時点から先に進まなくなってしまう現象です。処理が正常に終了しないという意味では、実質的に1と同じことだともいえますが、先に進めなくなっている原因が解決できれば再開可能な場合もありますから、一応区別されます。こちらはフリーズ (freeze)、ハングアップ (hang-up)、ストール (stall) などと呼ばれることが多いです。

3は、プログラムの実行自体は行われるものの、結果が予定と違う場合です。論理エラー (logical error) と呼ばれることがあります。


プログラムに実行時エラーが起こるような間違いが潜んでいることを、バグ(用語集) (bug) があると表現します。また、バグを理解し修正する作業をデバッグ(用語集) (debug) といいます。

実行時エラーは、ビルドエラーと違って、何がおかしいかを教えてくれるとは限りません。さきほどの分類の1番にあたるものは、なんの情報もなく強制終了してしまうかもしれません。2番の場合も、どこで止まっているのか自力で調査しなければなりませんし、3番もソースコードを読み返して、間違いを突き止めなければ修正できません。

このように、実行時エラーを解決するデバッグ作業はむずかしい作業です。間違いを教えてくれるビルドエラーのほうがずっと解決しやすいといえます。

【C言語プログラマー】C言語と同じような書き方でプログラミングをするのだとしても、C++ を使ったほうが良い理由がここにあります。C++ の方がルールが厳しい(型の不一致をエラーとみなす機会が多いなど)ので、ビルドの時点で間違いを見つけやすく、実行時エラーを減らす効果があります。

具体的なデバッグの方法については、現段階ではまだ難しいのでここでは取り上げませんが、本編で C++ について学ぶ過程の中で何度か取り上げたいと思います。

参考リンク



更新履歴




はてなブックマーク に保存 Pocket に保存 Facebook でシェア
Twitter でツイート Twitter をフォロー LINE で送る
rss1.0 取得ボタン RSS 管理者情報 プライバシーポリシー