Sun Studio 12: C ユーザーズガイド

4.4 lint のメッセージ

大部分の lint のメッセージは簡単な 1 行の文で、問題が起こって診断されるたびに出力されます。インクルードファイルで検出されたエラーはコンパイラでは複数回報告されますが、lint ではそのファイルがほかのソースファイルに何度インクルードされようとも一度報告されるだけです。複合メッセージは、ファイル全域の矛盾に対して、また時にはファイル内の問題に対しても表示されます。単一メッセージは、検査しているファイルで問題が発生するごとに知らせます。lint フィルタ (「4.6.2 lint ライブラリ」を参照) を使用して各現象ごとに表示されるメッセージを要求する時に、-s オプションを使用して lint を実行することにより、複雑なメッセージを簡単なものに変換することができます。

lint のメッセージは stderr に書き込まれます。

4.4.1 メッセージを抑制するオプション

いくつかの lint オプションを使用して、lint の診断メッセージを抑制することができます。メッセージを抑制するには、-erroff オプションのあとに 1 つ以上の タグ を指定して実行してください。これらのニーモニックタグは、-errtags=yes オプションで表示することができます。

次の表に lint のメッセージを抑制するオプションを示します。

表 4–8 メッセージを抑制する lint オプション

オプション 

抑制されるメッセージ 

-a

代入によって暗黙的により小さい型に変換されます

より大きな整数型への変換は符号拡張が不正確になる可能性があります

-b

到達できない文です

-h

等価演算子 "==" の使用が想定される場所に代入演算子 "=" が使用されています

演算子 "!" のオペランドが定数です

case 文を通り抜けます

ポインタのキャストによって境界整列が不正確になる可能性があります

優先度が混乱する可能性があります; 括弧

文が帰結していません:if

文が帰結していません:else

-m

大域的に宣言されていますが静的 (static) にすることができます

-erroff=タグ

タグで指定した 1 つまたは複数の lint メッセージ

-u

名前が定義されていますが使用されていません

未定義の名前が使用されています

-v

引数が関数中で使用されていません

-x

名前が宣言されていますが使用も定義もされていません

4.4.2 lint メッセージの形式

lint プログラムに一定のオプションを指定すると、エラーが発生した行位置を示すポインタを伴った詳細なソースファイル行を表示することができます。この機能を使用可能にするオプションは -errfmt=f です。このオプションを指定しておくと、lint は次の情報を出力します。

たとえば、次に示すプログラム Test1.c にはエラーがあります。


1 #include <string.h>
2 static void cpv(char *s, char* v, unsigned n)
3 { int i;
4   for (i=0; i<=n; i++){
5        *v++ = *s++;}
6 }
7 void main(int argc, char* argv[])
8 {
9     if (argc != 0){
10        cpv(argv[0], argc, strlen(argv[0]));}
11}

そこで、次のようなオプションを使用して Test1.clint を実行します。


% lint -errfmt=src -Nlevel=2 Test1.c

結果として、次のような出力が得られます。


      |static void cpv(char *s, char* v, unsigned n)
      |            ^  2 行目, Test1.c
      |
      |         cpv(argv[0], argc, strlen(argv[0]));
      |                      ^  10 行目, Test1.c
警告: ポインタ/整数の組み合わせは不適切です:2 番目の引数
      |
      |static void cpv(char *s, char* v, unsigned n)
      |                               ^  2 行目, Test1.c
      |
      |cpv(argv[0], argc, strlen(argv[0]));
      |                       ^ 10 行目, Test1.c
      |
      |        *v++ = *s++;
      |         ^  5 行目, Test1.c
疑わしい方法で作成されたポインタを使用しています
    v, 定義された場所: Test1.c(2)    ::Test1.c(5)
      呼び出しスタック:
          main()                ,    Test1.c(10)
          cpv()                 ,    Test1.c(5)

1 つめの警告は、2 つのコード行の間で矛盾があることを示しています。2 つめの警告には、その時のコールスタックとエラーに到るまでの制御フローが表示されます。

次に示すプログラム Test2.c には、前述のものとは異なる種類のエラーがあります。


1 #define AA(b) AR[b+l]
2 #define B(c,d) c+AA(d)
3
4 int x=0;
5
6 int AR[10]={1,2,3,4,5,6,77,88,99,0};
7
8 main()
9  {
10  int y=-5, z=5;
11  return B(y,z);
12 }

そこで、次のようなオプションを使用して Test2.clint を実行します。


% lint -errfmt=macro Test2.c

結果として、次のような出力が得られます。


      | return B(y,z);
      |        ^  11 行目, Test2.c
      |
      |#define B(c,d) c+AA(d)
      |                 ^  2 行目, Test2.c
      |
      |#define AA(b) AR[b+l]
      |                   ^  1 行目, Test2.c
エラー:未定義のシンボル:l
|
      |    return B(y,z);
      |           ^  11 行目, Test2.c
      |
      |#define B(c,d) c+AA(d)
      |                 ^  2 行目, Test2.c
      |
      |#define AA(b) AR[b+l]
      |                   ^  1 行目, Test2.c
変数が設定以前に使用されている可能性があります: l
lint: Test2.c 中のエラー; 出力ファイルは作成されません
lint: 2 回目のパスは実行しません - Test2.c 中のエラー