Oracle Solaris Studio 12.2: C ユーザーガイド

4.6.1 lint が行う診断

lint 固有 の診断は、矛盾した使い方、移植不能のコード、疑わしい言語構造の 3 つの広い条件カテゴリ に対して表示されます。この節では、各カテゴリにおける lint の動作の例を示し、どのような対応が可能かを説明します。

4.6.1.1 整合性の検査

ファイル全域とファイル内部における変数、引数、関数の矛盾した使用を検査します。概して lint が古いスタイルの関数に対して検査していたのと同様に、プロトタイプの使用、宣言、引数を検査します。プログラムが関数プロトタイプを使用していない場合、lint は関数の呼び出しごとにコンパイラより厳しく引数の数と型を検査します。lint は、[fs]printf()[fs]scanf() の制御文字列の変換指示子と引数の不一致も識別します。

次に例を示します。

4.6.1.2 移植性の検査

一部の移植不可能なコードは、lint のデフォルトの動作によってフラグを付けられます。また、ほかにも少数の状況で、 -p または -Xc を指定して lint を起動すると、診断されることがあります。lint は ISO C 規格に一致しない言語構造を検査します。-p および -Xc のもとで発行されるメッセージに関しては、「4.6.2 lint ライブラリ」を参照してください。

次に例を示します。


char c;
c = getchar();
if (c == EOF) ...

そこで EOF が値 -1 を持つテストは、文字変数が負でない値を取るマシンでは常に失敗します。-p オプションで呼び出した lint は、普通の char が負の値を取る可能性があるような比較をすべて検査します。しかし前述の例では、csigned char で宣言しても、問題が除去されるのではなく診断が除去されるだけです。これは、getchar() が入力可能な文字と明確な EOF 値を返さなければならず、char がその値を格納することができないためです。これは、処理系ごとに定義される符号拡張から生ずるもっとも一般的な例です。これにより、lint の移植性オプションを注意深く使用すると移植性に関係しないバグを発見するのに役立つということがわかります。ここでは cint で宣言します。


short s;
long l;
s = l;

lint は、デフォルトでこのような代入すべてを知らせます。診断は、-a オプションを指定して呼び出すことにより抑制することができます。どのオプションを指定して lint を呼び出しても、ほかの診断をも抑制する可能性があることに注意してください。2 つ以上の診断を抑制するオプションについては、「4.6.2 lint ライブラリ」にあるリストを参照してください。


int *fun(y)
char *y;
{
    return(int *)y;
}

大部分のマシンでは、intchar とは異なり任意のバイト境界から開始することができないため、lint はフラグを立てます。-h を指定して lint を実行することによってこの診断を抑制することができます。この場合もまた、ほかのメッセージを抑制する可能性があります。汎用ポインタ void * を使用すればほかの影響を回避することができます。


int a[10];
main()
{
    int i = 1;
    a[i++] = i;
}

この例での a[1] の値は、あるコンパイラでは 1、別のコンパイラでは 2 という可能性もあります。ビット単位の論理演算子 & がこのような診断をもたらすことがあるのは、誤って 論理演算子 && の代わりに使用される場合です。


if ((c = getchar()) != EOF & c != ’0’)

4.6.1.3 疑わしい言語構造

lint は、プログラマの意図には反するが、言語構造上は正しい箇所についても報告します。次に例を示します。


unsigned x;
if (x < 0) ...

常に失敗します。一方、


unsigned x;
if (x > 0) ...

これは次のように指定するのと同じことです。


if (x != 0) ...

最初の例は意図したものではない可能性があります。lint は、負の定数または 0unsigned 変数との疑わしい比較を知らせます。unsigned 変数を負数のビットパターンと比較するには、その負数を unsigned にキャストします。


if (u == (unsigned) -1) ...

または、接尾辞 U を使用します。


if (u == -1U) ...

int fun()
{
    int a, b, x, y;
    (a = x) && (b == y);
}

if (x & a == 0) ...

この式は、次のように評価されます。


if (x & (a == 0)) ...

これは、ユーザーの意図とは異なる可能性が高いものです。-h を指定して lint を起動すると、診断のものは無効になります