matsumoto-lab’s diary

慶應義塾大学物理情報工学科松本研究室の日々の活動について

エラー対処でまずすべきこと

はじめに


  本記事はプログラミングしたことがほぼない人を対象に、エラーが出た時の対処法について示しています。もしエラーがでたら何をすべきかを①~③で順に追って書きたいと思います。

 

①エラー出た!!


  以下の例を考えます。(他にも例あったら連絡いただければ幸いです。)

  1. Linux環境(CentOS)でC言語で書かれたプログラムをgccコンパイルして実行しようとしていました。プログラムの内容としては、2次元において r,  \theta極座標から x,  yを計算し表示するものを書いたつもりでした。(正直ライブラリにありそう)
    しかしコンパイルの時点でこんなエラーが…
    f:id:Roost:20201111234903p:plain
    エラー発生時のコマンドラインの様子1
      どうしましょう…

(例は今後追加予定)

②エラー文を読む


  まずは皆さんエラー文を読むと思います、エラーの原因が直接指摘されていることもありますし。 英語がわからなかったり何言ってるかわからなかったらググります。 例1では「sincos_error.c:13:3: エラー: ‘x’ が宣言されていません 」、'y'についても同様に書いてあるので、まずは元ファイルの該当部分がどうなっているか確認します。 すると元のsincos_error.cは以下のようになっていました。エラー文には'13(14)'行目とあるのでそこに注目します。

/* コンパイルエラーを出すために作った */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(int argc, char *argv[])
{  
  double r, theta;
  r = argv[1]; /* ここ10行目 */
  theta = argv[2];

  x = r * cos(theta); /* ここ13行目 */
  y = r * sin(theta);
  printf("x = %f\n", x);
  printf("y = %f\n", y);

  return 0;
}

 x,  yの型が定義されていませんでした。(Cでは必要)書き直してもう一度実行してみます。

f:id:Roost:20201111235136p:plain
改善後エラーメッセージ

  まだエラーが残ってますね、読むと「エラー: 型 ‘double’ への型 ‘char *’ からの代入時に互換性のない型です」とあります。
該当する10,11行目を見ると、どうやら読み込み時charで文字型になっていたのをdouble型に変換せずに r,  \thetaに代入していたことが原因っぽいですね。そこで変換できる関数がないか「文字列 double 変換 c言語」でググります。

f:id:Roost:20201111173655p:plain
「文字列 double 変換 c言語」で検索
検索結果のうち文字列を実数に変換する | Programming Place Plus C言語編 逆引きを読むと「atof関数」が有効であることが分かった*1ので早速使ってみます。

そこで以下のように直してもう一度コンパイルしてみます。

*/もうコンパイルエラーはないはず */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(int argc,  char *argv[])
{
  double r, theta;
  r = atof(argv[1]); /* atofによりchar→double */
  theta = atof(argv[2]); /* 上に同じ */
  double x,y; /* x,yを定義 */
  x = r * cos(theta);
  y = r * sin(theta);
  printf("x = %f\n", x);
  printf("y = %f\n", y);

  return 0;
}

f:id:Roost:20201111171601p:plain
改善後エラーメッセージ2
  まーたエラー出てますね。今度はmain関数内と記述がないことからcファイル内の問題ではないのではと推測できます。「cos(sin)が定義されていない」とありますが、cos,sinはmath.hで定義したものだったはずなので、これをうまく反映できていないことがわかります。同様に検索することで(「cos sin c gcc コンパイル」とかで出てきました)原因が判明し、-lmを末尾に付けることでエラーが出ずコンパイル終了しました。 エラーが出ていなくても「自分が思った通りに動くか」とは別なので、テストとしていくつか実行してみます。
f:id:Roost:20201111234448p:plain
出力テスト結果
問題なさそうです。(本来公に見せるような試算ではなく、軽い検算です)

③質問をするorメール(or何らかのSNS)を送る


  ②でも詰まったらできる人に聞く方が早いです、ためらわずに聞きましょう。 
とはいえ、自分がどんな状況かは質問相手はわかっていないことに留意すべきです。
そこで、ここでは質問する際、特にメールする際に書くべきことを順に書きます。 これがあると仮に対面(またはオンライン通話)対応になっても準備がしやすく、解決までのスピードが段違いです。

  1. どんな環境か

  2. 目的は何か

  3. どのような問題が起こったか(出力、エラー文など)

  4. 起動してからどんなコマンドを打ってきたか、どんなプログラムを書いたか (そのコピーまたは画面スクショ)

  5. (以下対処した場合)どんなアプローチをとったか(そのコピーまたは画面スクショ)

  6. アプローチの結果どうなっているか(出力、エラー文など)

ありがちな例と補足 特に欠けがちなのは2,4です。いきなり

・hogehoge.cをコンパイルしたらエラーが出てうまくいきません、なんでこうなってるんですか?

と来ることがあります。

この場合ファイル内容が分からず、コンパイルに使ったコマンドの内容も分からないので、下調べをほぼできずに対面やオンライン通話などで時間を共有して解決する必要が出てきます。
またよくあるのは

・hogehoge.cを編集して云々したらエラーがでて「~」と言ってます、どうしたらいいですか?

といった文章のみの場合です。エラー文の詳細、ほかにどんな出力があるか、hogehoge.cがどんなファイルかなどが分からずそれだけでは対処が難しい(というか無理)です。これも対面が必要になることがほとんどです。

さいごに


  コーディング指導をしていたときに、「来たメールを読んでも状況が分からず解決のしようがない」ということが何度かあったのがきっかけで書きました。 ただ「質問をためらわない」ことが大事なのはここで再度強調します。私自身質問しなければならないことが多々あるのでまた気づいたことあったら追記していきます。
  何かご指摘あれば連絡いただければと思います、ここまで読んでいただきありがとうございました。

*1:今回コードの手軽さゆえにatof関数を用いていますが、変換失敗を明確なエラー文として検出する機能がないため、一般にstrtod関数を代用することが推奨されます