C言語+MySQL入門|警告を表示してコンパイルする

C言語+MySQL入門|警告を表示してコンパイルする

前回は、次の短いコマンドでhello.cをコンパイルしました。

gcc hello.c -o hello.exe

今回は、このコマンドにオプションを加え、使用するC言語の規格を指定し、書き間違いや問題につながりそうな記述を見つけやすくします。

使用するコマンドは、次のとおりです。

gcc -std=c17 -Wall -Wextra -Wpedantic hello.c -o hello.exe

少し長くなりましたが、それぞれのオプションには明確な役割があります。ひとつずつ確認していけば大丈夫です。

この記事では、次の内容を扱います。

  • C17を指定する意味
  • 警告を表示するオプションの役割
  • エラーと警告の違い
  • 警告メッセージの読み方
  • ソースコードを修正して再コンパイルする流れ

エラーと警告の違いを知る

GCCが表示する診断メッセージには、エラーや警告があります。

まずは、次の違いを押さえておきましょう。

種類メッセージの目印意味コンパイルへの影響
エラーerror:文法上の問題などがあり、処理を正常に完了できない正常なビルドが完了しない
警告warning:間違いや意図しない動作につながる可能性がある通常は処理を続行する

例えば、必要なセミコロンが抜けていると、エラーになることがあります。

一方、変数を作ったのに一度も使っていない場合は、警告によって知らせてもらえます。「使う予定だった変数の処理を書き忘れていないかな」と見直すきっかけになります。

実行ファイルが作られた場合でも、警告が出ていれば内容を確認することが大切です。GCCの警告は、問題の可能性を知らせる診断として用意されています。

図1:エラーと警告の役割

この図から分かること

エラーは、ビルドを正常に完了できない問題を知らせます。警告は、処理を続行できる場合でも、確認しておきたい記述を知らせます。

警告が表示されたら、まずメッセージを読み、コードにどのような意図があったのかを確かめましょう。

今回使うコンパイルコマンド

MSYS2 UCRT64、またはVS Codeで設定したUCRT64ターミナルを開きます。

作業ディレクトリへ移動してください。

cd /c/c-mysql/chap02

今回のコマンドを、役割ごとに分けてみましょう。

gcc -std=c17 -Wall -Wextra -Wpedantic hello.c -o hello.exe
記述役割
gccGCCを起動する
-std=c17C17の規格を指定する
-Wallよく使う警告をまとめて有効にする
-Wextra-Wallに含まれない警告の一部を追加する
-Wpedantic指定した規格に照らし、規格外の拡張の使用などを診断する
hello.cコンパイルするソースファイル
-o hello.exe出力する実行ファイルの名前を指定する

オプションの大文字と小文字は、見本どおりに入力してください。-Wall、-Wextra、-WpedanticのWは大文字です。

C17を指定する理由

C言語には、C99、C11、C17、C23などの規格があります。

この教材では、使用する規格をそろえるために、-std=c17を指定します。GCCは、この指定に基づいてC17のモードでソースコードを処理します。

規格を省略すると、GCCの既定の設定が使われます。明示的に指定しておけば、GCCのバージョンによって既定の規格が変わっても、教材で使う規格をそろえやすくなります。

また、VS Code側でC17を設定していても、ターミナルから実行するGCCのコマンドに、その設定が自動で付け加えられるわけではありません。

設定する場所主な役割
VS CodeのC/C++拡張機能入力補完や編集中のコード解析に使う規格を指定する
GCCの-std=c17実際のコンパイルに使う規格を指定する

エディターの設定と、コンパイル時の指定は分けて考えましょう。

3つの警告オプションを組み合わせる

-Wallで基本的な警告を有効にする

-Wallは、使用していない変数など、よく確認したい問題に関する警告をまとめて有効にします。

名前にallが含まれていますが、GCCのすべての警告を有効にするオプションではありません。

-Wextraで確認する範囲を広げる

-Wextraは、-Wallだけでは有効にならない警告の一部を追加します。

この教材では、両方を指定して、問題に気付く機会を増やします。

-Wpedanticで規格に沿った記述を確認する

-Wpedanticは、-stdで指定した規格に照らして、規格外の拡張の使用などを診断します。

今回の指定では、C17が基準になります。ただし、この指定だけで規格への適合を完全に証明できるわけではありません。gcc.gnu.org

最初は、次の組み合わせをひとまとまりとして使っていきましょう。

-std=c17 -Wall -Wextra -Wpedantic

hello.cを警告付きでコンパイルする

前回までに作成したhello.cを確認します。

学習開始のメッセージを表示するプログラム

ファイル名: hello.c

#include <stdio.h>

int main(void)
{
    /* 学習開始のメッセージを表示する */
    printf("Hello, C and MySQL!\n");

    return 0;
}

printfがメッセージを表示し、\nで改行します。最後のreturn 0;は、プログラムが正常に終了したことを伝えます。

VS CodeでCtrl + Sを押して保存したら、次のコマンドを実行してください。

gcc -std=c17 -Wall -Wextra -Wpedantic hello.c -o hello.exe

この内容であれば、通常は警告やエラーを表示せずにコンパイルが完了します。

警告を有効にするオプションを付けても、必ず警告が表示されるわけではありません。該当する問題が見つかったときに表示されます。

直後に、終了ステータスを確認できます。

echo $?

正常終了した場合の表示例

0

ただし、警告が出た場合でも、ビルドが正常に完了すれば0になります。 終了ステータスだけでなく、ターミナルに表示された診断も確認してください。

実行結果の例

作成したhello.exeを実行すると、表示内容は前回と同じです。

Hello, C and MySQL!

警告オプションを付けても、プログラムに「警告を表示する機能」が追加されるわけではありません。警告は、GCCがコンパイル中に表示するものです。

警告が出る例を試す

警告の読み方を練習するために、短いプログラムを別のファイルに作ってみましょう。

保存場所は、hello.cと同じC:\c-mysql\chap02です。

この例では、商品数を表す変数item_countを用意しますが、意図的に使わないままにしてあります。

使っていない変数の警告を確認するプログラム

ファイル名: warning_example.c

#include <stdio.h>

int main(void)
{
    int item_count = 3;

    printf("Inventory learning started.\n");

    return 0;
}

item_countには3を代入していますが、その値を表示したり、計算に使ったりしていません。

次のコマンドでコンパイルします。

gcc -std=c17 -Wall -Wextra -Wpedantic warning_example.c -o warning_example.exe

警告メッセージの要点を、次に示します。読みやすいように、引用符やソースコードの補助表示を省いています。実際の表示形式はGCCのバージョンや言語設定によって異なります。

warning_example.c:5:9: warning: unused variable item_count [-Wunused-variable]

unused variableは「使用されていない変数」という意味です。

実行結果の例

この例は警告が出ても通常は実行ファイルが作られ、実行すると次のように表示されます。

Inventory learning started.

item_countの値を表示する処理は書いていないため、3は表示されません。

警告メッセージを順番に読む

先ほどの警告を、部分ごとに分けてみましょう。

部分読み取れる内容
warning_example.c問題が見つかったファイル
5ソースコードの行番号
9その行の列番号
warning:警告であること
unused variable item_countitem_countが使われていないこと
[-Wunused-variable]この警告を制御するオプションの名前

まずは、ファイル名、行番号、警告の内容を確認すれば大丈夫です。

今回なら、warning_example.cの5行目にあるitem_countの宣言を見直します。

末尾の-Wunused-variableは、今回表示された警告の種類を調べる手掛かりになります。この警告は-Wallによって有効になります。

図2:警告メッセージから修正箇所を見つける

この図から分かること

警告メッセージには、問題の場所と内容が含まれています。

英語の文章をすべて理解できなくても、ファイル名と行番号を手掛かりに該当箇所を開けば、確認する範囲を絞れます。

プログラムの意図に合わせて修正する

使用していない変数が見つかった場合、修正方法はプログラムの意図によって変わります。

  • 不要な変数であれば、宣言を削除する。
  • 使う予定の変数であれば、書き忘れた処理を追加する。

今回は、商品数を表示したかったものとして、printfを追加しましょう。

商品数を表示して変数を使用するプログラム

ファイル名: warning_example.c

#include <stdio.h>

int main(void)
{
    int item_count = 3;

    printf("Inventory learning started.\n");
    printf("Item count: %d\n", item_count);

    return 0;
}

追加したprintfでは、%dの位置にint型の値を表示します。表示する値としてitem_countを渡しているため、この変数が実際に使われるようになりました。

Ctrl + Sで保存し、同じコマンドでもう一度コンパイルします。

gcc -std=c17 -Wall -Wextra -Wpedantic warning_example.c -o warning_example.exe

この内容なら、先ほどの未使用変数の警告は表示されなくなります。

実行結果の例

修正後の実行ファイルを実行すると、次のように表示されます。

Inventory learning started.
Item count: 3

警告をきっかけに、商品数を表示する処理の書き忘れを修正できました。

警告を消すことだけを目的にせず、「本来どのように動かしたかったのか」を考えて直していきましょう。

エラーが出たときは最初の診断から確認する

エラーが表示された場合も、ファイル名や行番号を手掛かりにします。

ただし、表示された場所そのものに原因があるとは限りません。例えば、前の行のセミコロンが抜けていて、次の行を読み取ったときにエラーとして報告される場合があります。

次の順番で確認すると、落ち着いて修正できます。

  1. 最初に表示されたエラーを読む。
  2. 指定された行と、その直前の行を見る。
  3. セミコロン、括弧、二重引用符などを確認する。
  4. 修正して保存する。
  5. もう一度コンパイルする。

ひとつの書き間違いが原因で、複数のエラーが続けて表示されることもあります。最初の原因を直して再コンパイルすると、後続のエラーも一緒に解消する場合があります。

警告がないことと、正しく動くことは別に確認する

警告がなくなったら、次は実際の動作を確認します。

コンパイラは、開発者が意図した計算や表示内容を、すべて理解しているわけではありません。商品数を3にするつもりで30と書いてしまっても、C言語として正しい記述なら、その間違いを警告できるとは限りません。

確認すること主な確認方法
文法上の問題や疑わしい記述がないかコンパイル時のエラーや警告を確認する
意図した表示や計算になっているかプログラムを実行して結果を確認する

また、コンパイルに失敗した後に、以前作成した実行ファイルが残っていることがあります。

実行前には、今回のコンパイルが成功したことを確かめましょう。そうすることで、古い実行ファイルを動かして修正結果を確認したつもりになる、といった混乱を防げます。

図3:診断を確認してから動作を確かめる

この図から分かること

プログラムは、編集して終わりではありません。保存し、コンパイル時の診断を確認し、実行結果を確かめながら作っていきます。

警告が出たらコードを見直し、コンパイルに成功したら動作を確認する。この流れを繰り返すことで、少しずつ意図したプログラムに近づけられます。

次はhello.exeを実行する

今後、基本のコンパイルコマンドとして、次の形を使っていきます。

gcc -std=c17 -Wall -Wextra -Wpedantic hello.c -o hello.exe

今回練習したwarning_example.cとwarning_example.exeも、chap02に保存しておけば、警告の読み方を復習するときに使えます。

次の記事では、hello.exeを実行し、メッセージが表示されることを確認します。ソースコードの保存、コンパイル、実行をひとつの流れとして身に付けていきましょう。

Follow me!